diff --git a/RegExpSupport/RegExpSupport.iml b/RegExpSupport/RegExpSupport.iml index 6fa1ddeb73d2..355cc42fcd21 100644 --- a/RegExpSupport/RegExpSupport.iml +++ b/RegExpSupport/RegExpSupport.iml @@ -19,7 +19,6 @@ - diff --git a/java/idea-ui/src/com/intellij/platform/templates/PlainModuleTemplatesFactory.java b/java/idea-ui/src/com/intellij/platform/templates/PlainModuleTemplatesFactory.java index 3ce17ab649ce..adea9045c607 100644 --- a/java/idea-ui/src/com/intellij/platform/templates/PlainModuleTemplatesFactory.java +++ b/java/idea-ui/src/com/intellij/platform/templates/PlainModuleTemplatesFactory.java @@ -28,6 +28,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.util.HashSet; import java.util.List; import java.util.Set; @@ -47,8 +48,9 @@ public class PlainModuleTemplatesFactory extends ProjectTemplatesFactory { return builder.getGroupName(); } }); - groups.add(OTHER_GROUP); - return ArrayUtil.toStringArray(groups); + HashSet set = new HashSet(groups); + set.add(OTHER_GROUP); + return ArrayUtil.toStringArray(set); } @NotNull 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 86162bb89c89..cbfde6328f9c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java @@ -16,6 +16,7 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.ExpectedTypeInfo; +import com.intellij.codeInsight.completion.impl.BetterPrefixMatcher; import com.intellij.codeInsight.completion.impl.CamelHumpMatcher; import com.intellij.codeInsight.lookup.AutoCompletionPolicy; import com.intellij.codeInsight.lookup.LookupElement; @@ -40,9 +41,9 @@ import static com.intellij.patterns.PsiJavaPatterns.psiElement; public class JavaNoVariantsDelegator extends CompletionContributor { @Override - public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) { - final boolean empty = containsOnlyPackages(result.runRemainingContributors(parameters, true)) || - suggestMetaAnnotations(parameters); + public void fillCompletionVariants(final CompletionParameters parameters, CompletionResultSet result) { + LinkedHashSet plainResults = result.runRemainingContributors(parameters, true); + final boolean empty = containsOnlyPackages(plainResults) || suggestMetaAnnotations(parameters); if (!empty && parameters.getInvocationCount() == 0) { result.restartCompletionWhenNothingMatches(); @@ -50,10 +51,13 @@ public class JavaNoVariantsDelegator extends CompletionContributor { if (empty) { delegate(parameters, JavaCompletionSorting.addJavaSorting(parameters, result)); - } else if (Registry.is("ide.completion.show.all.classes")) { + } else if (Registry.is("ide.completion.show.all.classes") || Registry.is("ide.completion.show.better.matching.classes")) { if (parameters.getInvocationCount() <= 1 && JavaCompletionContributor.mayStartClassName(result) && JavaCompletionContributor.isClassNamePossible(parameters)) { + if (Registry.is("ide.completion.show.better.matching.classes")) { + result = result.withPrefixMatcher(new BetterPrefixMatcher(result.getPrefixMatcher(), BetterPrefixMatcher.getBestMatchingDegree(plainResults))); + } suggestNonImportedClasses(parameters, result); } } diff --git a/java/java-impl/src/com/intellij/ide/util/PackageChooserDialog.java b/java/java-impl/src/com/intellij/ide/util/PackageChooserDialog.java index 245f34266cf7..2ad3edc9afa9 100644 --- a/java/java-impl/src/com/intellij/ide/util/PackageChooserDialog.java +++ b/java/java-impl/src/com/intellij/ide/util/PackageChooserDialog.java @@ -22,6 +22,11 @@ import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.event.*; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.fileChooser.ex.FileChooserDialogImpl; +import com.intellij.openapi.fileChooser.ex.TextFieldAction; +import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ContentIterator; @@ -35,9 +40,10 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; -import com.intellij.ui.ScrollPaneFactory; -import com.intellij.ui.TreeSpeedSearch; +import com.intellij.ui.*; +import com.intellij.ui.components.labels.LinkLabel; import com.intellij.ui.treeStructure.Tree; +import com.intellij.util.Alarm; import com.intellij.util.IncorrectOperationException; import com.intellij.util.PlatformIcons; import com.intellij.util.containers.Convertor; @@ -66,6 +72,9 @@ public class PackageChooserDialog extends PackageChooser { private final Project myProject; private final String myTitle; private Module myModule; + private EditorTextField myPathEditor; + + private Alarm myAlarm = new Alarm(getDisposable()); public PackageChooserDialog(String title, @NotNull Module module) { super(module.getProject(), true); @@ -147,19 +156,69 @@ public class PackageChooserDialog extends PackageChooser { else { setTitle(myTitle); } + updatePathFromTree(); } }); panel.add(scrollPane, BorderLayout.CENTER); DefaultActionGroup group = createActionGroup(myTree); + final JPanel northPanel = new JPanel(new BorderLayout()); + panel.add(northPanel, BorderLayout.NORTH); ActionToolbar toolBar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true); - panel.add(toolBar.getComponent(), BorderLayout.NORTH); - toolBar.getComponent().setAlignmentX(JComponent.LEFT_ALIGNMENT); - + northPanel.add(toolBar.getComponent(), BorderLayout.WEST); + setupPathComponent(northPanel); return panel; } + private void setupPathComponent(final JPanel northPanel) { + northPanel.add(new TextFieldAction() { + @Override + public void linkSelected(LinkLabel aSource, Object aLinkData) { + toggleShowPathComponent(northPanel, this); + } + }, BorderLayout.EAST); + myPathEditor = new EditorTextField(JavaReferenceEditorUtil.createDocument("", myProject, false), myProject, StdFileTypes.JAVA); + myPathEditor.addDocumentListener(new DocumentAdapter() { + @Override + public void documentChanged(DocumentEvent e) { + myAlarm.cancelAllRequests(); + myAlarm.addRequest(new Runnable() { + @Override + public void run() { + updateTreeFromPath(); + } + }, 300); + } + }); + myPathEditor.setBorder(BorderFactory.createEmptyBorder(0, 0, 2, 0)); + northPanel.add(myPathEditor, BorderLayout.SOUTH); + } + + private void toggleShowPathComponent(JPanel northPanel, TextFieldAction fieldAction) { + boolean toShowTextField = !isPathShowing(); + PropertiesComponent.getInstance().setValue(FileChooserDialogImpl.FILE_CHOOSER_SHOW_PATH_PROPERTY, Boolean.toString(toShowTextField)); + myPathEditor.setVisible(toShowTextField); + fieldAction.update(); + northPanel.revalidate(); + northPanel.repaint(); + updatePathFromTree(); + } + + private static boolean isPathShowing() { + return PropertiesComponent.getInstance().getBoolean(FileChooserDialogImpl.FILE_CHOOSER_SHOW_PATH_PROPERTY, true); + } + + private void updatePathFromTree() { + if (!isPathShowing()) return; + final PsiPackage selection = getTreeSelection(); + myPathEditor.setText(selection != null ? selection.getQualifiedName() : ""); + } + + private void updateTreeFromPath() { + selectPackage(myPathEditor.getText().trim()); + } + private DefaultActionGroup createActionGroup(JComponent component) { final DefaultActionGroup group = new DefaultActionGroup(); final DefaultActionGroup temp = new DefaultActionGroup(); diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHandler.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHandler.java index 07227c067851..21de8fc80d2a 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHandler.java @@ -81,8 +81,7 @@ public class ExtractMethodHandler implements RefactoringActionHandler { editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); if (!editor.getSelectionModel().hasSelection()) { final int offset = editor.getCaretModel().getOffset(); - final PsiElement[] statementsInRange = IntroduceVariableBase.findStatementsAtOffset(editor, file, offset); - final List expressions = IntroduceVariableBase.collectExpressions(file, editor, offset, statementsInRange); + final List expressions = IntroduceVariableBase.collectExpressions(file, editor, offset, true); if (expressions.isEmpty()) { editor.getSelectionModel().selectLineAtCaret(); } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/ElementToWorkOn.java b/java/java-impl/src/com/intellij/refactoring/introduceField/ElementToWorkOn.java index 93e19e3581bc..9e4f79c07e10 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/ElementToWorkOn.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/ElementToWorkOn.java @@ -99,7 +99,7 @@ public class ElementToWorkOn { } if (!editor.getSelectionModel().hasSelection()){ - final List expressions = IntroduceVariableBase.collectExpressions(file, editor, offset, statementsInRange); + final List expressions = IntroduceVariableBase.collectExpressions(file, editor, offset); for (Iterator iterator = expressions.iterator(); iterator.hasNext(); ) { PsiExpression expression = iterator.next(); if (!processor.accept(new ElementToWorkOn(null, expression))) { diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java index a8bb3eb7cca7..740c2cc15b3c 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java @@ -125,7 +125,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { } if (!selectionModel.hasSelection()) { - final List expressions = collectExpressions(file, editor, offset, statementsInRange); + final List expressions = collectExpressions(file, editor, offset); if (expressions.isEmpty()) { selectionModel.selectLineAtCaret(); } else if (expressions.size() == 1) { @@ -162,7 +162,16 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { return Boolean.valueOf(PropertiesComponent.getInstance().getOrInit(PREFER_STATEMENTS_OPTION, "false")).booleanValue() || Registry.is(PREFER_STATEMENTS_OPTION, false); } - public static List collectExpressions(final PsiFile file, final Editor editor, final int offset, final PsiElement... statementsInRange) { + public static List collectExpressions(final PsiFile file, + final Editor editor, + final int offset) { + return collectExpressions(file, editor, offset, false); + } + + public static List collectExpressions(final PsiFile file, + final Editor editor, + final int offset, + boolean acceptVoid) { Document document = editor.getDocument(); CharSequence text = document.getCharsSequence(); int correctedOffset = offset; @@ -196,7 +205,8 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { }*/ PsiExpression expression = PsiTreeUtil.getParentOfType(elementAtCaret, PsiExpression.class); while (expression != null) { - if (!expressions.contains(expression) && !(expression instanceof PsiParenthesizedExpression) && !(expression instanceof PsiSuperExpression) && expression.getType() != PsiType.VOID) { + if (!expressions.contains(expression) && !(expression instanceof PsiParenthesizedExpression) && !(expression instanceof PsiSuperExpression) && + (acceptVoid || expression.getType() != PsiType.VOID)) { if (expression instanceof PsiMethodReferenceExpression) { expressions.add(expression); } diff --git a/java/java-impl/src/com/intellij/refactoring/rename/BeanPropertyRenameHandler.java b/java/java-impl/src/com/intellij/refactoring/rename/BeanPropertyRenameHandler.java index 785c5dafb4b2..4f3bf58ab4ab 100644 --- a/java/java-impl/src/com/intellij/refactoring/rename/BeanPropertyRenameHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/rename/BeanPropertyRenameHandler.java @@ -23,6 +23,9 @@ import com.intellij.openapi.ui.DialogWrapper; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiParameter; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; +import com.intellij.psi.codeStyle.VariableKind; import com.intellij.psi.impl.beanProperties.BeanProperty; import com.intellij.psi.util.PropertyUtil; import com.intellij.refactoring.RenameRefactoring; @@ -65,6 +68,15 @@ public abstract class BeanPropertyRenameHandler implements RenameHandler { if (setter != null) { final String setterName = PropertyUtil.suggestSetterName(newName); rename.addElement(setter, setterName); + + final PsiParameter[] setterParameters = setter.getParameterList().getParameters(); + if (setterParameters.length == 1) { + final JavaCodeStyleManager manager = JavaCodeStyleManager.getInstance(psiElement.getProject()); + final String suggestedParameterName = manager.propertyNameToVariableName(property.getName(), VariableKind.PARAMETER); + if (suggestedParameterName.equals(setterParameters[0].getName())) { + rename.addElement(setterParameters[0], manager.propertyNameToVariableName(newName, VariableKind.PARAMETER)); + } + } } final PsiMethod getter = property.getGetter(); diff --git a/java/java-impl/src/com/intellij/ui/JavaReferenceEditorUtil.java b/java/java-impl/src/com/intellij/ui/JavaReferenceEditorUtil.java index eae218373176..b5323adc4199 100644 --- a/java/java-impl/src/com/intellij/ui/JavaReferenceEditorUtil.java +++ b/java/java-impl/src/com/intellij/ui/JavaReferenceEditorUtil.java @@ -43,11 +43,21 @@ public class JavaReferenceEditorUtil { } @Nullable - public static Document createDocument(final String text, Project project, boolean isClassesAccepted) { + public static Document createDocument(final String text, + Project project, + boolean isClassesAccepted) { + return createDocument(text, project, isClassesAccepted, JavaCodeFragment.VisibilityChecker.EVERYTHING_VISIBLE); + } + + @Nullable + public static Document createDocument(final String text, + Project project, + boolean isClassesAccepted, + JavaCodeFragment.VisibilityChecker visibilityChecker) { final PsiPackage defaultPackage = JavaPsiFacade.getInstance(project).findPackage(""); final JavaCodeFragmentFactory factory = JavaCodeFragmentFactory.getInstance(project); final JavaCodeFragment fragment = factory.createReferenceCodeFragment(text, defaultPackage, true, isClassesAccepted); - fragment.setVisibilityChecker(JavaCodeFragment.VisibilityChecker.EVERYTHING_VISIBLE); + fragment.setVisibilityChecker(visibilityChecker); return PsiDocumentManager.getInstance(project).getDocument(fragment); } diff --git a/java/java-impl/src/com/intellij/ui/ReferenceEditorComboWithBrowseButton.java b/java/java-impl/src/com/intellij/ui/ReferenceEditorComboWithBrowseButton.java index 718a8c2fcdc7..e86cbb5bad32 100644 --- a/java/java-impl/src/com/intellij/ui/ReferenceEditorComboWithBrowseButton.java +++ b/java/java-impl/src/com/intellij/ui/ReferenceEditorComboWithBrowseButton.java @@ -43,7 +43,7 @@ public class ReferenceEditorComboWithBrowseButton extends ComponentWithBrowseBut @NotNull final Project project, boolean toAcceptClasses, final JavaCodeFragment.VisibilityChecker visibilityChecker, final String recentsKey) { - super(new EditorComboBox(createDocument(StringUtil.isEmpty(text) ? "" : text, project, toAcceptClasses, visibilityChecker), project, StdFileTypes.JAVA), + super(new EditorComboBox(JavaReferenceEditorUtil.createDocument(StringUtil.isEmpty(text) ? "" : text, project, toAcceptClasses, visibilityChecker), project, StdFileTypes.JAVA), browseActionListener); final List recentEntries = RecentsManager.getInstance(project).getRecentEntries(recentsKey); if (recentEntries != null) { @@ -54,16 +54,6 @@ public class ReferenceEditorComboWithBrowseButton extends ComponentWithBrowseBut } } - private static Document createDocument(final String text, - Project project, - boolean isClassesAccepted, - final JavaCodeFragment.VisibilityChecker visibilityChecker) { - PsiPackage defaultPackage = JavaPsiFacade.getInstance(project).findPackage(""); - final JavaCodeFragment fragment = JavaCodeFragmentFactory.getInstance(project).createReferenceCodeFragment(text, defaultPackage, true, isClassesAccepted); - fragment.setVisibilityChecker(visibilityChecker); - return PsiDocumentManager.getInstance(project).getDocument(fragment); - } - public String getText(){ return getChildComponent().getText().trim(); } diff --git a/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java b/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java index 1177603fde19..c3156445f7dd 100644 --- a/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java @@ -405,6 +405,14 @@ public class ControlFlowUtil { if (parent instanceof PsiClass) { final PsiClass clss = (PsiClass)parent; if (PsiTreeUtil.isAncestor(targetClassMember, clss, false)) return false; + PsiClass containingClass = PsiTreeUtil.getParentOfType(ref, PsiClass.class); + while (containingClass != null) { + if (containingClass.isInheritor(clss, true) && + PsiTreeUtil.isAncestor(targetClassMember, containingClass, false)) { + return false; + } + containingClass = containingClass.getContainingClass(); + } } } diff --git a/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation.java b/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation.java new file mode 100644 index 000000000000..2cb308ff53e0 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation.java @@ -0,0 +1,6 @@ +class MyClass { + String hc = this. + + @Annotation + public void myAnnotatedMethod() {} +} diff --git a/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation_After.java b/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation_After.java new file mode 100644 index 000000000000..71da13a48a8b --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation_After.java @@ -0,0 +1,6 @@ +class MyClass { + String hc = this.toString() + + @Annotation + public void myAnnotatedMethod() {} +} diff --git a/java/java-tests/testData/refactoring/extractMethod/TargetAnonymous.java b/java/java-tests/testData/refactoring/extractMethod/TargetAnonymous.java new file mode 100644 index 000000000000..fa5180a881bb --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/TargetAnonymous.java @@ -0,0 +1,13 @@ +public class Foo { + public void update() {} +} + +class FooBar { + { + Foo tm = new Foo() { + { + update(); + } + }; + } +} diff --git a/java/java-tests/testData/refactoring/extractMethod/TargetAnonymous_after.java b/java/java-tests/testData/refactoring/extractMethod/TargetAnonymous_after.java new file mode 100644 index 000000000000..575b821c069c --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/TargetAnonymous_after.java @@ -0,0 +1,17 @@ +public class Foo { + public void update() {} +} + +class FooBar { + { + Foo tm = new Foo() { + { + newMethod(); + } + + private void newMethod() { + update(); + } + }; + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/TabCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/TabCompletionTest.java index a2481a48985e..212ced546d12 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/TabCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/TabCompletionTest.java @@ -14,6 +14,14 @@ public class TabCompletionTest extends LightFixtureCompletionTestCase { checkResultByFile("MethodLookup3_After.java"); } + public void _testMethodCallBeforeAnnotation() { + String name = getTestName(false); + myFixture.configureByFile(name + ".java"); + myFixture.completeBasic(); + myFixture.type("tos\t"); + checkResultByFile(name + "_After.java"); + } + public void testReplaceThisWithSuper() throws Throwable { configureByFile("ReplaceThisWithSuper.java"); checkResultByFile("ReplaceThisWithSuper_After.java"); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy index 372c1802171b..af208b0867f4 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy @@ -540,4 +540,15 @@ class Foo { } } + public void "test expand current live template on no suggestions in lookup"() { + myFixture.configureByText "a.java", "class Foo {{ }}" + myFixture.completeBasic() + assert myFixture.lookup + myFixture.type("sout") + assert myFixture.lookup + assert myFixture.lookupElementStrings == [] + myFixture.type('\t') + myFixture.checkResult "class Foo {{\n System.out.println(); }}" + } + } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java index 3191c0943465..3639cbdfc78d 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java @@ -583,6 +583,10 @@ public class ExtractMethodTest extends LightCodeInsightTestCase { doDuplicatesTest(); } + public void testTargetAnonymous() throws Exception { + doTest(); + } + private void doTestDisabledParam() throws PrepareFailedException { final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject()); settings.ELSE_ON_NEW_LINE = true; diff --git a/platform/core-api/src/com/intellij/concurrency/AsyncFuture.java b/platform/core-api/src/com/intellij/concurrency/AsyncFuture.java index 914e27b4032e..e817f85a6174 100644 --- a/platform/core-api/src/com/intellij/concurrency/AsyncFuture.java +++ b/platform/core-api/src/com/intellij/concurrency/AsyncFuture.java @@ -15,8 +15,7 @@ */ package com.intellij.concurrency; -import com.intellij.util.Consumer; - +import org.jetbrains.annotations.NotNull; import java.util.concurrent.Executor; import java.util.concurrent.Future; @@ -25,5 +24,5 @@ import java.util.concurrent.Future; * Author: dmitrylomov */ public interface AsyncFuture extends Future { - void addConsumer(Executor executor, ResultConsumer consumer); + void addConsumer(@NotNull Executor executor, @NotNull ResultConsumer consumer); } diff --git a/platform/core-api/src/com/intellij/concurrency/AsyncFutureResult.java b/platform/core-api/src/com/intellij/concurrency/AsyncFutureResult.java index e0a6c4479c43..bc4ccab46f8c 100644 --- a/platform/core-api/src/com/intellij/concurrency/AsyncFutureResult.java +++ b/platform/core-api/src/com/intellij/concurrency/AsyncFutureResult.java @@ -15,10 +15,12 @@ */ package com.intellij.concurrency; +import org.jetbrains.annotations.NotNull; + /** * Author: dmitrylomov */ public interface AsyncFutureResult extends AsyncFuture { void set(V value); - void setException(Throwable t); + void setException(@NotNull Throwable t); } diff --git a/platform/core-api/src/com/intellij/concurrency/AsyncUtil.java b/platform/core-api/src/com/intellij/concurrency/AsyncUtil.java index 74cff15b56b4..dc8589585365 100644 --- a/platform/core-api/src/com/intellij/concurrency/AsyncUtil.java +++ b/platform/core-api/src/com/intellij/concurrency/AsyncUtil.java @@ -15,6 +15,8 @@ */ package com.intellij.concurrency; +import org.jetbrains.annotations.NotNull; + import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @@ -22,7 +24,7 @@ import java.util.concurrent.Future; * Author: dmitrylomov */ public class AsyncUtil { - public static V get(Future result) { + public static V get(@NotNull Future result) { try { return result.get(); } @@ -30,11 +32,12 @@ public class AsyncUtil { throw new Error(e); } catch (ExecutionException e) { - if (e.getCause() instanceof RuntimeException) - throw (RuntimeException) e.getCause(); - else + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException)e.getCause(); + } + else { throw new Error(e); + } } - } } diff --git a/platform/core-api/src/com/intellij/concurrency/DoOnce.java b/platform/core-api/src/com/intellij/concurrency/DoOnce.java index 6fa505e91257..c871e79247d0 100644 --- a/platform/core-api/src/com/intellij/concurrency/DoOnce.java +++ b/platform/core-api/src/com/intellij/concurrency/DoOnce.java @@ -15,18 +15,20 @@ */ package com.intellij.concurrency; +import org.jetbrains.annotations.NotNull; + import java.util.concurrent.atomic.AtomicBoolean; /** * Executes given runnable exactly once. - * + *

* Author: dmitrylomov */ public class DoOnce { private Runnable myRunnable; private final AtomicBoolean myAlreadyRun; - public DoOnce(Runnable runnable) { + public DoOnce(@NotNull Runnable runnable) { myRunnable = runnable; myAlreadyRun = new AtomicBoolean(false); } @@ -35,7 +37,8 @@ public class DoOnce { if (myAlreadyRun.compareAndSet(false, true)) { try { myRunnable.run(); - } finally { + } + finally { myRunnable = null; // do not leak runnable } } diff --git a/platform/core-api/src/com/intellij/concurrency/FinallyFuture.java b/platform/core-api/src/com/intellij/concurrency/FinallyFuture.java index f578b27f0b16..c392106befaa 100644 --- a/platform/core-api/src/com/intellij/concurrency/FinallyFuture.java +++ b/platform/core-api/src/com/intellij/concurrency/FinallyFuture.java @@ -15,6 +15,8 @@ */ package com.intellij.concurrency; +import org.jetbrains.annotations.NotNull; + import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; @@ -27,7 +29,7 @@ public class FinallyFuture implements AsyncFuture { private final DoOnce myFinallyBlock; private final AsyncFuture myInner; - public FinallyFuture(AsyncFuture inner, Runnable finallyBlock) { + public FinallyFuture(@NotNull AsyncFuture inner, @NotNull Runnable finallyBlock) { myInner = inner; myFinallyBlock = new DoOnce(finallyBlock); } @@ -35,8 +37,9 @@ public class FinallyFuture implements AsyncFuture { @Override public boolean cancel(boolean mayInterruptIfRunning) { boolean cancel = myInner.cancel(mayInterruptIfRunning); - if (cancel) + if (cancel) { myFinallyBlock.execute(); + } return cancel; } @@ -61,14 +64,15 @@ public class FinallyFuture implements AsyncFuture { } @Override - public void addConsumer(Executor executor, final ResultConsumer consumer) { + public void addConsumer(@NotNull Executor executor, @NotNull final ResultConsumer consumer) { myInner.addConsumer(executor, new ResultConsumer() { @Override public void onSuccess(V value) { try { myFinallyBlock.execute(); consumer.onSuccess(value); - } catch (Throwable t) { + } + catch (Throwable t) { consumer.onFailure(t); } } @@ -77,7 +81,8 @@ public class FinallyFuture implements AsyncFuture { public void onFailure(Throwable t) { try { myFinallyBlock.execute(); - } catch (Throwable t1) { + } + catch (Throwable t1) { t = t1; } consumer.onFailure(t); @@ -86,7 +91,7 @@ public class FinallyFuture implements AsyncFuture { } @Override - public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + public V get(long timeout, @NotNull TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { boolean timeoutOccurred = false; try { try { @@ -96,10 +101,11 @@ public class FinallyFuture implements AsyncFuture { timeoutOccurred = true; throw t; } - } finally { - if (!timeoutOccurred) - myFinallyBlock.execute(); } - + finally { + if (!timeoutOccurred) { + myFinallyBlock.execute(); + } + } } } diff --git a/platform/core-api/src/com/intellij/util/AbstractQuery.java b/platform/core-api/src/com/intellij/util/AbstractQuery.java index 5edacf03fd37..1c29ef6437ac 100644 --- a/platform/core-api/src/com/intellij/util/AbstractQuery.java +++ b/platform/core-api/src/com/intellij/util/AbstractQuery.java @@ -96,6 +96,7 @@ public abstract class AbstractQuery implements Query { protected abstract boolean processResults(@NotNull Processor consumer); + @NotNull protected AsyncFuture processResultsAsync(@NotNull Processor consumer) { final AsyncFutureResult result = AsyncFutureFactory.getInstance().createAsyncFutureResult(); try { diff --git a/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties b/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties index b2c613b073da..868aec0ba58f 100644 --- a/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties +++ b/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties @@ -44,4 +44,5 @@ run.configuration.description={0} build run.configuration.settings.label.project={0} project: run.configuration.settings.label.tasks=Tasks: run.configuration.settings.label.vmoptions=VM options: -run.configuration.settings.caption.vmoptions=VM options: \ No newline at end of file +run.configuration.settings.caption.vmoptions=VM options: +run.text.starting=Executing external tasks ''{0}''... \ No newline at end of file diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/execution/ExternalSystemTaskExecutionSettings.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/execution/ExternalSystemTaskExecutionSettings.java index 66b3ef91ffac..dfc54db28ff6 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/execution/ExternalSystemTaskExecutionSettings.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/execution/ExternalSystemTaskExecutionSettings.java @@ -71,8 +71,7 @@ public class ExternalSystemTaskExecutionSettings implements Cloneable { } public void setTaskNames(List taskNames) { - myTaskNames.clear(); - myTaskNames.addAll(taskNames); + myTaskNames = taskNames; } @Override diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java index a6aaffdb3906..ed5b60bd632b 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java @@ -18,11 +18,13 @@ import com.intellij.openapi.externalSystem.model.serialization.ExternalTaskPojo; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListenerAdapter; import com.intellij.openapi.externalSystem.service.internal.ExternalSystemExecuteTaskTask; +import com.intellij.openapi.externalSystem.util.ExternalSystemBundle; import com.intellij.openapi.options.SettingsEditor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.JDOMExternalizable; import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.containers.ContainerUtilRt; import com.intellij.util.xmlb.XmlSerializer; import org.jdom.Element; @@ -103,7 +105,7 @@ public class ExternalSystemRunConfiguration extends RunConfigurationBase { ConsoleView console = new TextConsoleBuilderImpl(getProject()).getConsole(); final MyProcessHandler processHandler = new MyProcessHandler(); console.attachToProcess(processHandler); - List tasks = ContainerUtilRt.newArrayList(); + final List tasks = ContainerUtilRt.newArrayList(); for (String taskName : mySettings.getTaskNames()) { tasks.add(new ExternalTaskPojo(taskName, mySettings.getExternalProjectPath(), null)); } @@ -114,9 +116,18 @@ public class ExternalSystemRunConfiguration extends RunConfigurationBase { ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { @Override public void run() { + String greeting = ExternalSystemBundle.message("run.text.starting", StringUtil.join(mySettings.getTaskNames(), " ")); + processHandler.notifyTextAvailable(greeting, ProcessOutputTypes.SYSTEM); task.execute(new ExternalSystemTaskNotificationListenerAdapter() { + + private boolean myResetGreeting = true; + @Override public void onTaskOutput(@NotNull ExternalSystemTaskId id, @NotNull String text, boolean stdOut) { + if (myResetGreeting) { + processHandler.notifyTextAvailable("\r", ProcessOutputTypes.SYSTEM); + myResetGreeting = false; + } processHandler.notifyTextAvailable(text, stdOut ? ProcessOutputTypes.STDOUT : ProcessOutputTypes.STDERR); } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskSettingsControl.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskSettingsControl.java index c36d1a623711..6f6902654429 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskSettingsControl.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskSettingsControl.java @@ -15,7 +15,6 @@ */ package com.intellij.openapi.externalSystem.service.execution; -import com.intellij.openapi.editor.Editor; import com.intellij.openapi.externalSystem.ExternalSystemManager; import com.intellij.openapi.externalSystem.ExternalSystemUiAware; import com.intellij.openapi.externalSystem.model.ProjectSystemId; @@ -30,11 +29,10 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.RawCommandLineEditor; import com.intellij.ui.components.JBLabel; import com.intellij.ui.components.JBTextField; -import com.intellij.util.Consumer; +import com.intellij.util.ui.GridBag; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.swing.*; import java.awt.*; import static com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil.normalizePath; @@ -94,52 +92,15 @@ public class ExternalSystemTaskSettingsControl implements ExternalSystemSettings myTasksLabel = new JBLabel(ExternalSystemBundle.message("run.configuration.settings.label.tasks")); myTasksTextField = new JBTextField(ExternalSystemConstants.TEXT_FIELD_WIDTH_IN_COLUMNS); canvas.add(myTasksLabel, ExternalSystemUiUtil.getLabelConstraints(0)); - canvas.add(myTasksTextField, ExternalSystemUiUtil.getFillLineConstraints(0)); + GridBag c = ExternalSystemUiUtil.getFillLineConstraints(0); + c.insets.right = myProjectPathField.getButton().getPreferredSize().width + 8 /* street magic, sorry */; + canvas.add(myTasksTextField, c); myVmOptionsLabel = new JBLabel(ExternalSystemBundle.message("run.configuration.settings.label.vmoptions")); myVmOptionsEditor = new RawCommandLineEditor(); myVmOptionsEditor.setDialogCaption(ExternalSystemBundle.message("run.configuration.settings.caption.vmoptions")); canvas.add(myVmOptionsLabel, ExternalSystemUiUtil.getLabelConstraints(0)); canvas.add(myVmOptionsEditor, ExternalSystemUiUtil.getFillLineConstraints(0)); - - canvas.setPaintCallback(new Consumer() { - - @Nullable private Dimension myDimension; - @Nullable private Dimension myBounds; - private boolean myBorderReset; - - @Override - public void consume(Graphics graphics) { - if (!myBorderReset) { - Editor editor = myProjectPathField.getChildComponent().getEditor(); - if (editor != null) { - myBorderReset = true; - editor.setBorder(null); - } - } - Dimension size = myVmOptionsEditor.getTextField().getPreferredSize(); - Rectangle bounds = myVmOptionsEditor.getTextField().getBounds(); - if (!size.equals(myDimension)) { - myDimension = size; - } - if (myBounds == null || myBounds.width != bounds.width || myBounds.height == bounds.height) { - myBounds = bounds.getSize(); - } - - applyDimension(myProjectPathField.getChildComponent(), false); - applyDimension(myTasksTextField, true); - } - - private void applyDimension(@NotNull JComponent component, boolean processBounds) { - Rectangle bounds = component.getBounds(); - if (bounds != null && myBounds != null && (bounds.width != myBounds.width || bounds.height != myBounds.height)) { - component.setPreferredSize(myDimension); - if (processBounds) { - component.setBounds(bounds.x, bounds.y, myBounds.width, myBounds.height); - } - } - } - }); } @Override diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectPathField.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectPathField.java index fa36d88c3f86..102591445c0b 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectPathField.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectPathField.java @@ -16,17 +16,26 @@ package com.intellij.openapi.externalSystem.service.ui; import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.FoldRegion; +import com.intellij.openapi.editor.FoldingModel; import com.intellij.openapi.externalSystem.ExternalSystemManager; import com.intellij.openapi.externalSystem.ExternalSystemUiAware; import com.intellij.openapi.externalSystem.model.ProjectSystemId; import com.intellij.openapi.externalSystem.model.serialization.ExternalProjectPojo; import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings; import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; +import com.intellij.openapi.fileChooser.FileChooser; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.ComponentWithBrowseButton; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.EditorTextField; import com.intellij.ui.TextAccessor; +import com.intellij.util.Consumer; import com.intellij.util.TextFieldCompletionProvider; import com.intellij.util.TextFieldCompletionProviderDumbAware; import com.intellij.util.ui.UIUtil; @@ -43,17 +52,31 @@ import java.util.Map; */ public class ExternalProjectPathField extends ComponentWithBrowseButton implements TextAccessor { + @NotNull private static final String PROJECT_FILE_TO_START_WITH_KEY = "external.system.task.project.file.to.start"; + + @NotNull private final Project myProject; + @NotNull private final ProjectSystemId myExternalSystemId; + public ExternalProjectPathField(@NotNull Project project, @NotNull ProjectSystemId externalSystemId, @NotNull FileChooserDescriptor descriptor, @NotNull String fileChooserTitle) { - super(createTextField(project, externalSystemId), createBrowseListener(descriptor, fileChooserTitle)); + super(createTextField(project, externalSystemId), new MyBrowseListener(descriptor, fileChooserTitle, project)); + ActionListener[] listeners = getButton().getActionListeners(); + for (ActionListener listener : listeners) { + if (listener instanceof MyBrowseListener) { + ((MyBrowseListener)listener).setPathField(getChildComponent()); + break; + } + } + myProject = project; + myExternalSystemId = externalSystemId; } @NotNull - private static EditorTextField createTextField(@NotNull Project project, @NotNull ProjectSystemId externalSystemId) { - ExternalSystemManager manager = ExternalSystemApiUtil.getManager(externalSystemId); + private static EditorTextField createTextField(@NotNull final Project project, @NotNull final ProjectSystemId externalSystemId) { + ExternalSystemManager manager = ExternalSystemApiUtil.getManager(externalSystemId); assert manager != null; final AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project); final ExternalSystemUiAware uiAware; @@ -84,38 +107,117 @@ public class ExternalProjectPathField extends ComponentWithBrowseButton() { + @Override + public void consume(Editor editor) { + collapseIfPossible(editor, externalSystemId, project); + } + }); result.setBorder(UIUtil.getTextFieldBorder()); result.setOneLineMode(true); result.setOpaque(true); result.setBackground(UIUtil.getTextFieldBackground()); return result; } + + @Override + public void setText(final String text) { + getChildComponent().setText(text); - @NotNull - private static ActionListener createBrowseListener(@NotNull final FileChooserDescriptor descriptor, - final @NotNull String fileChooserTitle) - { - return new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - descriptor.setTitle(fileChooserTitle); - // TODO den implement - //VirtualFile file = FileChooser.chooseFile(descriptor, get, null); - //if (file != null) { - // setWorkingDirectory(file.getPresentableUrl()); - //} - } - }; + Editor editor = getChildComponent().getEditor(); + if (editor != null) { + collapseIfPossible(editor, myExternalSystemId, myProject); + } } - @Override - public void setText(String text) { - getChildComponent().setText(text); + private static void collapseIfPossible(@NotNull final Editor editor, + @NotNull ProjectSystemId externalSystemId, + @NotNull Project project) + { + ExternalSystemManager manager = ExternalSystemApiUtil.getManager(externalSystemId); + assert manager != null; + final AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project); + final ExternalSystemUiAware uiAware; + if (manager instanceof ExternalSystemUiAware) { + uiAware = (ExternalSystemUiAware)manager; + } + else { + uiAware = DefaultExternalSystemUiAware.INSTANCE; + } + + String rawText = editor.getDocument().getText(); + for (Map.Entry> entry : settings.getAvailableProjects().entrySet()) { + if (entry.getKey().getPath().equals(rawText)) { + collapse(editor, uiAware.getProjectRepresentationName(entry.getKey().getPath(), null)); + return; + } + for (ExternalProjectPojo pojo : entry.getValue()) { + if (pojo.getPath().equals(rawText)) { + collapse(editor, uiAware.getProjectRepresentationName(pojo.getPath(), entry.getKey().getPath())); + return; + } + } + } + } + + private static void collapse(@NotNull final Editor editor, @NotNull final String placeholder) { + final FoldingModel foldingModel = editor.getFoldingModel(); + foldingModel.runBatchFoldingOperation(new Runnable() { + @Override + public void run() { + FoldRegion region = foldingModel.addFoldRegion(0, editor.getDocument().getTextLength(), placeholder); + if (region != null) { + region.setExpanded(false); + } + } + }); } @Override public String getText() { return getChildComponent().getText(); } + + private static class MyBrowseListener implements ActionListener { + + @NotNull private final FileChooserDescriptor myDescriptor; + @NotNull private final Project myProject; + private EditorTextField myPathField; + + MyBrowseListener(@NotNull final FileChooserDescriptor descriptor, + @NotNull final String fileChooserTitle, + @NotNull final Project project) + { + descriptor.setTitle(fileChooserTitle); + myDescriptor = descriptor; + myProject = project; + } + + private void setPathField(@NotNull EditorTextField pathField) { + myPathField = pathField; + } + + @Override + public void actionPerformed(ActionEvent e) { + if (myPathField == null) { + assert false; + return; + } + PropertiesComponent component = PropertiesComponent.getInstance(myProject); + String pathToStart = myPathField.getText(); + if (StringUtil.isEmpty(pathToStart)) { + pathToStart = component.getValue(PROJECT_FILE_TO_START_WITH_KEY); + } + VirtualFile fileToStart = null; + if (!StringUtil.isEmpty(pathToStart)) { + fileToStart = LocalFileSystem.getInstance().findFileByPath(pathToStart); + } + VirtualFile file = FileChooser.chooseFile(myDescriptor, myProject, fileToStart); + if (file != null) { + String path = ExternalSystemApiUtil.getLocalFileSystemPath(file); + myPathField.setText(path); + component.setValue(PROJECT_FILE_TO_START_WITH_KEY, path); + } + } + } } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectPathLookupElement.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectPathLookupElement.java index 8490eb4d8513..a5837173aeb0 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectPathLookupElement.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectPathLookupElement.java @@ -49,12 +49,24 @@ public class ExternalProjectPathLookupElement extends LookupElement { @Override public void handleInsert(InsertionContext context) { Editor editor = context.getEditor(); + final FoldingModel foldingModel = editor.getFoldingModel(); + foldingModel.runBatchFoldingOperation(new Runnable() { + @Override + public void run() { + FoldRegion[] regions = foldingModel.getAllFoldRegions(); + for (FoldRegion region : regions) { + foldingModel.removeFoldRegion(region); + } + } + }); + final Document document = editor.getDocument(); final int startOffset = context.getStartOffset(); - document.replaceString(startOffset, context.getTailOffset(), myProjectPath); + + document.replaceString(startOffset, document.getTextLength(), myProjectPath); final Project project = context.getProject(); PsiDocumentManager.getInstance(project).commitDocument(document); - final FoldingModel foldingModel = editor.getFoldingModel(); + foldingModel.runBatchFoldingOperationDoNotCollapseCaret(new Runnable() { @Override public void run() { diff --git a/platform/indexing-api/src/com/intellij/psi/search/SearchRequestQuery.java b/platform/indexing-api/src/com/intellij/psi/search/SearchRequestQuery.java index c51e984fba9b..6ba2f7eb6458 100644 --- a/platform/indexing-api/src/com/intellij/psi/search/SearchRequestQuery.java +++ b/platform/indexing-api/src/com/intellij/psi/search/SearchRequestQuery.java @@ -14,11 +14,12 @@ public class SearchRequestQuery extends AbstractQuery { private final Project myProject; private final SearchRequestCollector myRequests; - public SearchRequestQuery(Project project, SearchRequestCollector requests) { + public SearchRequestQuery(@NotNull Project project, @NotNull SearchRequestCollector requests) { myProject = project; myRequests = requests; } + @NotNull @Override protected AsyncFuture processResultsAsync(@NotNull Processor consumer) { return PsiSearchHelper.SERVICE.getInstance(myProject).processRequestsAsync(myRequests, consumer); diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java b/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java index 36dceef358e4..d2843fca6464 100644 --- a/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java +++ b/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java @@ -221,81 +221,82 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { @NotNull final Processor psiRootProcessor, final ProgressIndicator progress) { myManager.startBatchFilesProcessingMode(); - final AtomicInteger counter = new AtomicInteger(0); - final AtomicBoolean canceled = new AtomicBoolean(false); - final AtomicBoolean pceThrown = new AtomicBoolean(false); + final AtomicInteger counter = new AtomicInteger(0); + final AtomicBoolean canceled = new AtomicBoolean(false); + final AtomicBoolean pceThrown = new AtomicBoolean(false); - final int size = files.size(); - AsyncFuture - completed = JobLauncher.getInstance().invokeConcurrentlyUnderProgressAsync(files, progress, false, new Processor() { - @Override - public boolean process(final VirtualFile vfile) { - final PsiFile file = ApplicationManager.getApplication().runReadAction(new Computable() { + final int size = files.size(); + AsyncFuture + completed = JobLauncher.getInstance().invokeConcurrentlyUnderProgressAsync(files, progress, false, new Processor() { + @Override + public boolean process(final VirtualFile vfile) { + final PsiFile file = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public PsiFile compute() { + return vfile.isValid() ? myManager.findFile(vfile) : null; + } + }); + if (file != null && !(file instanceof PsiBinaryFile)) { + file.getViewProvider().getContents(); // load contents outside readaction + ApplicationManager.getApplication().runReadAction(new Runnable() { @Override - public PsiFile compute() { - return vfile.isValid() ? myManager.findFile(vfile) : null; + public void run() { + try { + if (myManager.getProject().isDisposed()) throw new ProcessCanceledException(); + List psiRoots = file.getViewProvider().getAllFiles(); + Set processed = new THashSet(psiRoots.size() * 2, (float)0.5); + for (PsiElement psiRoot : psiRoots) { + if (progress != null) progress.checkCanceled(); + assert psiRoot != null : "One of the roots of file " + file + " is null. All roots: " + psiRoots + + "; ViewProvider: " + file.getViewProvider() + "; Virtual file: " + file.getViewProvider().getVirtualFile(); + if (!processed.add(psiRoot)) continue; + if (!psiRoot.isValid()) continue; + if (!psiRootProcessor.process(psiRoot)) { + canceled.set(true); + return; + } + } + myManager.dropResolveCaches(); + } + catch (ProcessCanceledException e) { + canceled.set(true); + pceThrown.set(true); + } } }); - if (file != null && !(file instanceof PsiBinaryFile)) { - file.getViewProvider().getContents(); // load contents outside readaction - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - try { - if (myManager.getProject().isDisposed()) throw new ProcessCanceledException(); - List psiRoots = file.getViewProvider().getAllFiles(); - Set processed = new THashSet(psiRoots.size() * 2, (float)0.5); - for (PsiElement psiRoot : psiRoots) { - if (progress != null) progress.checkCanceled(); - assert psiRoot != null : "One of the roots of file " + file + " is null. All roots: " + psiRoots + - "; ViewProvider: " + file.getViewProvider() + "; Virtual file: " + file.getViewProvider().getVirtualFile(); - if (!processed.add(psiRoot)) continue; - if (!psiRoot.isValid()) continue; - if (!psiRootProcessor.process(psiRoot)) { - canceled.set(true); - return; - } - } - myManager.dropResolveCaches(); - } - catch (ProcessCanceledException e) { - canceled.set(true); - pceThrown.set(true); - } - } - }); - } - if (progress != null && progress.isRunning()) { - double fraction = (double)counter.incrementAndGet() / size; - progress.setFraction(fraction); - } - return !canceled.get(); } - }); - - final AsyncFutureResult ourResult = AsyncFutureFactory.getInstance().createAsyncFutureResult(); - completed.addConsumer(SameThreadExecutor.INSTANCE, new DefaultResultConsumer(ourResult) { - @Override - public void onSuccess(Boolean value) { - if (pceThrown.get()) - ourResult.setException(new ProcessCanceledException()); - else - ourResult.set(value); + if (progress != null && progress.isRunning()) { + double fraction = (double)counter.incrementAndGet() / size; + progress.setFraction(fraction); } + return !canceled.get(); + } + }); - @Override - public void onFailure(Throwable t) { - ourResult.setException(t); + final AsyncFutureResult ourResult = AsyncFutureFactory.getInstance().createAsyncFutureResult(); + completed.addConsumer(SameThreadExecutor.INSTANCE, new DefaultResultConsumer(ourResult) { + @Override + public void onSuccess(Boolean value) { + if (pceThrown.get()) { + ourResult.setException(new ProcessCanceledException()); } - }); - - - return new FinallyFuture(ourResult, new Runnable() { - @Override - public void run() { - myManager.finishBatchFilesProcessingMode(); + else { + ourResult.set(value); } - }); + } + + @Override + public void onFailure(Throwable t) { + ourResult.setException(t); + } + }); + + return new FinallyFuture(ourResult, new Runnable() { + @Override + public void run() { + myManager.finishBatchFilesProcessingMode(); + } + }); } @NotNull @@ -597,7 +598,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { @NotNull private AsyncFuture processGlobalRequestsOptimizedAsync(@NotNull MultiMap, RequestWithProcessor> singles, - final ProgressIndicator progress) { + final ProgressIndicator progress) { if (singles.isEmpty()) { return AsyncFutureFactory.wrap(true); } diff --git a/platform/lang-impl/src/com/intellij/application/options/ModuleAwareProjectConfigurable.java b/platform/lang-impl/src/com/intellij/application/options/ModuleAwareProjectConfigurable.java new file mode 100644 index 000000000000..03d97dd7cb44 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/application/options/ModuleAwareProjectConfigurable.java @@ -0,0 +1,142 @@ +package com.intellij.application.options; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.options.SearchableConfigurable; +import com.intellij.openapi.options.UnnamedConfigurable; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Splitter; +import com.intellij.platform.ModuleAttachProcessor; +import com.intellij.ui.CollectionListModel; +import com.intellij.ui.components.JBList; +import com.intellij.ui.components.JBScrollPane; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author yole + */ +public abstract class ModuleAwareProjectConfigurable implements SearchableConfigurable { + private final Project myProject; + private final String myDisplayName; + private final String myHelpTopic; + private final Map myModuleConfigurables = new HashMap(); + + public ModuleAwareProjectConfigurable(Project project, String displayName, String helpTopic) { + myProject = project; + myDisplayName = displayName; + myHelpTopic = helpTopic; + } + + @Nls + @Override + public String getDisplayName() { + return myDisplayName; + } + + @Override + public String getHelpTopic() { + return myHelpTopic; + } + + @Override + public JComponent createComponent() { + if (myProject.isDefault()) { + T configurable = createDefaultProjectConfigurable(); + if (configurable != null) { + myModuleConfigurables.put(null, configurable); + return configurable.createComponent(); + } + } + final List modules = ModuleAttachProcessor.getSortedModules(myProject); + if (modules.size() == 1) { + Module module = modules.get(0); + final T configurable = createModuleConfigurable(module); + myModuleConfigurables.put(module, configurable); + return configurable.createComponent(); + } + final Splitter splitter = new Splitter(false, 0.25f); + final JBList moduleList = new JBList(new CollectionListModel(modules)); + moduleList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + moduleList.setCellRenderer(new ModuleListCellRenderer()); + splitter.setFirstComponent(new JBScrollPane(moduleList)); + final CardLayout layout = new CardLayout(); + final JPanel cardPanel = new JPanel(layout); + splitter.setSecondComponent(cardPanel); + for (Module module : modules) { + final T configurable = createModuleConfigurable(module); + myModuleConfigurables.put(module, configurable); + final JComponent component = configurable.createComponent(); + cardPanel.add(component, module.getName()); + } + moduleList.addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + final Module value = (Module)moduleList.getSelectedValue(); + layout.show(cardPanel, value.getName()); + } + }); + if (modules.size() > 0) { + moduleList.setSelectedIndex(0); + layout.show(cardPanel, modules.get(0).getName()); + } + return splitter; + } + + @Nullable + protected T createDefaultProjectConfigurable() { + return null; + } + + protected abstract T createModuleConfigurable(Module module); + + @Override + public boolean isModified() { + for (T configurable : myModuleConfigurables.values()) { + if (configurable.isModified()) return true; + } + return false; + } + + @Override + public void apply() throws ConfigurationException { + for (T configurable : myModuleConfigurables.values()) { + configurable.apply(); + } + } + + @Override + public void reset() { + for (T configurable : myModuleConfigurables.values()) { + configurable.reset(); + } + } + + @Override + public void disposeUIResources() { + for (T configurable : myModuleConfigurables.values()) { + configurable.disposeUIResources(); + } + myModuleConfigurables.clear(); + } + + @NotNull + @Override + public String getId() { + return getClass().getName(); + } + + @Override + public Runnable enableSearch(String option) { + return null; + } +} diff --git a/platform/lang-impl/src/com/intellij/application/options/ModuleListCellRenderer.java b/platform/lang-impl/src/com/intellij/application/options/ModuleListCellRenderer.java new file mode 100644 index 000000000000..f544517bb5d4 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/application/options/ModuleListCellRenderer.java @@ -0,0 +1,23 @@ +package com.intellij.application.options; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleType; +import com.intellij.ui.ListCellRendererWrapper; + +import javax.swing.*; + +/** +* @author yole +*/ +public class ModuleListCellRenderer extends ListCellRendererWrapper { + @Override + public void customize(JList list, Module module, int index, boolean selected, boolean hasFocus) { + if (module == null) { + setText("[none]"); + } + else { + setIcon(ModuleType.get(module).getIcon()); + setText(module.getName()); + } + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionPhase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionPhase.java index afa0aa70f513..8d1919e7c1ff 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionPhase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionPhase.java @@ -31,6 +31,8 @@ import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.editor.*; import com.intellij.openapi.editor.actionSystem.TypedAction; import com.intellij.openapi.editor.event.*; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.ex.FocusChangeListener; import com.intellij.openapi.fileEditor.FileEditorManagerAdapter; import com.intellij.openapi.fileEditor.FileEditorManagerEvent; import com.intellij.openapi.fileEditor.FileEditorManagerListener; @@ -177,6 +179,19 @@ public abstract class CompletionPhase implements Disposable { } } }, this); + if (indicator.isAutopopupCompletion()) { + // lookup is not visible, we have to check ourselves if editor retains focus + ((EditorEx)indicator.getEditor()).addFocusListener(new FocusChangeListener() { + @Override + public void focusGained(Editor editor) { + } + + @Override + public void focusLost(Editor editor) { + indicator.closeAndFinish(true); + } + }, this); + } } @Override diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/BetterPrefixMatcher.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/BetterPrefixMatcher.java new file mode 100644 index 000000000000..968da5f89a31 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/BetterPrefixMatcher.java @@ -0,0 +1,59 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.completion.impl; + +import com.intellij.codeInsight.completion.CompletionResult; +import com.intellij.codeInsight.completion.PrefixMatcher; +import org.jetbrains.annotations.NotNull; + +import java.util.LinkedHashSet; + +/** + * @author peter + */ +public class BetterPrefixMatcher extends PrefixMatcher { + private final PrefixMatcher myOriginal; + private final int myMinMatchingDegree; + + public BetterPrefixMatcher(PrefixMatcher original, int minMatchingDegree) { + super(original.getPrefix()); + myOriginal = original; + myMinMatchingDegree = minMatchingDegree; + } + + public static int getBestMatchingDegree(LinkedHashSet plainResults) { + int bestMatchingDegree = Integer.MIN_VALUE; + for (CompletionResult cr : plainResults) { + bestMatchingDegree = Math.max(bestMatchingDegree, RealPrefixMatchingWeigher + .getBestMatchingDegree(cr.getLookupElement(), cr.getPrefixMatcher())); + } + return bestMatchingDegree; + } + + @Override + public boolean prefixMatches(@NotNull String name) { + if (!myOriginal.prefixMatches(name) || !myOriginal.isStartMatch(name)) { + return false; + } + return myOriginal.matchingDegree(name) >= myMinMatchingDegree; + } + + @NotNull + @Override + public PrefixMatcher cloneWithPrefix(@NotNull String prefix) { + return new BetterPrefixMatcher(myOriginal.cloneWithPrefix(prefix), myMinMatchingDegree); + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/RealPrefixMatchingWeigher.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/RealPrefixMatchingWeigher.java index 26491a0bb36d..9169142f5180 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/RealPrefixMatchingWeigher.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/RealPrefixMatchingWeigher.java @@ -19,13 +19,14 @@ public class RealPrefixMatchingWeigher extends LookupElementWeigher { @Override public Comparable weigh(@NotNull LookupElement element) { - final PrefixMatcher matcher = CompletionServiceImpl.getItemMatcher(element, myLocation.getCompletionParameters().getLookup()); + return getBestMatchingDegree(element, CompletionServiceImpl.getItemMatcher(element, myLocation.getCompletionParameters().getLookup())); + } + public static int getBestMatchingDegree(LookupElement element, PrefixMatcher matcher) { int max = Integer.MIN_VALUE; for (String lookupString : element.getAllLookupStrings()) { max = Math.max(max, matcher.matchingDegree(lookupString)); } return -max; } - } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/actions/ChooseItemAction.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/actions/ChooseItemAction.java index 49c7e89c2203..6f93833f6755 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/actions/ChooseItemAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/actions/ChooseItemAction.java @@ -84,9 +84,6 @@ public abstract class ChooseItemAction extends EditorAction { return false; } if (finishingChar == Lookup.REPLACE_SELECT_CHAR) { - if (lookup.isFocused()) { - return true; - } return !lookup.getItems().isEmpty(); } diff --git a/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java b/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java index d6da349d512a..6c0907beb148 100644 --- a/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java +++ b/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java @@ -21,6 +21,7 @@ import com.intellij.ide.CutProvider; import com.intellij.ide.DeleteProvider; import com.intellij.ide.PasteProvider; import com.intellij.ide.highlighter.HighlighterFactory; +import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.*; @@ -628,6 +629,11 @@ public class EditorWindow extends UserDataHolderBase implements EditorEx { myDelegate.addFocusListener(listener); } + @Override + public void addFocusListener(@NotNull FocusChangeListener listener, Disposable parentDisposable) { + myDelegate.addFocusListener(listener, parentDisposable); + } + @Override public Project getProject() { return myDelegate.getProject(); diff --git a/platform/lang-impl/src/com/intellij/util/TextFieldCompletionProvider.java b/platform/lang-impl/src/com/intellij/util/TextFieldCompletionProvider.java index 5b50c48bb6ed..09c1a7e83e06 100644 --- a/platform/lang-impl/src/com/intellij/util/TextFieldCompletionProvider.java +++ b/platform/lang-impl/src/com/intellij/util/TextFieldCompletionProvider.java @@ -13,6 +13,7 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFileFactory; import com.intellij.ui.EditorTextField; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author sergey.evdokimov @@ -68,11 +69,21 @@ public abstract class TextFieldCompletionProvider { protected abstract void addCompletionVariants(@NotNull String text, int offset, @NotNull String prefix, @NotNull CompletionResultSet result); + @NotNull public EditorTextField createEditor(Project project) { return createEditor(project, true); } + @NotNull public EditorTextField createEditor(Project project, final boolean shouldHaveBorder) { + return createEditor(project, shouldHaveBorder, null); + } + + @NotNull + public EditorTextField createEditor(Project project, + final boolean shouldHaveBorder, + @Nullable final Consumer editorConstructionCallback) + { return new EditorTextField(createDocument(project, ""), project, PlainTextLanguage.INSTANCE.getAssociatedFileType()) { @Override protected boolean shouldHaveBorder() { @@ -88,6 +99,15 @@ public abstract class TextFieldCompletionProvider { editor.setBorder(null); } } + + @Override + protected EditorEx createEditor() { + EditorEx result = super.createEditor(); + if (editorConstructionCallback != null) { + editorConstructionCallback.consume(result); + } + return result; + } }; } } diff --git a/platform/platform-api/src/com/intellij/openapi/roots/ui/util/CompositeAppearance.java b/platform/platform-api/src/com/intellij/openapi/roots/ui/util/CompositeAppearance.java index 8ec0e75a36a2..d178f06c9310 100644 --- a/platform/platform-api/src/com/intellij/openapi/roots/ui/util/CompositeAppearance.java +++ b/platform/platform-api/src/com/intellij/openapi/roots/ui/util/CompositeAppearance.java @@ -24,18 +24,20 @@ import com.intellij.ui.SimpleTextAttributes; import com.intellij.util.PlatformIcons; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.TestOnly; import javax.swing.*; import java.awt.*; import java.util.ArrayList; import java.util.Iterator; +import java.util.List; // todo: move to lang-impl ? public class CompositeAppearance implements ModifiableCellAppearanceEx { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.ui.util.CompositeAppearance"); private Icon myIcon; - private final ArrayList mySections = new ArrayList(); + private final List mySections = new ArrayList(); private int myInsertionIndex = 0; public void customize(@NotNull SimpleColoredComponent component) { @@ -148,6 +150,7 @@ public class CompositeAppearance implements ModifiableCellAppearanceEx { return appearance; } + @TestOnly public Iterator getSectionsIterator() { return mySections.iterator(); } @@ -155,8 +158,8 @@ public class CompositeAppearance implements ModifiableCellAppearanceEx { public static class TextSection { private static final TextAttributes DEFAULT_TEXT_ATTRIBUTES = new TextAttributes(null, null, null, null, Font.PLAIN); private static final String DEFAULT_TEXT = ""; - private String TEXT; - private TextAttributes ATTRIBUTES; + private final String TEXT; + private final TextAttributes ATTRIBUTES; public TextSection(String text, TextAttributes attributes) { ATTRIBUTES = attributes == null ? DEFAULT_TEXT_ATTRIBUTES : attributes; @@ -198,7 +201,7 @@ public class CompositeAppearance implements ModifiableCellAppearanceEx { } public void addSurrounded(String text, String prefix, String suffix, SimpleTextAttributes textAttributes) { - if (text != null && text.trim().length() > 0) { + if (text != null && !text.trim().isEmpty()) { addText(prefix + text + suffix, textAttributes); } } diff --git a/platform/platform-impl/src/com/intellij/concurrency/AsyncFutureResultImpl.java b/platform/platform-impl/src/com/intellij/concurrency/AsyncFutureResultImpl.java index bd59fcd8001b..92e6e768c983 100644 --- a/platform/platform-impl/src/com/intellij/concurrency/AsyncFutureResultImpl.java +++ b/platform/platform-impl/src/com/intellij/concurrency/AsyncFutureResultImpl.java @@ -16,6 +16,7 @@ package com.intellij.concurrency; import com.google.common.util.concurrent.SettableFuture; +import org.jetbrains.annotations.NotNull; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; @@ -33,16 +34,18 @@ public class AsyncFutureResultImpl implements AsyncFutureResult { } @Override - public void addConsumer(Executor executor, final ResultConsumer consumer) { + public void addConsumer(@NotNull Executor executor, @NotNull final ResultConsumer consumer) { myFuture.addListener(new Runnable() { @Override public void run() { try { final V result = myFuture.get(); consumer.onSuccess(result); - } catch (ExecutionException e) { + } + catch (ExecutionException e) { consumer.onFailure(e.getCause()); - } catch (Throwable throwable) { + } + catch (Throwable throwable) { consumer.onFailure(throwable); } } @@ -70,7 +73,7 @@ public class AsyncFutureResultImpl implements AsyncFutureResult { } @Override - public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + public V get(long timeout, @NotNull TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { return myFuture.get(timeout, unit); } @@ -80,7 +83,7 @@ public class AsyncFutureResultImpl implements AsyncFutureResult { } @Override - public void setException(Throwable t) { + public void setException(@NotNull Throwable t) { myFuture.setException(t); } } diff --git a/platform/platform-impl/src/com/intellij/concurrency/JobLauncherImpl.java b/platform/platform-impl/src/com/intellij/concurrency/JobLauncherImpl.java index 670daace34e0..37319eaea59b 100644 --- a/platform/platform-impl/src/com/intellij/concurrency/JobLauncherImpl.java +++ b/platform/platform-impl/src/com/intellij/concurrency/JobLauncherImpl.java @@ -130,7 +130,8 @@ public class JobLauncherImpl extends JobLauncher { try { final boolean result = invokeConcurrentlyUnderProgress(things, progress, failFastOnAcquireReadAction, thingProcessor); asyncFutureResult.set(result); - } catch (Throwable t) { + } + catch (Throwable t) { asyncFutureResult.setException(t); } return asyncFutureResult; diff --git a/platform/platform-impl/src/com/intellij/featureStatistics/ProductivityFeaturesRegistryImpl.java b/platform/platform-impl/src/com/intellij/featureStatistics/ProductivityFeaturesRegistryImpl.java index 4a72378a2ccc..870a163003ca 100644 --- a/platform/platform-impl/src/com/intellij/featureStatistics/ProductivityFeaturesRegistryImpl.java +++ b/platform/platform-impl/src/com/intellij/featureStatistics/ProductivityFeaturesRegistryImpl.java @@ -57,7 +57,9 @@ public class ProductivityFeaturesRegistryImpl extends ProductivityFeaturesRegist readFromXml("file:///ProductivityFeaturesRegistry.xml"); } catch (Exception e) { - LOG.error(e); + if (!ApplicationManager.getApplication().isUnitTestMode()) { + LOG.error(e); + } } try { diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryHelper.java b/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryHelper.java index 6eb30e414f31..b4975925ad3c 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryHelper.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryHelper.java @@ -15,6 +15,8 @@ */ package com.intellij.ide.plugins; +import com.google.common.hash.Hashing; +import com.google.common.io.Files; import com.intellij.ide.IdeBundle; import com.intellij.openapi.application.ApplicationInfo; import com.intellij.openapi.application.PathManager; @@ -50,6 +52,11 @@ public class RepositoryHelper { indicator.setText2(IdeBundle.message("progress.connecting.to.plugin.manager", appInfo.getPluginManagerUrl())); } + File pluginListFile = new File(PathManager.getPluginsPath(), PLUGIN_LIST_FILE); + if (pluginListFile.length() > 0) { + url = url + "&crc32=" + Files.hash(pluginListFile, Hashing.crc32()).toString(); + } + HttpURLConnection connection = HttpConfigurable.getInstance().openHttpConnection(url); connection.setRequestProperty("Accept-Encoding", "gzip"); @@ -63,6 +70,10 @@ public class RepositoryHelper { indicator.checkCanceled(); } + if (connection.getResponseCode() == 304) { + return loadPluginList(pluginListFile); + } + String encoding = connection.getContentEncoding(); InputStream is = connection.getInputStream(); try { @@ -103,9 +114,13 @@ public class RepositoryHelper { os.close(); } + return loadPluginList(temp); + } + + private static List loadPluginList(File file) throws Exception { SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); RepositoryContentHandler handler = new RepositoryContentHandler(); - parser.parse(temp, handler); + parser.parse(file, handler); return handler.getPluginsList(); } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/StatisticsUploadAssistant.java b/platform/platform-impl/src/com/intellij/internal/statistic/StatisticsUploadAssistant.java index 9c7025d0c6fc..ec939cb7da31 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/StatisticsUploadAssistant.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/StatisticsUploadAssistant.java @@ -23,7 +23,6 @@ import com.intellij.internal.statistic.beans.PatchedUsage; import com.intellij.internal.statistic.beans.UsageDescriptor; import com.intellij.internal.statistic.persistence.SentUsagesPersistence; import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent; -import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; @@ -176,12 +175,12 @@ public class StatisticsUploadAssistant { private static Map> mapToPatchedUsagesMap(Map> allUsages) { Map> patchedUsages = new LinkedHashMap>(); for (Map.Entry> entry : allUsages.entrySet()) { - patchedUsages.put(entry.getKey(), ContainerUtil.map2Set(entry.getValue(), new Function() { + patchedUsages.put(entry.getKey(), new HashSet(ContainerUtil.map2Set(entry.getValue(), new Function() { @Override public PatchedUsage fun(UsageDescriptor usageDescriptor) { return new PatchedUsage(usageDescriptor); } - })); + }))); } return patchedUsages; } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorEx.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorEx.java index b5e04cbabe43..3e5575154407 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorEx.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorEx.java @@ -19,6 +19,7 @@ import com.intellij.ide.CopyProvider; import com.intellij.ide.CutProvider; import com.intellij.ide.DeleteProvider; import com.intellij.ide.PasteProvider; +import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.LogicalPosition; @@ -105,6 +106,8 @@ public interface EditorEx extends Editor { boolean setCaretEnabled(boolean enabled); void addFocusListener(@NotNull FocusChangeListener listener); + + void addFocusListener(@NotNull FocusChangeListener listener, Disposable parentDisposable); void setOneLineMode(boolean b); 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 29853472614e..8c86fe37979b 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 @@ -2199,7 +2199,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi if (hEnd >= lEnd) { FoldRegion collapsedFolderAt = myFoldingModel.getCollapsedRegionAtOffset(start); - if (collapsedFolderAt == null) { + if (collapsedFolderAt == null || collapsedFolderAt.getEndOffset() == lEnd) { position.x = drawSoftWrapAwareBackground(g, backColor, text, start, lEnd - lIterator.getSeparatorLength(), position, fontType, defaultBackground, clip, softWrapsToSkip, caretRowPainted); @@ -4268,6 +4268,11 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi myFocusListeners.add(listener); } + @Override + public void addFocusListener(@NotNull FocusChangeListener listener, Disposable parentDisposable) { + ContainerUtil.add(listener, myFocusListeners, parentDisposable); + } + @Override @Nullable public Project getProject() { diff --git a/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java index 231d93e6d8d0..97fbdcc1856b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java @@ -16,12 +16,10 @@ package com.intellij.openapi.fileChooser.ex; import com.intellij.icons.AllIcons; -import com.intellij.ide.IdeBundle; import com.intellij.ide.IdeEventQueue; import com.intellij.ide.SaveAndSyncHandlerImpl; import com.intellij.ide.util.PropertiesComponent; import com.intellij.ide.util.treeView.NodeRenderer; -import com.intellij.idea.ActionsBundle; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationActivationListener; import com.intellij.openapi.application.ApplicationManager; @@ -44,7 +42,6 @@ import com.intellij.openapi.wm.IdeFrame; import com.intellij.ui.*; import com.intellij.ui.components.JBList; import com.intellij.ui.components.labels.LinkLabel; -import com.intellij.ui.components.labels.LinkListener; import com.intellij.util.ArrayUtil; import com.intellij.util.Consumer; import com.intellij.util.IconUtil; @@ -75,6 +72,7 @@ import java.util.List; import java.util.Map; public class FileChooserDialogImpl extends DialogWrapper implements FileChooserDialog, PathChooserDialog, FileLookup { + @NonNls public static final String FILE_CHOOSER_SHOW_PATH_PROPERTY = "FileChooser.ShowPath"; public static final String RECENT_FILES_KEY = "file.chooser.recent.files"; private final FileChooserDescriptor myChooserDescriptor; protected FileSystemTreeImpl myFileSystemTree; @@ -292,7 +290,11 @@ public class FileChooserDialogImpl extends DialogWrapper implements FileChooserD final JPanel toolbarPanel = new JPanel(new BorderLayout()); toolbarPanel.add(toolBar.getComponent(), BorderLayout.CENTER); - myTextFieldAction = new TextFieldAction(); + myTextFieldAction = new TextFieldAction() { + public void linkSelected(final LinkLabel aSource, final Object aLinkData) { + toggleShowTextField(); + } + }; toolbarPanel.add(myTextFieldAction, BorderLayout.EAST); myPathTextFieldWrapper = new JPanel(new BorderLayout()); @@ -474,11 +476,11 @@ public class FileChooserDialogImpl extends DialogWrapper implements FileChooserD private final Map myRequests = new HashMap(); private static boolean isToShowTextField() { - return PropertiesComponent.getInstance().getBoolean("FileChooser.ShowPath", true); + return PropertiesComponent.getInstance().getBoolean(FILE_CHOOSER_SHOW_PATH_PROPERTY, true); } private static void setToShowTextField(boolean toShowTextField) { - PropertiesComponent.getInstance().setValue("FileChooser.ShowPath", Boolean.toString(toShowTextField)); + PropertiesComponent.getInstance().setValue(FILE_CHOOSER_SHOW_PATH_PROPERTY, Boolean.toString(toShowTextField)); } private final class FileTreeExpansionListener implements TreeExpansionListener { @@ -577,34 +579,6 @@ public class FileChooserDialogImpl extends DialogWrapper implements FileChooserD } - private class TextFieldAction extends LinkLabel implements LinkListener { - public TextFieldAction() { - super("", null); - setListener(this, null); - update(); - } - - protected void onSetActive(final boolean active) { - final String tooltip = AnAction - .createTooltipText(ActionsBundle.message("action.FileChooser.TogglePathShowing.text"), - ActionManager.getInstance().getAction("FileChooser.TogglePathShowing")); - setToolTipText(tooltip); - } - - protected String getStatusBarText() { - return ActionsBundle.message("action.FileChooser.TogglePathShowing.text"); - } - - public void update() { - setVisible(true); - setText(isToShowTextField() ? IdeBundle.message("file.chooser.hide.path") : IdeBundle.message("file.chooser.show.path")); - } - - public void linkSelected(final LinkLabel aSource, final Object aLinkData) { - toggleShowTextField(); - } - } - private void updatePathFromTree(final List selection, boolean now) { if (!isToShowTextField() || myTreeIsUpdating) return; diff --git a/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/TextFieldAction.java b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/TextFieldAction.java new file mode 100644 index 000000000000..f65b082a0319 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/TextFieldAction.java @@ -0,0 +1,54 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.fileChooser.ex; + +import com.intellij.ide.IdeBundle; +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.idea.ActionsBundle; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.ui.components.labels.LinkLabel; +import com.intellij.ui.components.labels.LinkListener; + +/** +* User: anna +*/ +public abstract class TextFieldAction extends LinkLabel implements LinkListener { + public TextFieldAction() { + super("", null); + setListener(this, null); + update(); + } + + protected void onSetActive(final boolean active) { + final String tooltip = AnAction + .createTooltipText(ActionsBundle.message("action.FileChooser.TogglePathShowing.text"), + ActionManager.getInstance().getAction("FileChooser.TogglePathShowing")); + setToolTipText(tooltip); + } + + protected String getStatusBarText() { + return ActionsBundle.message("action.FileChooser.TogglePathShowing.text"); + } + + public void update() { + setVisible(true); + setText(PropertiesComponent.getInstance().getBoolean(FileChooserDialogImpl.FILE_CHOOSER_SHOW_PATH_PROPERTY, true) ? IdeBundle.message("file.chooser.hide.path") : IdeBundle.message("file.chooser.show.path")); + } + + + +} diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 256ca86a4354..224f21b6d8d9 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -131,7 +131,7 @@ ide.mac.hide.cursor.when.typing=true ide.mac.show.native.help=true ide.mac.useNativeClipboard=false ide.mac.boldEditorTabs=false -ide.mac.modalDialogsOnFullscreen=true +ide.mac.modalDialogsOnFullscreen=false # suppress inspection "UnusedProperty" ide.mac.modalDialogsOnFullscreen.description=New modality approach. All dialogs are DOCUMENT_MODAL expect ide-wide dialogs @@ -215,6 +215,7 @@ documentation.component.editor.font=false find.usage.expand.all=false ide.completion.show.all.classes=false +ide.completion.show.better.matching.classes=false ide.completion.middle.matching=true # suppress inspection "UnusedProperty" diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/FileDocumentManagerImplTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/FileDocumentManagerImplTest.java index f9e2b4bc6e27..dffec2b1f7c5 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/FileDocumentManagerImplTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/FileDocumentManagerImplTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,7 +67,7 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture { MockEditorFactory editorFactory = new MockEditorFactory(); getApplication().registerService(EditorFactory.class, editorFactory); final LanguageFileType[] fileType = {null}; - getApplication().addComponent(FileTypeManager.class, new FileTypeManagerImpl(null, new MockSchemesManagerFactory()){ + getApplication().addComponent(FileTypeManager.class, new FileTypeManagerImpl(null, new MockSchemesManagerFactory()) { @NotNull @Override public FileType getFileTypeByFileName(@NotNull String fileName) { @@ -174,8 +174,8 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture { final Document[] unsavedDocuments = myDocumentManager.getUnsavedDocuments(); assertEquals(1, unsavedDocuments.length); - assertSame(document, unsavedDocuments[0]); - assertTrue(Arrays.equals("test".getBytes(), file.contentsToByteArray())); + assertSame(document, unsavedDocuments[0]); + assertTrue(Arrays.equals("test".getBytes("UTF-8"), file.contentsToByteArray())); } public void testGetUnsavedDocuments_afterSaveAllDocuments() throws Exception { @@ -200,10 +200,6 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture { assertEquals(0, unsavedDocuments.length); } - private static MockVirtualFile newTextFile() { - return new MockVirtualFile("test.txt", "test"); - } - public void testGetUnsavedDocuments_afterSaveDocumentWithProblems() throws Exception { final VirtualFile file = new MockVirtualFile("test.txt", "test") { @Override @@ -223,8 +219,8 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture { final Document[] unsavedDocuments = myDocumentManager.getUnsavedDocuments(); assertEquals(1, unsavedDocuments.length); - assertSame(document, unsavedDocuments[0]); - assertTrue(Arrays.equals("test".getBytes(), file.contentsToByteArray())); + assertSame(document, unsavedDocuments[0]); + assertTrue(Arrays.equals("test".getBytes("UTF-8"), file.contentsToByteArray())); } public void testUnsavedDocument_DoNotGC() throws Exception { @@ -275,12 +271,12 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture { final long stamp = file.getModificationStamp(); Document document = myDocumentManager.getDocument(file); assertNotNull(file.toString(), document); - document.insertString(0, "xxx"); + document.insertString(0, "xxx "); myDocumentManager.saveDocument(document); assertTrue(stamp != file.getModificationStamp()); assertEquals(document.getModificationStamp(), file.getModificationStamp()); - assertTrue(Arrays.equals("xxxtest".getBytes(), file.contentsToByteArray())); + assertTrue(Arrays.equals("xxx test".getBytes("UTF-8"), file.contentsToByteArray())); } public void testSaveAllDocuments_DocumentWasChanged() throws Exception { @@ -288,11 +284,11 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture { final long stamp = file.getModificationStamp(); Document document = myDocumentManager.getDocument(file); assertNotNull(file.toString(), document); - document.insertString(0, "xxx"); + document.insertString(0, "xxx "); myDocumentManager.saveAllDocuments(); assertTrue(stamp != file.getModificationStamp()); - assertTrue(Arrays.equals("xxxtest".getBytes(), file.contentsToByteArray())); + assertTrue(Arrays.equals("xxx test".getBytes("UTF-8"), file.contentsToByteArray())); } public void testGetFile() throws Exception { @@ -313,9 +309,9 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture { final VirtualFile file = new MockVirtualFile("test.txt", "test\rtest"); Document document = myDocumentManager.getDocument(file); assertNotNull(file.toString(), document); - document.insertString(0, "xxx"); + document.insertString(0, "xxx "); myDocumentManager.saveAllDocuments(); - assertTrue(Arrays.equals("xxxtest\rtest".getBytes(), file.contentsToByteArray())); + assertTrue(Arrays.equals("xxx test\rtest".getBytes("UTF-8"), file.contentsToByteArray())); } public void testContentChanged_noDocument() throws Exception { @@ -391,12 +387,12 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture { } } - public void testContentChanged_dontreloadChangedDocument() throws Exception { + public void testContentChanged_DoNotReloadChangedDocument() throws Exception { final MockVirtualFile file = newTextFile(); file.setListener(myDocumentManager); Document document = myDocumentManager.getDocument(file); assertNotNull(file.toString(), document); - document.insertString(0, "zzz"); + document.insertString(0, "old "); myDocumentManager.myReloadFromDisk = Boolean.FALSE; try { @@ -404,7 +400,7 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture { file.setContent(null, "xxx", true); - assertEquals("zzztest", document.getText()); + assertEquals("old test", document.getText()); assertEquals(oldDocumentStamp, document.getModificationStamp()); } finally { @@ -412,7 +408,7 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture { } } - public void testSaveDocument_dontSaveIfModStampEqualsToFile() throws Exception { + public void testSaveDocument_DoNotSaveIfModStampEqualsToFile() throws Exception { final VirtualFile file = new MockVirtualFile("test.txt", "test") { @NotNull @Override @@ -475,16 +471,16 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture { try { Document document = myDocumentManager.getDocument(file); assertNotNull(file.toString(), document); - document.insertString(0, "zzz"); + document.insertString(0, "old "); long documentStamp = document.getModificationStamp(); file.setContent(null, "xxx", false); myDocumentManager.saveAllDocuments(); - assertEquals("zzztest", document.getText()); + assertEquals("old test", document.getText()); assertEquals(file.getModificationStamp(), document.getModificationStamp()); - assertTrue(Arrays.equals("zzztest".getBytes(), file.contentsToByteArray())); + assertTrue(Arrays.equals("old test".getBytes("UTF-8"), file.contentsToByteArray())); assertEquals(documentStamp, document.getModificationStamp()); } finally { @@ -524,10 +520,8 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture { } } - - public void testExternalReplaceWithTheSameText() throws Exception{ + public void testExternalReplaceWithTheSameText() throws Exception { final long[] modificationStamp = new long[1]; - modificationStamp[0] = 1; final VirtualFile file = new MockVirtualFile("test.txt", "test") { @@ -546,20 +540,20 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture { @Override public void refresh(boolean asynchronous, boolean recursive, Runnable postRunnable) { myDocumentManager.contentsChanged(new VirtualFileEvent(null, this, null, 1, 2)); - } }; + DocumentEx document = (DocumentEx)myDocumentManager.getDocument(file); - - modificationStamp[0] = 2; - file.refresh(false, false); - assertNotNull(file.toString(), document); assertEquals(2, document.getModificationStamp()); } + private static MockVirtualFile newTextFile() { + return new MockVirtualFile("test.txt", "test"); + } + private static class MyMockFileDocumentManager extends FileDocumentManagerImpl { private static final FileDocumentManagerListener[] LISTENERS = new FileDocumentManagerListener[0]; diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/SymlinkTestCase.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/SymlinkTestCase.java index 43ea8f829ae8..7666d3116155 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/SymlinkTestCase.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/SymlinkTestCase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,7 +63,8 @@ public abstract class SymlinkTestCase extends LightPlatformLangTestCase { } protected void refresh(boolean recursive) { - final VirtualFile tempDir = myFileSystem.findFileByIoFile(myTempDir); + assertTrue(myTempDir.getPath(), myTempDir.isDirectory() || myTempDir.mkdirs()); + VirtualFile tempDir = myFileSystem.refreshAndFindFileByIoFile(myTempDir); assertNotNull(myTempDir.getPath(), tempDir); tempDir.getChildren(); tempDir.refresh(false, true); diff --git a/platform/util/src/com/intellij/util/io/URLUtil.java b/platform/util/src/com/intellij/util/io/URLUtil.java index dc291bf543d9..a55c15279195 100644 --- a/platform/util/src/com/intellij/util/io/URLUtil.java +++ b/platform/util/src/com/intellij/util/io/URLUtil.java @@ -94,6 +94,7 @@ public class URLUtil { final ZipEntry zipEntry = zipFile.getEntry(resource); if (zipEntry == null) throw new FileNotFoundException("Entry " + resource + " not found in " + file); return new FilterInputStream(zipFile.getInputStream(zipEntry)) { + @Override public void close() throws IOException { super.close(); zipFile.close(); diff --git a/platform/util/src/com/intellij/util/xmlb/AttributeBinding.java b/platform/util/src/com/intellij/util/xmlb/AttributeBinding.java index 1833947df827..49b70e638ac6 100644 --- a/platform/util/src/com/intellij/util/xmlb/AttributeBinding.java +++ b/platform/util/src/com/intellij/util/xmlb/AttributeBinding.java @@ -32,6 +32,7 @@ public class AttributeBinding implements Binding { myAttribute = attribute; } + @Override public Object serialize(Object o, Object context, SerializationFilter filter) { final Object v = myAccessor.read(o); final Object node = myBinding.serialize(v, context, filter); @@ -39,6 +40,7 @@ public class AttributeBinding implements Binding { return new org.jdom.Attribute(myAttribute.value(), ((Content)node).getValue()); } + @Override @Nullable public Object deserialize(Object context, @NotNull Object... nodes) { assert nodes.length == 1; @@ -52,14 +54,17 @@ public class AttributeBinding implements Binding { return context; } + @Override public boolean isBoundTo(Object node) { return node instanceof org.jdom.Attribute && ((org.jdom.Attribute)node).getName().equals(myAttribute.value()); } + @Override public Class getBoundNodeType() { return org.jdom.Attribute.class; } + @Override public void init() { myBinding = XmlSerializerImpl.getBinding(myAccessor); if (!Text.class.isAssignableFrom(myBinding.getBoundNodeType())) { diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java index 7c0d0a03e408..473ca9f7f499 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java @@ -414,6 +414,7 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver rootProjectTasks = ContainerUtilRt.newArrayList(); final DomainObjectSet modules = project.getModules(); for (IdeaModule module : modules) { + String moduleConfigPath = GradleUtil.getConfigPath(module.getGradleProject(), rootProjectPath); for (GradleTask task : module.getGradleProject().getTasks()) { String name = task.getName(); if (name == null || name.trim().isEmpty()) { @@ -425,7 +426,6 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver plainResults = result.runRemainingContributors(parameters, true); + final boolean empty = JavaNoVariantsDelegator.containsOnlyPackages(plainResults) || suggestMetaAnnotations(parameters); if (!empty && parameters.getInvocationCount() == 0) { result.restartCompletionWhenNothingMatches(); @@ -58,11 +59,15 @@ public class GroovyNoVariantsDelegator extends CompletionContributor { if (empty) { delegate(parameters, result); - } else if (Registry.is("ide.completion.show.all.classes")) { + } else if (Registry.is("ide.completion.show.all.classes") || Registry.is("ide.completion.show.better.matching.classes")) { if (parameters.getInvocationCount() <= 1 && JavaCompletionContributor.mayStartClassName(result) && GroovyCompletionContributor.isClassNamePossible(parameters.getPosition()) && !MapArgumentCompletionProvider.isMapKeyCompletion(parameters)) { + if (Registry.is("ide.completion.show.better.matching.classes")) { + result = result.withPrefixMatcher(new BetterPrefixMatcher(result.getPrefixMatcher(), BetterPrefixMatcher.getBestMatchingDegree(plainResults))); + } + suggestNonImportedClasses(parameters, result); } } diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenDependencyCompletionAndResolutionTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenDependencyCompletionAndResolutionTest.java index 9d7365241feb..23307e49e01f 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenDependencyCompletionAndResolutionTest.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenDependencyCompletionAndResolutionTest.java @@ -29,7 +29,6 @@ import org.jetbrains.idea.maven.dom.intentions.ChooseFileIntentionAction; import org.jetbrains.idea.maven.dom.model.MavenDomDependency; import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel; -import java.io.File; import java.util.Arrays; import java.util.List; @@ -668,7 +667,7 @@ public class MavenDependencyCompletionAndResolutionTest extends MavenDomWithIndi " " + ""); - assertCompletionVariants(myProjectPom, "jar", "test-jar", "pom", "ear", "ejb", "ejb-client", "war", "bundle", "jboss-har", "jboss-sar"); + assertCompletionVariants(myProjectPom, "jar", "test-jar", "pom", "ear", "ejb", "ejb-client", "war", "bundle", "jboss-har", "jboss-sar", "maven-plugin"); } public void testDoNotHighlightUnknownType() throws Throwable { diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/context/LoadContextAction.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/context/LoadContextAction.java index b33519abb9f3..7c661f575022 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/context/LoadContextAction.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/context/LoadContextAction.java @@ -58,29 +58,29 @@ public class LoadContextAction extends BaseTaskAction { DefaultActionGroup group = new DefaultActionGroup(); final WorkingContextManager manager = WorkingContextManager.getInstance(project); List history = manager.getContextHistory(); - List infos = ContainerUtil.map2List(history, new Function() { + List infos = new ArrayList(ContainerUtil.map2List(history, new Function() { public ContextHolder fun(final ContextInfo info) { return new ContextHolder() { - @Override - void load(final boolean clear) { - LoadContextUndoableAction undoableAction = LoadContextUndoableAction.createAction(manager, clear, info.name); - UndoableCommand.execute(project, undoableAction, "Load context " + info.comment, "Context"); - } + @Override + void load(final boolean clear) { + LoadContextUndoableAction undoableAction = LoadContextUndoableAction.createAction(manager, clear, info.name); + UndoableCommand.execute(project, undoableAction, "Load context " + info.comment, "Context"); + } - @Override - void remove() { - manager.removeContext(info.name); - } + @Override + void remove() { + manager.removeContext(info.name); + } - @Override - Date getDate() { - return new Date(info.date); - } + @Override + Date getDate() { + return new Date(info.date); + } - @Override - String getComment() { - return info.comment; - } + @Override + String getComment() { + return info.comment; + } @Override Icon getIcon() { @@ -88,7 +88,7 @@ public class LoadContextAction extends BaseTaskAction { } }; } - }); + })); final TaskManager taskManager = TaskManager.getManager(project); List tasks = taskManager.getLocalTasks(); infos.addAll(ContainerUtil.mapNotNull(tasks, new NullableFunction() { @@ -131,7 +131,7 @@ public class LoadContextAction extends BaseTaskAction { return o2.getDate().compareTo(o1.getDate()); } }); - + final Ref shiftPressed = Ref.create(false); boolean today = true; Calendar now = Calendar.getInstance(); @@ -166,7 +166,7 @@ public class LoadContextAction extends BaseTaskAction { }); popup.registerAction("invoke", KeyStroke.getKeyStroke("shift ENTER"), new AbstractAction() { public void actionPerformed(ActionEvent e) { - popup.handleSelect(true); + popup.handleSelect(true); } }); popup.addPopupListener(new JBPopupAdapter() { diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisRepository.java index 8a5b0cffa152..8095e31b1c8a 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisRepository.java @@ -215,12 +215,12 @@ public class MantisRepository extends BaseRepositoryImpl { final MantisConnectPortType soap = createSoap(); myProjects = new ArrayList(); ProjectData[] projectDatas = soap.mc_projects_get_user_accessible(getUsername(), getPassword()); - List projects = ContainerUtil.map(projectDatas, new Function() { + List projects = new ArrayList(ContainerUtil.map(projectDatas, new Function() { @Override public MantisProject fun(final ProjectData data) { return new MantisProject(data.getId().intValue(), data.getName()); } - }); + })); if (allProjectsAvailable(soap)){ projects.add(0, MantisProject.ALL_PROJECTS); } diff --git a/spellchecker/src/com/intellij/spellchecker/jetbrains.dic b/spellchecker/src/com/intellij/spellchecker/jetbrains.dic index d1c3707464da..feef720e0750 100644 --- a/spellchecker/src/com/intellij/spellchecker/jetbrains.dic +++ b/spellchecker/src/com/intellij/spellchecker/jetbrains.dic @@ -3,12 +3,14 @@ aggregator ajax alloc anyschema +aopalliance appender archivelog args arial arity asensitive +aspectj attr attlist auth @@ -50,6 +52,7 @@ capath captcha ccflags cdata +cglib changelist charset checkbox @@ -133,6 +136,7 @@ foreach formatter freelist freelists +freemarker freepools frontend ftlvariable @@ -140,6 +144,7 @@ fulltext func fxml gdata +gemfire geocode geometrycollection getters @@ -247,6 +252,7 @@ minvalue miny mixin mlslabel +mongodb monospaced multi multilinestring @@ -356,6 +362,7 @@ rebase rebased rebasing rect +redis redistributions refactor refactored @@ -401,6 +408,7 @@ serializers servererror servlet servlets +sftp shader significand significands @@ -457,6 +465,7 @@ tokenize tokenizer tooltip tooltips +toplink trebuchet twitter typedef diff --git a/xml/dom-openapi/src/com/intellij/util/xml/ui/ComboControl.java b/xml/dom-openapi/src/com/intellij/util/xml/ui/ComboControl.java index 3984d19fba47..4966c85f1b17 100644 --- a/xml/dom-openapi/src/com/intellij/util/xml/ui/ComboControl.java +++ b/xml/dom-openapi/src/com/intellij/util/xml/ui/ComboControl.java @@ -95,11 +95,12 @@ public class ComboControl extends BaseModifiableControl { }; final ResolvingConverter resolvingConverter = (ResolvingConverter)converter; final Collection variants = resolvingConverter.getVariants(context); - final List> all = ContainerUtil.map(variants, new Function>() { - public Pair fun(final Object s) { - return Pair.create(ElementPresentationManager.getElementName(s), ElementPresentationManager.getIcon(s)); - } - }); + final List> all = + new ArrayList>(ContainerUtil.map(variants, new Function>() { + public Pair fun(final Object s) { + return Pair.create(ElementPresentationManager.getElementName(s), ElementPresentationManager.getIcon(s)); + } + })); all.addAll(ContainerUtil.map(resolvingConverter.getAdditionalVariants(context), new Function() { public Object fun(final Object s) { return new Pair(s, null); diff --git a/xml/impl/src/com/intellij/ide/browsers/impl/WebBrowserServiceImpl.java b/xml/impl/src/com/intellij/ide/browsers/impl/WebBrowserServiceImpl.java index 67dba80e0d6b..11b9db5fb282 100644 --- a/xml/impl/src/com/intellij/ide/browsers/impl/WebBrowserServiceImpl.java +++ b/xml/impl/src/com/intellij/ide/browsers/impl/WebBrowserServiceImpl.java @@ -58,8 +58,7 @@ public class WebBrowserServiceImpl extends WebBrowserService { WebBrowserUrlProvider provider = getProvider(psiElement); if (provider != null) { try { - // I (develar) don't want to change API right now, so, just wrap result - return Urls.newFromIdea(provider.getUrl(psiElement, psiFile, virtualFile)); + return provider.getUrl(psiElement, psiFile, virtualFile); } catch (WebBrowserUrlProvider.BrowserException e) { if (!HtmlUtil.isHtmlFile(psiFile)) { @@ -71,29 +70,30 @@ public class WebBrowserServiceImpl extends WebBrowserService { return Urls.newFromVirtualFile(virtualFile); } + @Override @Nullable public Url getUrlToOpen(@NotNull PsiElement psiElement) { try { return getUrlToOpen(psiElement, false); } - catch (WebBrowserUrlProvider.BrowserException e) { + catch (WebBrowserUrlProvider.BrowserException ignored) { return null; } } @Nullable public static WebBrowserUrlProvider getProvider(@Nullable PsiElement element) { - if (element == null) { + PsiFile psiFile = element == null ? null : element.getContainingFile(); + if (psiFile == null) { return null; } - final List allProviders = Arrays.asList(WebBrowserUrlProvider.EP_NAME.getExtensions()); + List allProviders = Arrays.asList(WebBrowserUrlProvider.EP_NAME.getExtensions()); for (WebBrowserUrlProvider urlProvider : DumbService.getInstance(element.getProject()).filterByDumbAwareness(allProviders)) { - if (urlProvider.canHandleElement(element)) { + if (urlProvider.canHandleElement(element, psiFile)) { return urlProvider; } } - return null; } } diff --git a/xml/impl/src/com/intellij/xml/util/HtmlUtil.java b/xml/impl/src/com/intellij/xml/util/HtmlUtil.java index 0d6685b1009a..552f12794ec8 100644 --- a/xml/impl/src/com/intellij/xml/util/HtmlUtil.java +++ b/xml/impl/src/com/intellij/xml/util/HtmlUtil.java @@ -249,10 +249,12 @@ public class HtmlUtil { if (customName.length() == 0) continue; descriptors[index++] = new XmlAttributeDescriptorImpl() { + @Override public String getName(PsiElement context) { return customName; } + @Override public String getName() { return customName; } @@ -275,14 +277,17 @@ public class HtmlUtil { if (tagName.length() == 0) continue; descriptors[index++] = new XmlElementDescriptorImpl(context instanceof XmlTag ? (XmlTag)context : null) { + @Override public String getName(PsiElement context) { return tagName; } + @Override public String getDefaultName() { return tagName; } + @Override public boolean allowElementsFromNamespace(final String namespace, final XmlTag context) { return true; } @@ -340,10 +345,12 @@ public class HtmlUtil { descriptors = ArrayUtil.append( descriptors, new XmlAttributeDescriptorImpl() { + @Override public String getName(PsiElement context) { return JSFC; } + @Override public String getName() { return JSFC; } @@ -454,6 +461,7 @@ public class HtmlUtil { public static void processInjectedContent(final XmlTag element, @NotNull final Processor tagProcessor) { final PsiLanguageInjectionHost.InjectedPsiVisitor injectedPsiVisitor = new PsiLanguageInjectionHost.InjectedPsiVisitor() { + @Override public void visit(@NotNull PsiFile injectedPsi, @NotNull List places) { if (injectedPsi instanceof XmlFile) { final XmlDocument injectedDocument = ((XmlFile)injectedPsi).getDocument(); @@ -508,12 +516,14 @@ public class HtmlUtil { @NonNls final Set inTag = new THashSet(); boolean metHttpEquiv = false; + @Override public void doctype(@Nullable final CharSequence publicId, @Nullable final CharSequence systemId, final int startOffset, final int endOffset) { } + @Override public ProcessingOrder startTag(final CharSequence localName, final String namespace, final int startoffset, final int endoffset, final int headerEndOffset) { @NonNls String name = localName.toString().toLowerCase(); @@ -526,6 +536,7 @@ public class HtmlUtil { throw TerminateException.INSTANCE; } + @Override public void endTag(final CharSequence localName, final String namespace, final int startoffset, final int endoffset) { @NonNls final String name = localName.toString().toLowerCase(); if ("meta".equals(name) && metHttpEquiv && contentAttributeValue != null) { @@ -548,6 +559,7 @@ public class HtmlUtil { private String contentAttributeValue; + @Override public void attribute(final CharSequence localName, final CharSequence v, final int startoffset, final int endoffset) { @NonNls final String name = localName.toString().toLowerCase(); if (inTag.contains("meta")) { @@ -561,20 +573,23 @@ public class HtmlUtil { } } + @Override public void textElement(final CharSequence display, final CharSequence physical, final int startoffset, final int endoffset) { } + @Override public void entityRef(final CharSequence ref, final int startOffset, final int endOffset) { } + @Override public void error(String message, int startOffset, int endOffset) { } }); } - catch (TerminateException e) { + catch (TerminateException ignored) { //ignore } - catch (Exception e) { + catch (Exception ignored) { // some weird things can happen, like unbalanaced tree } diff --git a/xml/impl/src/com/intellij/xml/util/UserColorLookup.java b/xml/impl/src/com/intellij/xml/util/UserColorLookup.java index cb6337eb4f59..dbc248031c21 100644 --- a/xml/impl/src/com/intellij/xml/util/UserColorLookup.java +++ b/xml/impl/src/com/intellij/xml/util/UserColorLookup.java @@ -22,7 +22,6 @@ import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.codeInsight.lookup.LookupElementDecorator; import com.intellij.codeInsight.lookup.LookupValueWithPriority; -import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.wm.WindowManager; import com.intellij.psi.PsiElement; @@ -30,7 +29,10 @@ import com.intellij.psi.xml.XmlToken; import com.intellij.ui.ColorChooser; import com.intellij.ui.ColorPickerListener; import com.intellij.ui.ColorPickerListenerFactory; +import com.intellij.ui.ColorUtil; +import com.intellij.util.Function; import com.intellij.xml.XmlBundle; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.awt.*; @@ -40,18 +42,28 @@ import java.awt.*; */ public class UserColorLookup extends LookupElementDecorator { private static final String COLOR_STRING = XmlBundle.message("choose.color.in.color.lookup"); + private static final Function COLOR_TO_STRING_CONVERTER = new Function() { + @Override + public String fun(Color color) { + return '#' + ColorUtil.toHex(color); + } + }; public UserColorLookup() { + this(COLOR_TO_STRING_CONVERTER); + } + + public UserColorLookup(final Function colorToStringConverter) { super(PrioritizedLookupElement.withPriority(LookupElementBuilder.create(COLOR_STRING).withInsertHandler( new InsertHandler() { @Override public void handleInsert(InsertionContext context, LookupElement item) { - handleUserSelection(context); + handleUserSelection(context, colorToStringConverter); } }), LookupValueWithPriority.HIGH)); } - private static void handleUserSelection(InsertionContext context) { + private static void handleUserSelection(InsertionContext context, @NotNull Function colorToStringConverter) { Color myColorAtCaret = null; Editor selectedTextEditor = context.getEditor(); @@ -68,16 +80,8 @@ public class UserColorLookup extends LookupElementDecorator { XmlBundle.message("choose.color.dialog.title"), myColorAtCaret, true, listeners, true); if (color != null) { - String s = Integer.toHexString(color.getRGB() & 0xFFFFFF); - if (s.length() != 6) { - StringBuilder buf = new StringBuilder(s); - for (int i = 6 - buf.length(); i > 0; --i) { - buf.insert(0, '0'); - } - s = buf.toString(); - } - s = "#" + s; - context.getDocument().insertString(context.getStartOffset(), s); + String colorString = colorToStringConverter.fun(color); + context.getDocument().insertString(context.getStartOffset(), colorString); context.getEditor().getCaretModel().moveToOffset(context.getTailOffset()); } } diff --git a/xml/openapi/src/com/intellij/ide/browsers/WebBrowserUrlProvider.java b/xml/openapi/src/com/intellij/ide/browsers/WebBrowserUrlProvider.java index e5795d1d6db5..80db55d83382 100644 --- a/xml/openapi/src/com/intellij/ide/browsers/WebBrowserUrlProvider.java +++ b/xml/openapi/src/com/intellij/ide/browsers/WebBrowserUrlProvider.java @@ -33,17 +33,13 @@ public abstract class WebBrowserUrlProvider { super(message); } } - - @NotNull - /** - * URL must not be encoded (space as is) - */ - public abstract String getUrl(@NotNull PsiElement element, @NotNull PsiFile psiFile, @NotNull VirtualFile virtualFile) throws BrowserException; - /** * Invariant: element has not null containing psi file with not null virtual file */ - public abstract boolean canHandleElement(@NotNull final PsiElement element); + public abstract boolean canHandleElement(@NotNull PsiElement element, @NotNull PsiFile psiFile); + + @NotNull + public abstract Url getUrl(@NotNull PsiElement element, @NotNull PsiFile psiFile, @NotNull VirtualFile virtualFile) throws BrowserException; @Nullable public String getOpenInBrowserActionText(@NotNull PsiFile file) {