From b7303ca245adbc95781d34786e659374a48347df Mon Sep 17 00:00:00 2001 From: "Kirill.Safonov" Date: Tue, 4 Jan 2011 13:22:07 +0300 Subject: [PATCH 01/53] mnemonic --- .../src/com/intellij/platform/NewDirectoryProjectDialog.form | 2 +- .../src/com/intellij/platform/NewDirectoryProjectDialog.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/platform/NewDirectoryProjectDialog.form b/platform/platform-impl/src/com/intellij/platform/NewDirectoryProjectDialog.form index 9aeb85636ba0..2c47a21e834b 100644 --- a/platform/platform-impl/src/com/intellij/platform/NewDirectoryProjectDialog.form +++ b/platform/platform-impl/src/com/intellij/platform/NewDirectoryProjectDialog.form @@ -17,7 +17,7 @@ - + diff --git a/platform/platform-impl/src/com/intellij/platform/NewDirectoryProjectDialog.java b/platform/platform-impl/src/com/intellij/platform/NewDirectoryProjectDialog.java index 0a46b047b627..47369f156cfd 100644 --- a/platform/platform-impl/src/com/intellij/platform/NewDirectoryProjectDialog.java +++ b/platform/platform-impl/src/com/intellij/platform/NewDirectoryProjectDialog.java @@ -49,6 +49,7 @@ public class NewDirectoryProjectDialog extends DialogWrapper { private JPanel myRootPane; private JComboBox myProjectTypeComboBox; private JPanel myProjectTypePanel; + private JLabel myLocationLabel; private String myBaseDir; private boolean myModifyingLocation = false; private boolean myModifyingProjectName = false; @@ -60,6 +61,8 @@ public class NewDirectoryProjectDialog extends DialogWrapper { setTitle("Create New Project"); init(); + myLocationLabel.setLabelFor(myLocationField.getChildComponent()); + myBaseDir = getBaseDir(); File projectName = FileUtil.findSequentNonexistentFile(new File(myBaseDir), "untitled", ""); myLocationField.setText(projectName.toString()); From 0bf7c5d4baac7c9160aaf22a3911e865890c85d3 Mon Sep 17 00:00:00 2001 From: "Rustam.Vishnyakov" Date: Mon, 24 Jan 2011 14:59:26 +0300 Subject: [PATCH 02/53] Fixing WI-4830 Adding A large JS library makes code completion slow (even if not in usage scope) --- .../roots/libraries/scripting/ScriptingLibraryTable.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibraryTable.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibraryTable.java index 77c20de37c41..2cbaa05d6d6e 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibraryTable.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibraryTable.java @@ -149,8 +149,8 @@ public class ScriptingLibraryTable { public static class LibraryModel { private String myName; - private ArrayList mySourceFiles = new ArrayList(); - private ArrayList myCompactFiles = new ArrayList(); + private Set mySourceFiles = new HashSet(); + private Set myCompactFiles = new HashSet(); private ArrayList myDocUrls = new ArrayList(); public LibraryModel(String name, VirtualFile[] sourceFiles, VirtualFile[] compactFiles, String[] docUrls) { @@ -186,7 +186,7 @@ public class ScriptingLibraryTable { public VirtualFile[] getSourceFiles() { return mySourceFiles.toArray(new VirtualFile[mySourceFiles.size()]); } - + public VirtualFile[] getCompactFiles() { return myCompactFiles.toArray(new VirtualFile[myCompactFiles.size()]); } From 42ca4fdbb04346a27825ebef4775cab7dd8f8104 Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 24 Jan 2011 11:14:32 +0100 Subject: [PATCH 03/53] make method return: position caret after fix on physical element (IDEA-64321) --- .../daemon/impl/quickfix/ConvertReturnStatementsVisitor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ConvertReturnStatementsVisitor.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ConvertReturnStatementsVisitor.java index 3d888e854ad4..8003afcc7ace 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ConvertReturnStatementsVisitor.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ConvertReturnStatementsVisitor.java @@ -71,7 +71,7 @@ public class ConvertReturnStatementsVisitor implements ReturnStatementsVisitor { final String value = generateValue(returnStatement); latestReplaced = (PsiReturnStatement) myFactory.createStatementFromText("return " + value+";", returnStatement.getParent()); - returnStatement.replace(latestReplaced); + latestReplaced = (PsiReturnStatement)returnStatement.replace(latestReplaced); } return latestReplaced; From d4cab5dc89069aca6149545c43b1606a4da05b7b Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 24 Jan 2011 12:16:03 +0100 Subject: [PATCH 04/53] inspections: revert optimizations for modified profile (IDEA-64529) --- .../codeInspection/ui/SingleInspectionProfilePanel.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java index a0b1f5aff4c1..2fa225f058cb 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java @@ -929,9 +929,8 @@ public class SingleInspectionProfilePanel extends JPanel { if (myShareProfile != (mySelectedProfile.getProfileManager() == myProjectProfileManager)) return true; if (!Comparing.strEqual(myInitialProfile, mySelectedProfile.getName())) return true; if (descriptorsAreChanged()) { - return setSelectedProfileModified(true); + return true; } - setSelectedProfileModified(false); return false; } From 58447c4832dd148a4145a82b904bf41a7230369f Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 24 Jan 2011 12:45:21 +0100 Subject: [PATCH 05/53] add explicit type arguments: qualify method expression if needed (IDEA-64458) --- .../daemon/impl/quickfix/AddTypeArgumentsFix.java | 15 ++++++++++++++- .../addTypeArguments/afterUnqualified.java | 7 +++++++ .../addTypeArguments/afterUnqualifiedStatic.java | 7 +++++++ .../addTypeArguments/beforeUnqualified.java | 7 +++++++ .../addTypeArguments/beforeUnqualifiedStatic.java | 7 +++++++ 5 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/afterUnqualified.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/afterUnqualifiedStatic.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/beforeUnqualified.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/beforeUnqualifiedStatic.java diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeArgumentsFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeArgumentsFix.java index 87fbe3ccf8f6..f0940a84f3ed 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeArgumentsFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeArgumentsFix.java @@ -20,6 +20,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; @@ -72,11 +73,23 @@ public class AddTypeArgumentsFix extends MethodArgumentFix { final PsiElementFactory factory = JavaPsiFacade.getInstance(expression.getProject()).getElementFactory(); PsiMethodCallExpression copy = (PsiMethodCallExpression)expression.copy(); - final PsiReferenceParameterList parameterList = copy.getMethodExpression().getParameterList(); + final PsiReferenceExpression methodExpression = copy.getMethodExpression(); + final PsiReferenceParameterList parameterList = methodExpression.getParameterList(); LOG.assertTrue(parameterList != null); for (PsiType mapping : mappings) { parameterList.add(factory.createTypeElement(mapping)); } + if (methodExpression.getQualifierExpression() == null) { + final PsiExpression qualifierExpression; + final PsiClass containingClass = method.getContainingClass(); + LOG.assertTrue(containingClass != null); + if (method.hasModifierProperty(PsiModifier.STATIC)) { + qualifierExpression = factory.createReferenceExpression(containingClass); + } else { + qualifierExpression = RefactoringUtil.createThisExpression(method.getManager(), null); + } + methodExpression.setQualifierExpression(qualifierExpression); + } return copy; } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/afterUnqualified.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/afterUnqualified.java new file mode 100644 index 000000000000..2e7cbdc95880 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/afterUnqualified.java @@ -0,0 +1,7 @@ +// "Add explicit type arguments" "true" +import java.util.*; +class Test { + List f() { return new ArrayList(); } + void g(List a) {} + void someMethod() { g(this.f()); } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/afterUnqualifiedStatic.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/afterUnqualifiedStatic.java new file mode 100644 index 000000000000..6ca0a0b28769 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/afterUnqualifiedStatic.java @@ -0,0 +1,7 @@ +// "Add explicit type arguments" "true" +import java.util.*; +class Test { + static List f() { return new ArrayList(); } + void g(List a) {} + void someMethod() { g(Test.f()); } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/beforeUnqualified.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/beforeUnqualified.java new file mode 100644 index 000000000000..8ed862474c9f --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/beforeUnqualified.java @@ -0,0 +1,7 @@ +// "Add explicit type arguments" "true" +import java.util.*; +class Test { + List f() { return new ArrayList(); } + void g(List a) {} + void someMethod() { g(f()); } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/beforeUnqualifiedStatic.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/beforeUnqualifiedStatic.java new file mode 100644 index 000000000000..66bc051cd302 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/beforeUnqualifiedStatic.java @@ -0,0 +1,7 @@ +// "Add explicit type arguments" "true" +import java.util.*; +class Test { + static List f() { return new ArrayList(); } + void g(List a) {} + void someMethod() { g(f()); } +} \ No newline at end of file From df06aa36130d4199204b501a5bbe02deb9201b78 Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 24 Jan 2011 13:14:55 +0100 Subject: [PATCH 06/53] update copyright after all dialogs with e.g. override/implement methods are shown --- .../src/com/maddyhome/idea/copyright/CopyrightManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/CopyrightManager.java b/plugins/copyright/src/com/maddyhome/idea/copyright/CopyrightManager.java index 7e8ecfbec398..ed4e2d42f114 100644 --- a/plugins/copyright/src/com/maddyhome/idea/copyright/CopyrightManager.java +++ b/plugins/copyright/src/com/maddyhome/idea/copyright/CopyrightManager.java @@ -17,6 +17,7 @@ package com.maddyhome.idea.copyright; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.components.*; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileEditor.FileEditorManager; @@ -102,7 +103,7 @@ public class CopyrightManager extends AbstractProjectComponent implements JDOMEx new UpdateCopyrightProcessor(myProject, module, file).run(); } } - }); + }, ModalityState.NON_MODAL); } } } From 76a78632a4fda7ed0ec55e3de77c216d07650135 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Mon, 24 Jan 2011 14:52:47 +0300 Subject: [PATCH 07/53] IDEA-64523 remove auth info from console 1. Before logging all command arguments go through the new simple method maskAuthInfoFromUrl() which hides username and password from URLs. 2. Log not only to console, but to idea.log as well. 3. Change color of system messages. --- .../hg4idea/command/HgCommandService.java | 40 +++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgCommandService.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgCommandService.java index fcf87cbcf151..e5ad4ec72fa2 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgCommandService.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgCommandService.java @@ -22,7 +22,11 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.vcsUtil.VcsUtil; import org.apache.commons.lang.StringUtils; import org.jetbrains.annotations.Nullable; -import org.zmlx.hg4idea.*; +import org.zmlx.hg4idea.HgExecutableValidator; +import org.zmlx.hg4idea.HgGlobalSettings; +import org.zmlx.hg4idea.HgUtil; +import org.zmlx.hg4idea.HgVcs; +import org.zmlx.hg4idea.HgVcsMessages; import javax.swing.*; import java.awt.*; @@ -31,7 +35,9 @@ import java.io.DataOutputStream; import java.io.File; import java.io.IOException; import java.net.Socket; +import java.net.URI; import java.nio.charset.Charset; +import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; @@ -155,15 +161,43 @@ public final class HgCommandService { // logging to the Version Control console (without extensions and configs) final String cmdString = String.format("%s %s %s", mySettings.isRunViaBash() ? "bash -c " + HgVcs.HG_EXECUTABLE_FILE_NAME : HgVcs.HG_EXECUTABLE_FILE_NAME, operation, - StringUtils.join(arguments, " ")); - myVcs.showMessageInConsole(cmdString, ConsoleViewContentType.USER_INPUT.getAttributes()); + StringUtils.join(maskAuthInfoFromUrl(arguments), " ")); + myVcs.showMessageInConsole(cmdString, ConsoleViewContentType.NORMAL_OUTPUT.getAttributes()); + LOG.info(cmdString); if (!silent) { myVcs.showMessageInConsole(result.getRawOutput(), ConsoleViewContentType.SYSTEM_OUTPUT.getAttributes()); + LOG.info(result.getRawOutput()); } myVcs.showMessageInConsole(result.getRawError(), ConsoleViewContentType.ERROR_OUTPUT.getAttributes()); + LOG.info(result.getRawError()); return result; + } + /** + * Strips possible authentication information from arguments passed to the command line + * to prevent private information appear in the VCS console or logs. + * @param arguments command line arguments. + * @return command line arguments which don't contain authentication information. + */ + private static List maskAuthInfoFromUrl(List arguments) { + if (arguments == null || arguments.isEmpty()) { + return arguments; + } + final List newArgs = new ArrayList(arguments.size()); + for (String arg : arguments) { + if (!arg.contains("@")) { // simple filter + newArgs.add(arg); + } else { + try { + final URI uri = new URI(arg); // parsing via URI methods, exception means it's not an URI + newArgs.add(uri.toString().replace(uri.getUserInfo(), ":")); + } catch (Throwable e) { + newArgs.add(arg); + } + } + } + return newArgs; } private void showError(Exception e) { From de9d78518a9d45cf955b7057a8977cc5798dd511 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Mon, 24 Jan 2011 15:24:02 +0300 Subject: [PATCH 08/53] IDEA-64429 Focus password field in SSH passphrase dialog --- .../ide/passwordSafe/ui/PasswordSafePromptDialog.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/ui/PasswordSafePromptDialog.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/ui/PasswordSafePromptDialog.java index ccc4bcee5b4d..d83651858622 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/ui/PasswordSafePromptDialog.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/ui/PasswordSafePromptDialog.java @@ -98,6 +98,11 @@ public class PasswordSafePromptDialog extends DialogWrapper { return myRoot; } + @Override + public JComponent getPreferredFocusedComponent() { + return myPasswordPasswordField; + } + /** * Ask password possibly asking password database first. The method could be invoked from any thread. If UI needs to be shown, * the method invokes {@link com.intellij.util.ui.UIUtil#invokeAndWaitIfNeeded(Runnable)} From 8e3a18a3b34d51bff94289f04aecf534e3e2e6e1 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Mon, 24 Jan 2011 15:33:26 +0300 Subject: [PATCH 09/53] IDEA-62908 Cursor up/down movement jumpy for non-monospaced fonts Corrected processing in case when the shift exceeds document boundaries --- .../src/com/intellij/openapi/editor/impl/CaretModelImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java index bae51f8cb205..4a04ca467d18 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java @@ -213,7 +213,7 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener, int newLineNumber = visualCaret.line + lineShift; int newColumnNumber = visualCaret.column + columnShift; if (desiredX >= 0) { - newColumnNumber = myEditor.xyToVisualPosition(new Point(desiredX, newLineNumber * myEditor.getLineHeight())).column; + newColumnNumber = myEditor.xyToVisualPosition(new Point(desiredX, Math.max(0, newLineNumber) * myEditor.getLineHeight())).column; } Document document = myEditor.getDocument(); From f8e27336436d6d0a9594581128373b2d120f4c81 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 24 Jan 2011 13:52:55 +0100 Subject: [PATCH 10/53] WI-4133 CSS Code Completion produces wrong property --- .../lookup/impl/actions/ChooseItemReplaceAction.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/actions/ChooseItemReplaceAction.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/actions/ChooseItemReplaceAction.java index 25c2163aeeb8..d1d4690cce1a 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/actions/ChooseItemReplaceAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/actions/ChooseItemReplaceAction.java @@ -19,7 +19,6 @@ package com.intellij.codeInsight.lookup.impl.actions; import com.intellij.codeInsight.completion.CodeCompletionFeatures; import com.intellij.codeInsight.completion.CompletionProcess; import com.intellij.codeInsight.completion.CompletionService; -import com.intellij.codeInsight.completion.CompletionUtil; import com.intellij.codeInsight.lookup.Lookup; import com.intellij.codeInsight.lookup.LookupManager; import com.intellij.codeInsight.lookup.impl.LookupImpl; @@ -31,6 +30,7 @@ import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.actionSystem.EditorAction; import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; +import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; @@ -74,9 +74,10 @@ public class ChooseItemReplaceAction extends EditorAction { final Editor editor = lookup.getEditor(); PsiDocumentManager.getInstance(file.getProject()).commitDocument(editor.getDocument()); - final int offset = editor.getCaretModel().getOffset(); - final String prefix = CompletionUtil.findJavaIdentifierPrefix(file, offset); - final TemplateImpl template = LiveTemplateCompletionContributor.findApplicableTemplate(file, offset, prefix); + final int end = editor.getCaretModel().getOffset(); + final int start = lookup.getLookupStart(); + final String prefix = editor.getDocument().getText(TextRange.create(start, end)); + final TemplateImpl template = LiveTemplateCompletionContributor.findApplicableTemplate(file, end, prefix); return template != null && shortcutChar == TemplateSettings.getInstance().getShortcutChar(template); } From 1d80476b4602e3595c4d6f19fc7ef8fb66f7a989 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Mon, 24 Jan 2011 16:10:12 +0300 Subject: [PATCH 11/53] IDEA-25139: Proper caret placement for methods, if "next line" brace style is in use. --- .../editorActions/smartEnter/PlainEnterProcessor.java | 4 ++++ .../codeInsight/completeStatement/IDEA25139.java | 5 +++++ .../codeInsight/completeStatement/IDEA25139_after.java | 8 ++++++++ .../intellij/codeInsight/CompleteStatementTest.java | 10 +++++++++- 4 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/codeInsight/completeStatement/IDEA25139.java create mode 100644 java/java-tests/testData/codeInsight/completeStatement/IDEA25139_after.java diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java index 20ef10f7f27b..b8d06069838e 100644 --- a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java +++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java @@ -71,6 +71,10 @@ public class PlainEnterProcessor implements EnterProcessor { else if (element instanceof PsiDoWhileStatement) { body = ((PsiDoWhileStatement)element).getBody(); } + else if (element instanceof PsiMethod) { + PsiCodeBlock methodBody = ((PsiMethod)element).getBody(); + if (methodBody != null) return methodBody; + } return body instanceof PsiBlockStatement ? ((PsiBlockStatement)body).getCodeBlock() : null; } diff --git a/java/java-tests/testData/codeInsight/completeStatement/IDEA25139.java b/java/java-tests/testData/codeInsight/completeStatement/IDEA25139.java new file mode 100644 index 000000000000..3f1197b91684 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completeStatement/IDEA25139.java @@ -0,0 +1,5 @@ + +class Foo { + @Test + public void testValueOf() +} diff --git a/java/java-tests/testData/codeInsight/completeStatement/IDEA25139_after.java b/java/java-tests/testData/codeInsight/completeStatement/IDEA25139_after.java new file mode 100644 index 000000000000..54aedb8277b7 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completeStatement/IDEA25139_after.java @@ -0,0 +1,8 @@ + +class Foo { + @Test + public void testValueOf() + { + + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java index 52134e7078d2..d63d98fe8239 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java @@ -184,7 +184,15 @@ public class CompleteStatementTest extends EditorActionTestCase { public void testIDEADEV40479() throws Exception { doTest(); } - public void testIDEADEV13019() throws Exception { + public void testIDEADEV13019() throws Exception { + doTestBracesNextLineStyle(); + } + + public void testIDEA25139() throws Exception { + doTestBracesNextLineStyle(); + } + + private void doTestBracesNextLineStyle() throws Exception { CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject()); settings.BRACE_STYLE = CodeStyleSettings.NEXT_LINE; settings.METHOD_BRACE_STYLE = CodeStyleSettings.NEXT_LINE; From 4fd5d4406e90cbf4518fdf8b135837a223e05151 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Mon, 24 Jan 2011 16:18:16 +0300 Subject: [PATCH 12/53] Refactoring: remove duplicate code that checks if the feature is supported --- ...bstractUnappliableEditorCustomization.java | 34 -------- .../ui/AbstractEditorCustomization.java | 77 +++++++++++++++++++ ...tionalPageAtBottomEditorCustomization.java | 19 ++--- ...orizontalScrollBarEditorCustomization.java | 20 ++--- .../ui/OneLineEditorCustomization.java | 18 ++--- .../ui/SoftWrapsEditorCustomization.java | 15 ++-- .../ui/SpellCheckingEditorCustomization.java | 46 +++++------ 7 files changed, 117 insertions(+), 112 deletions(-) delete mode 100644 platform/platform-impl/src/com/intellij/AbstractUnappliableEditorCustomization.java create mode 100644 platform/platform-impl/src/com/intellij/ui/AbstractEditorCustomization.java diff --git a/platform/platform-impl/src/com/intellij/AbstractUnappliableEditorCustomization.java b/platform/platform-impl/src/com/intellij/AbstractUnappliableEditorCustomization.java deleted file mode 100644 index 65348be2e58f..000000000000 --- a/platform/platform-impl/src/com/intellij/AbstractUnappliableEditorCustomization.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2000-2011 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; - -import com.intellij.openapi.editor.ex.EditorEx; -import com.intellij.ui.EditorCustomization; -import org.jetbrains.annotations.NotNull; - -/** - * Basic super class for {@link EditorCustomization editor customizations} that don't consider un-applying feature. - * - * @author Denis Zhdanov - * @since 1/14/11 12:52 PM - */ -public abstract class AbstractUnappliableEditorCustomization implements EditorCustomization { - - @Override - public void removeCustomization(@NotNull EditorEx editor, @NotNull Feature feature) { - // Do nothing - } -} diff --git a/platform/platform-impl/src/com/intellij/ui/AbstractEditorCustomization.java b/platform/platform-impl/src/com/intellij/ui/AbstractEditorCustomization.java new file mode 100644 index 000000000000..1a477e8e7406 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ui/AbstractEditorCustomization.java @@ -0,0 +1,77 @@ +/* + * Copyright 2000-2011 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.ui; + +import com.intellij.openapi.editor.ex.EditorEx; +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; +import java.util.EnumSet; +import java.util.Set; + +/** + * Base super class for {@link EditorCustomization editor customizations} that provide the following: + *
+ * 
    + *
  • + * Don't process {@link #addCustomization(EditorEx, Feature)} and {@link #removeCustomization(EditorEx, Feature)} if given feature + * is not supported by the current customization (supported features are defined at constructor); + *
  • + *
+ *
+ * + * @author Denis Zhdanov + * @since 1/24/11 3:56 PM + */ +public abstract class AbstractEditorCustomization implements EditorCustomization { + + private final Set myFeatures = EnumSet.noneOf(Feature.class); + + protected AbstractEditorCustomization(@NotNull Feature... features) { + myFeatures.addAll(Arrays.asList(features)); + } + + @Override + public Set getSupportedFeatures() { + return myFeatures; + } + + @Override + public void addCustomization(@NotNull EditorEx editor, @NotNull Feature feature) { + if (!myFeatures.contains(feature)) { + return; + } + doProcessCustomization(editor, feature, true); + } + + @Override + public void removeCustomization(@NotNull EditorEx editor, @NotNull Feature feature) { + if (!myFeatures.contains(feature)) { + return; + } + doProcessCustomization(editor, feature, false); + } + + /** + * Template method for sub-classes to process target feature applying/removal and being sure that given feature + * is supported by the current customization. + * + * @param editor target editor to apply the given feature + * @param feature target feature to apply to the given editor + * @param apply flag the identifies if given feature should be applied/removed from the given editor + */ + protected abstract void doProcessCustomization(@NotNull EditorEx editor, @NotNull Feature feature, boolean apply); +} diff --git a/platform/platform-impl/src/com/intellij/ui/AdditionalPageAtBottomEditorCustomization.java b/platform/platform-impl/src/com/intellij/ui/AdditionalPageAtBottomEditorCustomization.java index 2aedf8499e1a..c4c8abce75ac 100644 --- a/platform/platform-impl/src/com/intellij/ui/AdditionalPageAtBottomEditorCustomization.java +++ b/platform/platform-impl/src/com/intellij/ui/AdditionalPageAtBottomEditorCustomization.java @@ -18,29 +18,20 @@ package com.intellij.ui; import com.intellij.openapi.editor.ex.EditorEx; import org.jetbrains.annotations.NotNull; -import java.util.EnumSet; -import java.util.Set; - /** * {@link EditorCustomization} for {@link EditorCustomization.Feature#ADDITIONAL_PAGE_AT_BOTTOM}. * * @author Denis Zhdanov * @since 1/21/11 4:06 PM */ -public class AdditionalPageAtBottomEditorCustomization implements EditorCustomization { +public class AdditionalPageAtBottomEditorCustomization extends AbstractEditorCustomization { - @Override - public Set getSupportedFeatures() { - return EnumSet.of(Feature.ADDITIONAL_PAGE_AT_BOTTOM); + public AdditionalPageAtBottomEditorCustomization() { + super(Feature.ADDITIONAL_PAGE_AT_BOTTOM); } @Override - public void addCustomization(@NotNull EditorEx editor, @NotNull Feature feature) { - editor.getSettings().setAdditionalPageAtBottom(true); - } - - @Override - public void removeCustomization(@NotNull EditorEx editor, @NotNull Feature feature) { - editor.getSettings().setAdditionalPageAtBottom(false); + protected void doProcessCustomization(@NotNull EditorEx editor, @NotNull Feature feature, boolean apply) { + editor.getSettings().setAdditionalPageAtBottom(apply); } } diff --git a/platform/platform-impl/src/com/intellij/ui/HorizontalScrollBarEditorCustomization.java b/platform/platform-impl/src/com/intellij/ui/HorizontalScrollBarEditorCustomization.java index 14ed975ec6bd..e9654ccc96c1 100644 --- a/platform/platform-impl/src/com/intellij/ui/HorizontalScrollBarEditorCustomization.java +++ b/platform/platform-impl/src/com/intellij/ui/HorizontalScrollBarEditorCustomization.java @@ -18,29 +18,19 @@ package com.intellij.ui; import com.intellij.openapi.editor.ex.EditorEx; import org.jetbrains.annotations.NotNull; -import java.util.EnumSet; -import java.util.Set; - /** * @author irengrig * Date: 12/6/10 * Time: 10:18 AM */ -public class HorizontalScrollBarEditorCustomization implements EditorCustomization { - public Set getSupportedFeatures() { - return EnumSet.of(Feature.HORIZONTAL_SCROLLBAR); - } +public class HorizontalScrollBarEditorCustomization extends AbstractEditorCustomization { - public void addCustomization(@NotNull EditorEx editor, @NotNull Feature feature) { - if (Feature.HORIZONTAL_SCROLLBAR.equals(feature)) { - editor.setHorizontalScrollbarVisible(true); - } + public HorizontalScrollBarEditorCustomization() { + super(Feature.HORIZONTAL_SCROLLBAR); } @Override - public void removeCustomization(@NotNull EditorEx editor, @NotNull Feature feature) { - if (Feature.HORIZONTAL_SCROLLBAR.equals(feature)) { - editor.setHorizontalScrollbarVisible(false); - } + protected void doProcessCustomization(@NotNull EditorEx editor, @NotNull Feature feature, boolean apply) { + editor.setHorizontalScrollbarVisible(apply); } } diff --git a/platform/platform-impl/src/com/intellij/ui/OneLineEditorCustomization.java b/platform/platform-impl/src/com/intellij/ui/OneLineEditorCustomization.java index df719184a920..4d35f07a5993 100644 --- a/platform/platform-impl/src/com/intellij/ui/OneLineEditorCustomization.java +++ b/platform/platform-impl/src/com/intellij/ui/OneLineEditorCustomization.java @@ -15,24 +15,20 @@ */ package com.intellij.ui; -import com.intellij.AbstractUnappliableEditorCustomization; import com.intellij.openapi.editor.ex.EditorEx; import org.jetbrains.annotations.NotNull; -import java.util.EnumSet; -import java.util.Set; - /** * @author Kirill Likhodedov */ -public class OneLineEditorCustomization extends AbstractUnappliableEditorCustomization { - public Set getSupportedFeatures() { - return EnumSet.of(Feature.ONE_LINE); +public class OneLineEditorCustomization extends AbstractEditorCustomization { + + public OneLineEditorCustomization() { + super(Feature.ONE_LINE); } - public void addCustomization(@NotNull EditorEx editor, @NotNull Feature feature) { - if (Feature.ONE_LINE.equals(feature)) { - editor.setOneLineMode(true); - } + @Override + protected void doProcessCustomization(@NotNull EditorEx editor, @NotNull Feature feature, boolean apply) { + editor.setOneLineMode(apply); } } diff --git a/platform/platform-impl/src/com/intellij/ui/SoftWrapsEditorCustomization.java b/platform/platform-impl/src/com/intellij/ui/SoftWrapsEditorCustomization.java index 83d69140e5ad..0c36b4d4dc5c 100644 --- a/platform/platform-impl/src/com/intellij/ui/SoftWrapsEditorCustomization.java +++ b/platform/platform-impl/src/com/intellij/ui/SoftWrapsEditorCustomization.java @@ -15,13 +15,9 @@ */ package com.intellij.ui; -import com.intellij.AbstractUnappliableEditorCustomization; import com.intellij.openapi.editor.ex.EditorEx; import org.jetbrains.annotations.NotNull; -import java.util.EnumSet; -import java.util.Set; - /** * Editor customization that can make target editor soft wraps-aware. *

@@ -30,15 +26,14 @@ import java.util.Set; * @author Denis Zhdanov * @since Aug 20, 2010 4:54:48 PM */ -public class SoftWrapsEditorCustomization extends AbstractUnappliableEditorCustomization { +public class SoftWrapsEditorCustomization extends AbstractEditorCustomization { - @Override - public Set getSupportedFeatures() { - return EnumSet.of(Feature.SOFT_WRAP); + public SoftWrapsEditorCustomization() { + super(Feature.SOFT_WRAP); } @Override - public void addCustomization(@NotNull EditorEx editor, @NotNull Feature feature) { - editor.getSettings().setUseSoftWraps(true); + protected void doProcessCustomization(@NotNull EditorEx editor, @NotNull Feature feature, boolean apply) { + editor.getSettings().setUseSoftWraps(apply); } } diff --git a/plugins/spellchecker/src/com/intellij/spellchecker/ui/SpellCheckingEditorCustomization.java b/plugins/spellchecker/src/com/intellij/spellchecker/ui/SpellCheckingEditorCustomization.java index 8d009ed94c43..bcc2e3efd2d5 100644 --- a/plugins/spellchecker/src/com/intellij/spellchecker/ui/SpellCheckingEditorCustomization.java +++ b/plugins/spellchecker/src/com/intellij/spellchecker/ui/SpellCheckingEditorCustomization.java @@ -31,12 +31,14 @@ import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.spellchecker.inspections.SpellCheckerInspectionToolProvider; -import com.intellij.ui.EditorCustomization; +import com.intellij.ui.AbstractEditorCustomization; import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; /** * Makes current editor to have spell checking turned on all the time. @@ -46,7 +48,7 @@ import java.util.*; * @author Denis Zhdanov * @since Aug 20, 2010 3:54:42 PM */ -public class SpellCheckingEditorCustomization implements EditorCustomization { +public class SpellCheckingEditorCustomization extends AbstractEditorCustomization { /** * Holds custom inspection profile wrapper. @@ -60,6 +62,10 @@ public class SpellCheckingEditorCustomization implements EditorCustomization { @Nullable private static final InspectionProfileWrapper INSPECTION_PROFILE_WRAPPER = initProvider(); + public SpellCheckingEditorCustomization() { + super(Feature.SPELL_CHECK); + } + @SuppressWarnings("unchecked") @Nullable private static InspectionProfileWrapper initProvider() { @@ -116,12 +122,7 @@ public class SpellCheckingEditorCustomization implements EditorCustomization { } @Override - public Set getSupportedFeatures() { - return EnumSet.of(Feature.SPELL_CHECK); - } - - @Override - public void addCustomization(@NotNull EditorEx editor, @NotNull Feature feature) { + protected void doProcessCustomization(@NotNull EditorEx editor, @NotNull Feature feature, boolean apply) { if (INSPECTION_PROFILE_WRAPPER == null) { return; } @@ -135,27 +136,16 @@ public class SpellCheckingEditorCustomization implements EditorCustomization { if (file == null) { return; } - file.putUserData(InspectionProfileWrapper.KEY, INSPECTION_PROFILE_WRAPPER); - editor.putUserData(IntentionManager.SHOW_INTENTION_OPTIONS_KEY, false); - updateRepresentation(project, file); - } - - @Override - public void removeCustomization(@NotNull EditorEx editor, @NotNull Feature feature) { - Project project = editor.getProject(); - if (project == null) { - return; + + if (apply) { + file.putUserData(InspectionProfileWrapper.KEY, INSPECTION_PROFILE_WRAPPER); + editor.putUserData(IntentionManager.SHOW_INTENTION_OPTIONS_KEY, false); + } + else { + file.putUserData(InspectionProfileWrapper.KEY, null); } - PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); - if (file == null) { - return; - } - file.putUserData(InspectionProfileWrapper.KEY, null); - updateRepresentation(project, file); - } - - private static void updateRepresentation(@NotNull Project project, @NotNull PsiFile file) { + // Update representation. DaemonCodeAnalyzer analyzer = DaemonCodeAnalyzer.getInstance(project); if (analyzer != null) { analyzer.restart(file); From 940cd1da14f382a33d7076dcd923edf73cd8906c Mon Sep 17 00:00:00 2001 From: "sergey.vasiliev" Date: Mon, 24 Jan 2011 15:55:37 +0300 Subject: [PATCH 13/53] EA-25082,25129,25083 --- .../intellij/facet/frameworks/LibrariesDownloadAssistant.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-api/src/com/intellij/facet/frameworks/LibrariesDownloadAssistant.java b/platform/lang-api/src/com/intellij/facet/frameworks/LibrariesDownloadAssistant.java index 5d48f92fae26..31d194d21ea9 100644 --- a/platform/lang-api/src/com/intellij/facet/frameworks/LibrariesDownloadAssistant.java +++ b/platform/lang-api/src/com/intellij/facet/frameworks/LibrariesDownloadAssistant.java @@ -56,7 +56,7 @@ public class LibrariesDownloadAssistant { LOG.error(e); } catch (IOException e) { - LOG.error(e); + // no route to host, unknown host, etc. } } From 0c114af23f0ff661ec8c719ba98b5530ea10aee3 Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Mon, 24 Jan 2011 16:28:12 +0300 Subject: [PATCH 14/53] change label --- .../src/org/jetbrains/android/facet/AndroidFacetEditorTab.form | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.form b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.form index 0dbb99230e14..b5e43601d7fe 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.form +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.form @@ -34,7 +34,7 @@ - + From c0b8dc93cf1a164bc669c611b54c6a9d09769b6f Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Mon, 24 Jan 2011 16:42:46 +0300 Subject: [PATCH 15/53] IDEA-64156 prefer context in isolated module scope --- .../FileReferenceQuickFixProvider.java | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/quickFix/FileReferenceQuickFixProvider.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/quickFix/FileReferenceQuickFixProvider.java index 47a98cf0bc8d..110d0fd69025 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/quickFix/FileReferenceQuickFixProvider.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/quickFix/FileReferenceQuickFixProvider.java @@ -24,6 +24,8 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.fileTypes.UnknownFileType; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDirectory; @@ -33,6 +35,8 @@ import com.intellij.psi.PsiNamedElement; import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference; import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet; import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Arrays; import java.util.Collection; @@ -70,12 +74,20 @@ public class FileReferenceQuickFixProvider { return Collections.emptyList(); } + PsiElement element = reference.getElement(); + Module module = element != null ? ModuleUtil.findModuleForPsiElement(element) : null; + for (PsiFileSystemItem defaultContext : defaultContexts) { if (defaultContext != null) { final VirtualFile virtualFile = defaultContext.getVirtualFile(); if (virtualFile != null && defaultContext.isDirectory() && virtualFile.isInLocalFileSystem()) { - context = defaultContext; - break; + if (context == null) { + context = defaultContext; + } + else if (module != null && module == getModuleForContext(defaultContext)) { + context = defaultContext; + break; + } } } } @@ -134,4 +146,10 @@ public class FileReferenceQuickFixProvider { return Arrays.asList(action); } + + @Nullable + private static Module getModuleForContext(@NotNull PsiFileSystemItem context) { + VirtualFile file = context.getVirtualFile(); + return file != null ? ModuleUtil.findModuleForFile(file, context.getProject()) : null; + } } From 0bccae5f4e803f546c358853db987f58f2b9ccd3 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Mon, 24 Jan 2011 16:54:15 +0300 Subject: [PATCH 16/53] IDEA-62908 Cursor up/down movement jumpy for non-monospaced fonts Reset previously used 'x' coordinate during 'move to visual position' processing --- .../src/com/intellij/openapi/editor/impl/CaretModelImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java index 4a04ca467d18..9d4e8afd9e36 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java @@ -111,6 +111,7 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener, public void moveToVisualPosition(@NotNull VisualPosition pos) { assertIsDispatchThread(); validateCallContext(); + myDesiredX = -1; int column = pos.column; int line = pos.line; From ccc5552a06841d9b4b136a3f3a501c2dc881de52 Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Mon, 24 Jan 2011 16:56:24 +0300 Subject: [PATCH 17/53] todo --- .../daemon/quickFix/FileReferenceQuickFixProvider.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/quickFix/FileReferenceQuickFixProvider.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/quickFix/FileReferenceQuickFixProvider.java index 110d0fd69025..a19edcdf6196 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/quickFix/FileReferenceQuickFixProvider.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/quickFix/FileReferenceQuickFixProvider.java @@ -85,6 +85,8 @@ public class FileReferenceQuickFixProvider { context = defaultContext; } else if (module != null && module == getModuleForContext(defaultContext)) { + // fixes IDEA-64156 + // todo: fix it on PsiFileReferenceHelper level in 10.X context = defaultContext; break; } From f50277383799987d07f22af0aacb0b672f52ee36 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Mon, 24 Jan 2011 17:08:21 +0300 Subject: [PATCH 18/53] NPE fix --- .../com/intellij/ide/projectView/BaseProjectTreeBuilder.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/BaseProjectTreeBuilder.java b/platform/lang-impl/src/com/intellij/ide/projectView/BaseProjectTreeBuilder.java index c08e2e80381c..02edb5816ecf 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/BaseProjectTreeBuilder.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/BaseProjectTreeBuilder.java @@ -109,7 +109,9 @@ public abstract class BaseProjectTreeBuilder extends AbstractTreeBuilder { } protected final void expandNodeChildren(final DefaultMutableTreeNode node) { - Object element = ((NodeDescriptor)node.getUserObject()).getElement(); + final NodeDescriptor userObject = (NodeDescriptor)node.getUserObject(); + if (userObject == null) return; + Object element = userObject.getElement(); VirtualFile virtualFile = getFileToRefresh(element); super.expandNodeChildren(node); if (virtualFile != null) { From e4c21c905a90c48d19ea053efff9e6d41e84fc88 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Mon, 24 Jan 2011 17:11:13 +0300 Subject: [PATCH 19/53] hg: remove mercurial.logo due to license restrictions (GPLv2+) --- plugins/hg4idea/resources/images/mercurial.png | Bin 857 -> 0 bytes plugins/hg4idea/src/META-INF/plugin.xml | 4 ++-- .../org/zmlx/hg4idea/HgProjectConfigurable.java | 2 +- plugins/hg4idea/src/org/zmlx/hg4idea/HgVcs.java | 2 -- .../provider/update/HgUpdateEnvironment.java | 9 ++++++--- .../zmlx/hg4idea/ui/HgCurrentBranchStatus.java | 4 +--- 6 files changed, 10 insertions(+), 11 deletions(-) delete mode 100644 plugins/hg4idea/resources/images/mercurial.png diff --git a/plugins/hg4idea/resources/images/mercurial.png b/plugins/hg4idea/resources/images/mercurial.png deleted file mode 100644 index 7745acfee3575b1bd58f5c1b28e5d8664937e2ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 857 zcmV-f1E&0mP)-aha1d0%)QN>x={ozv4(vnYx$bGe+SR4TPn6s2$+Cs?i4 zS&PN;fnk_G)m`c;pja&Shr{88d_K=z)o7ZA#bQZ0oz5p5#|hT}<#PE>I2=xU1T==J&>xh#mH=srF^zR?T-8jZ#{H#hf5RaG#Th27m`t9_yteA}~EiECDNZ{n;1cZ=l z0F%jtR4T>OKA*2S5C}Na>2z#jV&Y9xQ&Z9F^L}A#S>e2Lt~>mF*v7IfxeOtMps}$L zi;Ih(6h%Qcn>Cuv=6#Juqg=fdi^d%5Ki0poEUT9!2>@WVTCuviild_=kx&!`p63ey zYGbk3OfVQsZ)|MLmCI!#0Q5L|q8%L_3$iR%BZR?V!1D4k1_uY%|HT-MM&EC4ZjN8X z*}Ai{bJy?p4_{QMrVeOZ=WZnqmQmkYUE4#8j$qobn>CX?wqbJ20-?Ck8AVVD|+!vU>U3zlU?LWm@a z;v~=Wgr;f4<8e$)O<`nYB=7NfCMk+S6@d18?XTto^B*&r46Ul_ncwe!K~WS6g+gyA z6vE!#9&|b#JRVQM>-D-D8X5`!{#SWucxc9KHvdfgO4#jo`$k(^TLu8?>+9cb=eBJF z4+j{N(G(bdJp9^VFzi-+e*tGrI?Z9I)FS`@03v!+SaefwW^{L9a%BJjc-kv3FW1Y= j%Pvk%EJ)SMFG>dhHrNJO5L3!r00000NkvXXu0mjfpYVt} diff --git a/plugins/hg4idea/src/META-INF/plugin.xml b/plugins/hg4idea/src/META-INF/plugin.xml index a73077bb494c..ec09509d7c6c 100644 --- a/plugins/hg4idea/src/META-INF/plugin.xml +++ b/plugins/hg4idea/src/META-INF/plugin.xml @@ -4,7 +4,7 @@ Provides integration with Mercurial version control system. Supports Mercurial 1.3+. VCS Integration 10.0 - Victor Iacoban and Willem Verstraeten + Victor Iacoban and Willem Verstraeten com.intellij.modules.vcs @@ -28,7 +28,7 @@ - + diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgProjectConfigurable.java b/plugins/hg4idea/src/org/zmlx/hg4idea/HgProjectConfigurable.java index 51c2b3eae3fe..3417a4906c7c 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/HgProjectConfigurable.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/HgProjectConfigurable.java @@ -34,7 +34,7 @@ public class HgProjectConfigurable implements SearchableConfigurable { } public Icon getIcon() { - return HgVcs.MERCURIAL_ICON; + return null; } public String getHelpTopic() { diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgVcs.java b/plugins/hg4idea/src/org/zmlx/hg4idea/HgVcs.java index 0e264a40c11f..82d8ef8272c2 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/HgVcs.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/HgVcs.java @@ -78,8 +78,6 @@ public class HgVcs extends AbstractVcs { public static final Topic OUTGOING_TOPIC = new Topic("hg4idea.outgoing", HgUpdater.class); - public static final Icon MERCURIAL_ICON = IconLoader.getIcon("/images/mercurial.png"); - private static final Icon INCOMING_ICON = IconLoader.getIcon("/actions/moveDown.png"); private static final Icon OUTGOING_ICON = IconLoader.getIcon("/actions/moveUp.png"); diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgUpdateEnvironment.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgUpdateEnvironment.java index 016675c58c99..061335e36aa8 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgUpdateEnvironment.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgUpdateEnvironment.java @@ -17,12 +17,15 @@ import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.Ref; import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.VcsException; -import com.intellij.openapi.vcs.update.*; +import com.intellij.openapi.vcs.update.SequentialUpdatesContext; +import com.intellij.openapi.vcs.update.UpdateEnvironment; +import com.intellij.openapi.vcs.update.UpdateSession; +import com.intellij.openapi.vcs.update.UpdateSessionAdapter; +import com.intellij.openapi.vcs.update.UpdatedFiles; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; @@ -102,7 +105,7 @@ public class HgUpdateEnvironment implements UpdateEnvironment { } public Icon getIcon() { - return IconLoader.getIcon("/images/mercurial.png"); + return null; } public String getHelpTopic() { diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgCurrentBranchStatus.java b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgCurrentBranchStatus.java index e787d7604ada..4a05db7c3cee 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgCurrentBranchStatus.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgCurrentBranchStatus.java @@ -12,7 +12,6 @@ // limitations under the License. package org.zmlx.hg4idea.ui; -import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.wm.CustomStatusBarWidget; import com.intellij.openapi.wm.StatusBar; import org.apache.commons.lang.StringUtils; @@ -25,10 +24,9 @@ import javax.swing.*; import java.util.List; public class HgCurrentBranchStatus extends JLabel implements CustomStatusBarWidget { - private static final Icon MERCURIAL_ICON = IconLoader.getIcon("/images/mercurial.png"); public HgCurrentBranchStatus() { - super(MERCURIAL_ICON, SwingConstants.TRAILING); + super("", SwingConstants.TRAILING); setVisible(false); } From 0d3a5a0ccb4f4b750fca7fcdea3db7174ce2f4e0 Mon Sep 17 00:00:00 2001 From: nik Date: Mon, 24 Jan 2011 18:33:49 +0300 Subject: [PATCH 20/53] run 'before launch' tasks on redeploy (IDEA-56052, IDEA-57036) --- .../src/com/intellij/execution/impl/ExecutionManagerImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java index 58f7d6fd1d92..e99fca8fb896 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java @@ -96,7 +96,7 @@ public class ExecutionManagerImpl extends ExecutionManager implements ProjectCom return handlers.toArray(new ProcessHandler[handlers.size()]); } - public void compileAndRun(final Runnable startRunnable, final RunProfile configuration, final RunProfileState state, @Nullable final Runnable onCancelRunnable) { + public void compileAndRun(final Runnable startRunnable, final RunProfile configuration, final @Nullable RunProfileState state, @Nullable final Runnable onCancelRunnable) { if (configuration instanceof RunConfiguration) { final RunConfiguration runConfiguration = (RunConfiguration)configuration; final RunManagerImpl runManager = RunManagerImpl.getInstanceImpl(myProject); @@ -112,7 +112,7 @@ public class ExecutionManagerImpl extends ExecutionManager implements ProjectCom if (!activeProviders.isEmpty()) { ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { public void run() { - ConfigurationPerRunnerSettings configurationSettings = state.getConfigurationSettings(); + ConfigurationPerRunnerSettings configurationSettings = state != null ? state.getConfigurationSettings() : null; DataContext projectContext = SimpleDataContext.getProjectContext(myProject); final DataContext dataContext = configurationSettings != null ? SimpleDataContext From 8062105eae872c0dbef652912091d57d4901a777 Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Mon, 24 Jan 2011 18:49:11 +0300 Subject: [PATCH 21/53] fix filetextfield path completion: do not hide current directory if lastChar != File.separatorChar + break currentSelection cycle if match found --- .../intellij/openapi/fileChooser/ex/FileTextFieldImpl.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileTextFieldImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileTextFieldImpl.java index ddda44542ffa..c1e7aa6858b0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileTextFieldImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileTextFieldImpl.java @@ -51,6 +51,7 @@ import javax.swing.text.Document; import javax.swing.text.JTextComponent; import java.awt.*; import java.awt.event.*; +import java.io.File; import java.util.*; import java.util.List; @@ -535,6 +536,7 @@ public abstract class FileTextFieldImpl implements FileLookup, Disposable, FileT if (currentDiff == diff) { toPreselect = each; toPreselectFixed = true; + break; } } @@ -597,7 +599,10 @@ public abstract class FileTextFieldImpl implements FileLookup, Disposable, FileT if (typed == null) return null; LookupFile lastFound = myFinder.find(typed); if (lastFound == null) return null; - if (lastFound.exists()) return lastFound; + if (lastFound.exists()) { + if (typed.charAt(typed.length() - 1) != File.separatorChar) return lastFound.getParent(); + return lastFound; + } final String[] splits = myFinder.normalize(typed).split(myFileSpitRegExp); StringBuffer fullPath = new StringBuffer(); From 54f4797c17b90bb30284c3254d1781d3f4ad8f95 Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Mon, 24 Jan 2011 18:51:00 +0300 Subject: [PATCH 22/53] FormBuilder vertical mode --- .../src/com/intellij/util/ui/FormBuilder.java | 66 ++++++++++++++----- 1 file changed, 50 insertions(+), 16 deletions(-) diff --git a/platform/util/src/com/intellij/util/ui/FormBuilder.java b/platform/util/src/com/intellij/util/ui/FormBuilder.java index f23113f5c9c1..f529f72bc7d6 100644 --- a/platform/util/src/com/intellij/util/ui/FormBuilder.java +++ b/platform/util/src/com/intellij/util/ui/FormBuilder.java @@ -26,9 +26,18 @@ public class FormBuilder { private int line = 0; private final JPanel panel; + private boolean vertical; + + /** + * @param vertical labels will be placed on their own rows + */ + public FormBuilder(final boolean vertical) { + this.vertical = vertical; + panel = new JPanel(new GridBagLayout()); + } public FormBuilder() { - panel = new JPanel(new GridBagLayout()); + this(false); } public FormBuilder addLabeledComponent(String labelText, JComponent component) { @@ -38,24 +47,49 @@ public class FormBuilder { GridBagConstraints c = new GridBagConstraints(); int verticalInset = line > 0 ? 10 : 0; - - c.gridx = 0; - c.gridy = line; - c.weightx = 0; - c.anchor = GridBagConstraints.EAST; - c.insets = new Insets(verticalInset, 0, 0, 5); - panel.add(label, c); + if (vertical) { + c.gridwidth = 1; - c.gridx = 1; - c.gridy = line; - c.fill = GridBagConstraints.HORIZONTAL; - c.anchor = GridBagConstraints.WEST; - c.weightx = 1; - c.insets = new Insets(verticalInset, 0, 0, 0); - panel.add(component, c); + c.gridx = 0; + c.gridy = line; + c.weightx = 1.0; + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.WEST; + c.insets = new Insets(verticalInset, 0, 0, 5); - line++; + panel.add(label, c); + + c.gridx = 0; + c.gridy = line + 1; + c.weightx = 1.0; + c.fill = GridBagConstraints.HORIZONTAL; + c.anchor = GridBagConstraints.WEST; + c.insets = new Insets(0, 0, 0, 5); + + panel.add(component, c); + + line += 2; + } + else { + c.gridx = 0; + c.gridy = line; + c.weightx = 0; + c.anchor = GridBagConstraints.EAST; + c.insets = new Insets(verticalInset, 0, 0, 5); + + panel.add(label, c); + + c.gridx = 1; + c.gridy = line; + c.fill = GridBagConstraints.HORIZONTAL; + c.anchor = GridBagConstraints.WEST; + c.weightx = 1; + c.insets = new Insets(verticalInset, 0, 0, 0); + panel.add(component, c); + + line++; + } return this; } From b43349018c58de90a75eea93a69ce153796a3b96 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 24 Jan 2011 14:19:40 +0100 Subject: [PATCH 23/53] keep a reference to an element with larger chance of survival (EA-25091) --- .../intellij/psi/filters/getters/ClassLiteralGetter.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/filters/getters/ClassLiteralGetter.java b/java/java-impl/src/com/intellij/psi/filters/getters/ClassLiteralGetter.java index 1ad4c520cbc6..747f64254254 100644 --- a/java/java-impl/src/com/intellij/psi/filters/getters/ClassLiteralGetter.java +++ b/java/java-impl/src/com/intellij/psi/filters/getters/ClassLiteralGetter.java @@ -58,14 +58,15 @@ public class ClassLiteralGetter extends CompletionProvider shortNameCondition, final PsiType classParameter, CompletionResultSet result) { @@ -79,7 +80,7 @@ public class ClassLiteralGetter extends CompletionProvider Date: Mon, 24 Jan 2011 16:26:45 +0100 Subject: [PATCH 24/53] yes, it's nullable --- .../src/com/intellij/codeInsight/lookup/LookupManager.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupManager.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupManager.java index 3aec15a4091e..3c085a317604 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupManager.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupManager.java @@ -55,6 +55,8 @@ public abstract class LookupManager { public abstract Lookup showLookup(Editor editor, @NotNull LookupElement[] items, String prefix, @NotNull LookupArranger arranger); public abstract void hideActiveLookup(); + + @Nullable public abstract Lookup getActiveLookup(); @NonNls public static final String PROP_ACTIVE_LOOKUP = "activeLookup"; From 709b01d63ab1d38c15d48b3bb53d7250e754b8ae Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 24 Jan 2011 16:42:31 +0100 Subject: [PATCH 25/53] when file is read-only, still send some event when lookup closes --- .../src/com/intellij/codeInsight/lookup/impl/LookupImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index bff687ebe99b..26baa6ad318d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -543,6 +543,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { final PsiFile file = getPsiFile(); if (file != null && !WriteCommandAction.ensureFilesWritable(myProject, Arrays.asList(file))) { + fireItemSelected(null, completionChar); return; } From 887f0f9e5df030f8bc4b1a6532be1362b944b493 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Mon, 24 Jan 2011 19:11:11 +0300 Subject: [PATCH 26/53] IDEA-64559: default shortcut for "NewElementSamePlace" on Mac --- platform/platform-resources/src/idea/Keymap_Mac.xml | 5 ++++- platform/platform-resources/src/idea/Keymap_MacClassic.xml | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/platform/platform-resources/src/idea/Keymap_Mac.xml b/platform/platform-resources/src/idea/Keymap_Mac.xml index e1d671d70a26..d50286d232b3 100644 --- a/platform/platform-resources/src/idea/Keymap_Mac.xml +++ b/platform/platform-resources/src/idea/Keymap_Mac.xml @@ -182,7 +182,10 @@ - + + + + diff --git a/platform/platform-resources/src/idea/Keymap_MacClassic.xml b/platform/platform-resources/src/idea/Keymap_MacClassic.xml index 23e39811608d..47a55edc08ed 100644 --- a/platform/platform-resources/src/idea/Keymap_MacClassic.xml +++ b/platform/platform-resources/src/idea/Keymap_MacClassic.xml @@ -209,6 +209,9 @@ + + + From 05906b4a00080473c35d468a0f167091853f2b08 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Mon, 24 Jan 2011 19:32:02 +0300 Subject: [PATCH 27/53] IDEA-64523 remove auth info from hgrc after clone Currently hg4idea doesn't work with mercurial prompt - instead for tasks requiring authentication it asks it from user and then injects into the URL, which is in turn supplied to an hg command (push, pull, clone, etc.). Because of that after cloning authentication data was recorded to .hg/hgrc to paths.default, which unsecure. Now after clone .hg/hgrc is scanned for paths.default, and user info data is removed from there. It is a hotfix. Right fix is to use hg prompt to supply password, will be implemented later. --- .../hg4idea/provider/HgCheckoutProvider.java | 105 +++++++++++++++--- 1 file changed, 91 insertions(+), 14 deletions(-) diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgCheckoutProvider.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgCheckoutProvider.java index 876b55e3646a..b551f382045a 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgCheckoutProvider.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgCheckoutProvider.java @@ -19,10 +19,12 @@ import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vcs.CheckoutProvider; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; @@ -34,13 +36,21 @@ import org.zmlx.hg4idea.command.HgCloneCommand; import org.zmlx.hg4idea.command.HgCommandResult; import org.zmlx.hg4idea.ui.HgCloneDialog; +import java.io.BufferedReader; import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.net.URI; /** * Checkout provider for Mercurial */ public class HgCheckoutProvider implements CheckoutProvider { + private static final Logger LOG = Logger.getInstance(HgCheckoutProvider.class.getName()); + public void doCheckout(@NotNull final Project project, @Nullable final Listener listener) { ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { @@ -62,30 +72,97 @@ public class HgCheckoutProvider implements CheckoutProvider { final String sourceRepositoryURL = dialog.getSourceRepositoryURL(); new Task.Backgroundable(project, HgVcsMessages.message("hg4idea.clone.progress", sourceRepositoryURL), true) { @Override public void run(@NotNull ProgressIndicator indicator) { + // clone HgCloneCommand clone = new HgCloneCommand(project); clone.setRepositoryURL(sourceRepositoryURL); clone.setDirectory(targetDir); - final HgCommandResult myCloneResult = clone.execute(); - if (myCloneResult == null) { - notifyError("Clone failed", "Clone failed due to unknown error", project); - } else if (myCloneResult.getExitValue() != 0) { - notifyError("Clone failed", "Clone from " + sourceRepositoryURL + " failed.

" + myCloneResult.getRawError(), project); - } else { - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - if (listener != null) { - listener.directoryCheckedOut(new File(dialog.getParentDirectory(), dialog.getDirectoryName())); - listener.checkoutCompleted(); + + // handle result + try { + final HgCommandResult myCloneResult = clone.execute(); + if (myCloneResult == null) { + notifyError("Clone failed", "Clone failed due to unknown error", project); + } else if (myCloneResult.getExitValue() != 0) { + notifyError("Clone failed", "Clone from " + sourceRepositoryURL + " failed.

" + myCloneResult.getRawError(), project); + } else { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + if (listener != null) { + listener.directoryCheckedOut(new File(dialog.getParentDirectory(), dialog.getDirectoryName())); + listener.checkoutCompleted(); + } } - } - }); + }); + } + } finally { + cleanupAuthDataFromHgrc(targetDir); } } }.queue(); } + /** + * Removes authentication data from the parent URL of a just cloned repository. + * @param targetDir directory where the hg project was cloned into. + */ + private static void cleanupAuthDataFromHgrc(String targetDir) { + File hgrc = new File(new File(targetDir, ".hg"), "hgrc"); + if (!hgrc.exists()) { + return; + } + + for (int i = 0; i < 3; i++) { // 3 attempts in case of an IOException + BufferedReader reader = null; + PrintWriter writer = null; + try { + // writing correct info into a temporary file + final File tempFile = FileUtil.createTempFile("hgrc", "temp"); + tempFile.deleteOnExit(); + reader = new BufferedReader(new FileReader(hgrc)); + writer = new PrintWriter(new FileWriter(tempFile)); + String line; + while ((line = reader.readLine()) != null) { + String parseLine = line.trim(); + if (parseLine.startsWith("default") && parseLine.contains("@")) { // looking for paths.default + int eqIdx = parseLine.indexOf('='); + parseLine = parseLine.substring(eqIdx+1).trim(); // getting value of paths.default + try { + final URI uri = new URI(parseLine); + final String urlWithoutAuthData = uri.toString().replace(uri.getUserInfo() + "@", ""); + writer.println("default = " + urlWithoutAuthData); + } catch (Throwable t) { // not URI => no sensitive data + writer.println(line); + } + } else { + writer.println(line); + } + } + + // substituting files + if (!tempFile.renameTo(hgrc)) { // this may fail in case of different FSs + FileUtil.copy(tempFile, hgrc); + tempFile.delete(); + } + return; + } catch (IOException e) { + LOG.info(e); + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException e) { + continue; + } + } + if (writer != null) { + writer.close(); + } + } + } + } + private static void notifyError(String title, String description, Project project) { Notifications.Bus.notify(new Notification(HgVcs.NOTIFICATION_GROUP_ID, title, description, NotificationType.ERROR), project); } From 2b329d4442016c042b22be75a5892bb62fb2e585 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Mon, 24 Jan 2011 19:50:08 +0300 Subject: [PATCH 28/53] Fix memory leak via this$0 by cached value provider --- .../intellij/xml/util/AnchorReference.java | 55 +++++++++++-------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/xml/impl/src/com/intellij/xml/util/AnchorReference.java b/xml/impl/src/com/intellij/xml/util/AnchorReference.java index 0b7d24be0a11..a68fd43bfb45 100644 --- a/xml/impl/src/com/intellij/xml/util/AnchorReference.java +++ b/xml/impl/src/com/intellij/xml/util/AnchorReference.java @@ -122,29 +122,7 @@ class AnchorReference implements PsiReference, EmptyResolveMessageProvider { if (file != null) { CachedValue> value = file.getUserData(ourCachedIdsKey); if (value == null) { - value = CachedValuesManager.getManager(file.getProject()).createCachedValue(new CachedValueProvider>() { - public Result> compute() { - final Map resultMap = new HashMap(); - XmlDocument document = HtmlUtil.getRealXmlDocument(file.getDocument()); - final XmlTag rootTag = document != null ? document.getRootTag():null; - - if (rootTag != null) { - processXmlElements(rootTag, - new PsiElementProcessor() { - public boolean execute(final PsiElement element) { - final String anchorValue = element instanceof XmlTag ? getAnchorValue((XmlTag)element):null; - - if (anchorValue!=null) { - resultMap.put(anchorValue, (XmlTag)element); - } - return true; - } - } - ); - } - return new Result>(resultMap, file); - } - }, false); + value = CachedValuesManager.getManager(file.getProject()).createCachedValue(new MapCachedValueProvider(file), false); file.putUserData(ourCachedIdsKey, value); } @@ -239,4 +217,35 @@ class AnchorReference implements PsiReference, EmptyResolveMessageProvider { XmlBundle.message("cannot.resolve.anchor", myAnchor) : XmlBundle.message("cannot.resolve.anchor.in.file", myAnchor, xmlFile.getName()); } + + // separate static class to avoid memory leak via this$0 + private static class MapCachedValueProvider implements CachedValueProvider> { + private final XmlFile myFile; + + public MapCachedValueProvider(XmlFile file) { + myFile = file; + } + + public Result> compute() { + final Map resultMap = new HashMap(); + XmlDocument document = HtmlUtil.getRealXmlDocument(myFile.getDocument()); + final XmlTag rootTag = document != null ? document.getRootTag():null; + + if (rootTag != null) { + processXmlElements(rootTag, + new PsiElementProcessor() { + public boolean execute(final PsiElement element) { + final String anchorValue = element instanceof XmlTag ? getAnchorValue((XmlTag)element):null; + + if (anchorValue!=null) { + resultMap.put(anchorValue, (XmlTag)element); + } + return true; + } + } + ); + } + return new Result>(resultMap, myFile); + } + } } From 2aa6b5b1a10e88f999fac0aa11509cca724b1fff Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 24 Jan 2011 17:52:20 +0100 Subject: [PATCH 29/53] branch number = 103 --- build.txt | 2 +- build/scripts/dist.gant | 2 +- .../src/com/intellij/ide/plugins/PluginManager.java | 4 ++-- platform/util/src/com/intellij/openapi/util/BuildNumber.java | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.txt b/build.txt index 9a5431c4a6a7..3d1817be47e6 100644 --- a/build.txt +++ b/build.txt @@ -1 +1 @@ -102.SNAPSHOT +103.SNAPSHOT diff --git a/build/scripts/dist.gant b/build/scripts/dist.gant index 9b022fba90cc..f1d70fe59670 100644 --- a/build/scripts/dist.gant +++ b/build/scripts/dist.gant @@ -64,7 +64,7 @@ def wire_build_date(String buildNumber) { target('default': 'The default target') { depends(compile) layoutAll( - buildNumber: "IC-102.SNAPSHOT", + buildNumber: "IC-103.SNAPSHOT", version: "IdeaX", system_selector: "IntelliJIdeaCE10", jdk_req: "1.6*", diff --git a/platform/platform-api/src/com/intellij/ide/plugins/PluginManager.java b/platform/platform-api/src/com/intellij/ide/plugins/PluginManager.java index 1505d7073b69..53566f945e19 100644 --- a/platform/platform-api/src/com/intellij/ide/plugins/PluginManager.java +++ b/platform/platform-api/src/com/intellij/ide/plugins/PluginManager.java @@ -760,11 +760,11 @@ public class PluginManager { ourBuildNumber = BuildNumber.fromString(new String(FileUtil.loadFileText(buildTxtFile)).trim()); } else { - ourBuildNumber = BuildNumber.fromString("102.SNAPSHOT"); + ourBuildNumber = BuildNumber.fromString("103.SNAPSHOT"); } } catch (IOException e) { - ourBuildNumber = BuildNumber.fromString("102.SNAPSHOT"); + ourBuildNumber = BuildNumber.fromString("103.SNAPSHOT"); } } } diff --git a/platform/util/src/com/intellij/openapi/util/BuildNumber.java b/platform/util/src/com/intellij/openapi/util/BuildNumber.java index 28d6c65167eb..0f68d89eea9b 100644 --- a/platform/util/src/com/intellij/openapi/util/BuildNumber.java +++ b/platform/util/src/com/intellij/openapi/util/BuildNumber.java @@ -26,7 +26,7 @@ public class BuildNumber implements Comparable { private final int myBaselineVersion; private final int myBuildNumber; private static final String BUILD_NUMBER = "__BUILD_NUMBER__"; - private static final int TOP_BASELINE_VERSION = 102; + private static final int TOP_BASELINE_VERSION = 103; public BuildNumber(String productCode, int baselineVersion, int buildNumber) { myProductCode = productCode; From 8442c955a4573ad322dc5f9d14aacccd2e525c20 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Mon, 24 Jan 2011 20:00:53 +0300 Subject: [PATCH 30/53] IDEA-64560 Grails: IDEA should support groovy expressions without '{' '}' in GSP attribute values. --- .../lang/parser/parsing/util/ParserUtils.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/util/ParserUtils.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/util/ParserUtils.java index 30158fe5ab09..600353d0fce1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/util/ParserUtils.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/util/ParserUtils.java @@ -178,20 +178,6 @@ public abstract class ParserUtils { marker.error(msg); } - public static void waitNextRCurly(PsiBuilder builder) { - int i = 0; - PsiBuilder.Marker em = builder.mark(); - while (!builder.eof() && !GroovyElementTypes.mRCURLY.equals(builder.getTokenType())) { - builder.advanceLexer(); - i++; - } - if (i > 0) { - em.error(GroovyBundle.message("rcurly.expected")); - } else { - em.drop(); - } - } - public static void advance(PsiBuilder builder, int count) { for (int i = 0; i < count; i++) { builder.getTokenText(); From ed89acd6c3a68df5b3eb19d06f345d0452ab9841 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 24 Jan 2011 18:13:30 +0100 Subject: [PATCH 31/53] branch number = 104 --- build.txt | 2 +- build/scripts/dist.gant | 2 +- .../src/com/intellij/ide/plugins/PluginManager.java | 4 ++-- platform/util/src/com/intellij/openapi/util/BuildNumber.java | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.txt b/build.txt index 3d1817be47e6..09d78e99910d 100644 --- a/build.txt +++ b/build.txt @@ -1 +1 @@ -103.SNAPSHOT +104.SNAPSHOT diff --git a/build/scripts/dist.gant b/build/scripts/dist.gant index f1d70fe59670..689a3b95098a 100644 --- a/build/scripts/dist.gant +++ b/build/scripts/dist.gant @@ -64,7 +64,7 @@ def wire_build_date(String buildNumber) { target('default': 'The default target') { depends(compile) layoutAll( - buildNumber: "IC-103.SNAPSHOT", + buildNumber: "IC-104.SNAPSHOT", version: "IdeaX", system_selector: "IntelliJIdeaCE10", jdk_req: "1.6*", diff --git a/platform/platform-api/src/com/intellij/ide/plugins/PluginManager.java b/platform/platform-api/src/com/intellij/ide/plugins/PluginManager.java index 53566f945e19..2fc1343026e7 100644 --- a/platform/platform-api/src/com/intellij/ide/plugins/PluginManager.java +++ b/platform/platform-api/src/com/intellij/ide/plugins/PluginManager.java @@ -760,11 +760,11 @@ public class PluginManager { ourBuildNumber = BuildNumber.fromString(new String(FileUtil.loadFileText(buildTxtFile)).trim()); } else { - ourBuildNumber = BuildNumber.fromString("103.SNAPSHOT"); + ourBuildNumber = BuildNumber.fromString("104.SNAPSHOT"); } } catch (IOException e) { - ourBuildNumber = BuildNumber.fromString("103.SNAPSHOT"); + ourBuildNumber = BuildNumber.fromString("104.SNAPSHOT"); } } } diff --git a/platform/util/src/com/intellij/openapi/util/BuildNumber.java b/platform/util/src/com/intellij/openapi/util/BuildNumber.java index 0f68d89eea9b..fa0f6f0be6a6 100644 --- a/platform/util/src/com/intellij/openapi/util/BuildNumber.java +++ b/platform/util/src/com/intellij/openapi/util/BuildNumber.java @@ -26,7 +26,7 @@ public class BuildNumber implements Comparable { private final int myBaselineVersion; private final int myBuildNumber; private static final String BUILD_NUMBER = "__BUILD_NUMBER__"; - private static final int TOP_BASELINE_VERSION = 103; + private static final int TOP_BASELINE_VERSION = 104; public BuildNumber(String productCode, int baselineVersion, int buildNumber) { myProductCode = productCode; From 2ec7b6f5e6d4acf2ca222b00d9bfb99fa7c356a7 Mon Sep 17 00:00:00 2001 From: "Rustam.Vishnyakov" Date: Mon, 24 Jan 2011 20:29:01 +0300 Subject: [PATCH 32/53] JavaScript library files scope for completion (performance improvements for WI-4830) --- .../ScriptingLibraryMappings.java | 25 +++++++++++++++++++ .../scripting/ScriptingLibrariesScope.java | 13 +++------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java index e3cdb712de0c..1563f90cb3f1 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java @@ -47,6 +47,7 @@ public class ScriptingLibraryMappings extends LanguagePerFileMappings myCompoundLibMap = new HashMap(); private CompoundLibrary myProjectLibs = new CompoundLibrary(); + private Set myProjectLibFiles; public ScriptingLibraryMappings(final Project project, final LibraryType libraryType) { super(project); @@ -95,6 +96,7 @@ public class ScriptingLibraryMappings extends LanguagePerFileMappings mappings) { super.setMappings(mappings); updateDependencies(mappings); + updateProjectLibraryFiles(); } private static boolean dependencyExists(ModuleRootManager rootManager, Library library) { @@ -171,6 +173,7 @@ public class ScriptingLibraryMappings extends LanguagePerFileMappings(); + for (CompoundLibrary container : myCompoundLibMap.values()) { + for (ScriptingLibraryTable.LibraryModel libModel : container.getLibraries()) { + myProjectLibFiles.addAll(Arrays.asList(libModel.getSourceFiles())); + myProjectLibFiles.addAll(Arrays.asList(libModel.getCompactFiles())); + } + } + for (ScriptingLibraryTable.LibraryModel libModel : myProjectLibs.getLibraries()) { + myProjectLibFiles.addAll(Arrays.asList(libModel.getSourceFiles())); + myProjectLibFiles.addAll(Arrays.asList(libModel.getCompactFiles())); + } + } + + public Set getProjectLibraryFiles() { + if (myProjectLibFiles == null) { + updateProjectLibraryFiles(); + } + return myProjectLibFiles; + } + + } diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibrariesScope.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibrariesScope.java index 75d549c0dcbc..3775379d474f 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibrariesScope.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibrariesScope.java @@ -30,7 +30,7 @@ public class ScriptingLibrariesScope extends GlobalSearchScope { private GlobalSearchScope myBaseScope; private ScriptingIndexableSetContributor myContributor; - private Set myLibraryFiles; + protected Set myLibraryFiles; public ScriptingLibrariesScope(GlobalSearchScope baseScope, Class providerClass) { super(baseScope.getProject()); @@ -38,21 +38,16 @@ public class ScriptingLibrariesScope extends GlobalSearchScope { IndexableSetContributor contributor = IndexableSetContributor.EP_NAME.findExtension(providerClass); if (contributor instanceof ScriptingIndexableSetContributor) { myContributor = (ScriptingIndexableSetContributor)contributor; - updateLibraryFiles(); + setLibraryFiles(); } } - public void updateLibraryFiles() { + public void setLibraryFiles() { myLibraryFiles = myContributor.getLibraryFiles(myBaseScope.getProject()); } public boolean contains(VirtualFile file) { - return myBaseScope.contains(file) | contributorContains(file); - } - - private boolean contributorContains(VirtualFile file) { - if (myContributor == null) return false; - return myLibraryFiles.contains(file); + return myBaseScope.contains(file) | (myLibraryFiles == null ? false : myLibraryFiles.contains(file)); } @Override From a6e612271962eb60de338725ae28dad62975e2c7 Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 24 Jan 2011 18:31:36 +0100 Subject: [PATCH 33/53] inline: find this ref corresponding to static imports (IDEA-64508) --- .../intellij/refactoring/util/InlineUtil.java | 9 +++++--- .../inlineLocal/StaticImported.java | 23 +++++++++++++++++++ .../inlineLocal/StaticImported.java.after | 22 ++++++++++++++++++ .../refactoring/inline/InlineLocalTest.java | 4 ++++ 4 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 java/java-tests/testData/refactoring/inlineLocal/StaticImported.java create mode 100644 java/java-tests/testData/refactoring/inlineLocal/StaticImported.java.after diff --git a/java/java-impl/src/com/intellij/refactoring/util/InlineUtil.java b/java/java-impl/src/com/intellij/refactoring/util/InlineUtil.java index 044493afcecb..ca2ac72bb928 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/InlineUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/util/InlineUtil.java @@ -78,10 +78,13 @@ public class InlineUtil { final PsiReferenceExpression methodExpression = ((PsiMethodCallExpression)expr).getMethodExpression(); final PsiExpression qualifierExpression = methodExpression.getQualifierExpression(); if (qualifierExpression == null) { - if (((PsiMethod)resolved).getModifierList().hasModifierProperty(PsiModifier.STATIC)) { - methodExpression.setQualifierExpression(elementFactory.createReferenceExpression(thisClass)); + final PsiMethod method = (PsiMethod)resolved; + final PsiClass containingClass = method.getContainingClass(); + LOG.assertTrue(containingClass != null); + if (method.getModifierList().hasModifierProperty(PsiModifier.STATIC)) { + methodExpression.setQualifierExpression(elementFactory.createReferenceExpression(containingClass)); } else { - methodExpression.setQualifierExpression(createThisExpression(manager, thisClass, refParent)); + methodExpression.setQualifierExpression(createThisExpression(manager, containingClass, refParent)); } } } diff --git a/java/java-tests/testData/refactoring/inlineLocal/StaticImported.java b/java/java-tests/testData/refactoring/inlineLocal/StaticImported.java new file mode 100644 index 000000000000..eea23b87fda6 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineLocal/StaticImported.java @@ -0,0 +1,23 @@ +import java.util.ArrayList; +import java.util.List; + +import static Statics._emptyList; + +public class Statics { + + public static List _emptyList() { + return new ArrayList(); + } +} + + +class Foo { + public static void main(String[] args) { + List v1 = _emptyList(); + doSomething(v1); + } + + public static void doSomething(List list) { + + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inlineLocal/StaticImported.java.after b/java/java-tests/testData/refactoring/inlineLocal/StaticImported.java.after new file mode 100644 index 000000000000..d40a49eb49d4 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineLocal/StaticImported.java.after @@ -0,0 +1,22 @@ +import java.util.ArrayList; +import java.util.List; + +import static Statics._emptyList; + +public class Statics { + + public static List _emptyList() { + return new ArrayList(); + } +} + + +class Foo { + public static void main(String[] args) { + doSomething(Statics._emptyList()); + } + + public static void doSomething(List list) { + + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineLocalTest.java b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineLocalTest.java index 8d469b31166e..9f20be7086c9 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineLocalTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineLocalTest.java @@ -123,6 +123,10 @@ public class InlineLocalTest extends LightCodeInsightTestCase { doTest(true); } + public void testStaticImported() throws Exception { + doTest(true); + } + private void doTest(final boolean inlineDef, String conflictMessage) throws Exception { try { doTest(inlineDef); From 2a8810a6fd33b93e719602950040a372a8867d99 Mon Sep 17 00:00:00 2001 From: Rustam Vishnyakov Date: Mon, 24 Jan 2011 22:07:54 +0300 Subject: [PATCH 34/53] Revert "JavaScript library files scope for completion (performance improvements for WI-4830)" This reverts commit 2ec7b6f5e6d4acf2ca222b00d9bfb99fa7c356a7. --- .../ScriptingLibraryMappings.java | 25 ------------------- .../scripting/ScriptingLibrariesScope.java | 13 +++++++--- 2 files changed, 9 insertions(+), 29 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java index 1563f90cb3f1..e3cdb712de0c 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java @@ -47,7 +47,6 @@ public class ScriptingLibraryMappings extends LanguagePerFileMappings myCompoundLibMap = new HashMap(); private CompoundLibrary myProjectLibs = new CompoundLibrary(); - private Set myProjectLibFiles; public ScriptingLibraryMappings(final Project project, final LibraryType libraryType) { super(project); @@ -96,7 +95,6 @@ public class ScriptingLibraryMappings extends LanguagePerFileMappings mappings) { super.setMappings(mappings); updateDependencies(mappings); - updateProjectLibraryFiles(); } private static boolean dependencyExists(ModuleRootManager rootManager, Library library) { @@ -173,7 +171,6 @@ public class ScriptingLibraryMappings extends LanguagePerFileMappings(); - for (CompoundLibrary container : myCompoundLibMap.values()) { - for (ScriptingLibraryTable.LibraryModel libModel : container.getLibraries()) { - myProjectLibFiles.addAll(Arrays.asList(libModel.getSourceFiles())); - myProjectLibFiles.addAll(Arrays.asList(libModel.getCompactFiles())); - } - } - for (ScriptingLibraryTable.LibraryModel libModel : myProjectLibs.getLibraries()) { - myProjectLibFiles.addAll(Arrays.asList(libModel.getSourceFiles())); - myProjectLibFiles.addAll(Arrays.asList(libModel.getCompactFiles())); - } - } - - public Set getProjectLibraryFiles() { - if (myProjectLibFiles == null) { - updateProjectLibraryFiles(); - } - return myProjectLibFiles; - } - - } diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibrariesScope.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibrariesScope.java index 3775379d474f..75d549c0dcbc 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibrariesScope.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibrariesScope.java @@ -30,7 +30,7 @@ public class ScriptingLibrariesScope extends GlobalSearchScope { private GlobalSearchScope myBaseScope; private ScriptingIndexableSetContributor myContributor; - protected Set myLibraryFiles; + private Set myLibraryFiles; public ScriptingLibrariesScope(GlobalSearchScope baseScope, Class providerClass) { super(baseScope.getProject()); @@ -38,16 +38,21 @@ public class ScriptingLibrariesScope extends GlobalSearchScope { IndexableSetContributor contributor = IndexableSetContributor.EP_NAME.findExtension(providerClass); if (contributor instanceof ScriptingIndexableSetContributor) { myContributor = (ScriptingIndexableSetContributor)contributor; - setLibraryFiles(); + updateLibraryFiles(); } } - public void setLibraryFiles() { + public void updateLibraryFiles() { myLibraryFiles = myContributor.getLibraryFiles(myBaseScope.getProject()); } public boolean contains(VirtualFile file) { - return myBaseScope.contains(file) | (myLibraryFiles == null ? false : myLibraryFiles.contains(file)); + return myBaseScope.contains(file) | contributorContains(file); + } + + private boolean contributorContains(VirtualFile file) { + if (myContributor == null) return false; + return myLibraryFiles.contains(file); } @Override From b8630448f57dfe015388e201a2a9ff96197555a0 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Tue, 25 Jan 2011 00:58:29 +0300 Subject: [PATCH 35/53] fixing tree leaks --- .../impl/source/html/ScriptSupportUtil.java | 64 +++++++++++-------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/xml/impl/src/com/intellij/psi/impl/source/html/ScriptSupportUtil.java b/xml/impl/src/com/intellij/psi/impl/source/html/ScriptSupportUtil.java index 2c03f0e80dcb..73aa583f7b2c 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/html/ScriptSupportUtil.java +++ b/xml/impl/src/com/intellij/psi/impl/source/html/ScriptSupportUtil.java @@ -22,6 +22,8 @@ import com.intellij.psi.ResolveState; import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceUtil; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.search.PsiElementProcessor; +import com.intellij.psi.util.CachedValue; +import com.intellij.psi.util.CachedValueProvider; import com.intellij.psi.xml.*; import com.intellij.xml.XmlElementDescriptor; import com.intellij.xml.util.HtmlUtil; @@ -35,7 +37,7 @@ import java.util.List; * @author Maxim.Mossienko */ public class ScriptSupportUtil { - private static final Key CachedScriptTagsKey = Key.create("script tags"); + private static final Key> CachedScriptTagsKey = Key.create("script tags"); private static final ThreadLocal ProcessingDeclarationsFlag = new ThreadLocal(); private static final @NonNls String SCRIPT_TAG = "script"; @@ -46,61 +48,71 @@ public class ScriptSupportUtil { element.putUserData(CachedScriptTagsKey,null); } - public static boolean processDeclarations(XmlFile element, PsiScopeProcessor processor, ResolveState state, PsiElement lastParent, PsiElement place) { - XmlTag[] myCachedScriptTags = element.getUserData(CachedScriptTagsKey); - + public static boolean processDeclarations(final XmlFile element, + PsiScopeProcessor processor, + ResolveState state, + PsiElement lastParent, + PsiElement place) { + CachedValue myCachedScriptTags = element.getUserData(CachedScriptTagsKey); if (myCachedScriptTags == null) { - final List scriptTags = new ArrayList(); - final XmlDocument document = HtmlUtil.getRealXmlDocument(element.getDocument()); + myCachedScriptTags = element.getManager().getCachedValuesManager().createCachedValue(new CachedValueProvider() { + @Override + public Result compute() { + final List scriptTags = new ArrayList(); + final XmlDocument document = HtmlUtil.getRealXmlDocument(element.getDocument()); - if (document != null) { - XmlUtil.processXmlElements(document, - new PsiElementProcessor() { - public boolean execute(final PsiElement element) { - if (element instanceof XmlTag) { - final XmlTag tag = (XmlTag)element; + if (document != null) { + PsiElementProcessor psiElementProcessor = new PsiElementProcessor() { + public boolean execute(final PsiElement element) { + if (element instanceof XmlTag) { + final XmlTag tag = (XmlTag)element; - if (SCRIPT_TAG.equalsIgnoreCase(tag.getName())) { - final XmlElementDescriptor descriptor = tag.getDescriptor(); - if (descriptor != null && SCRIPT_TAG.equals(descriptor.getName())) { - scriptTags.add(tag); + if (SCRIPT_TAG.equalsIgnoreCase(tag.getName())) { + final XmlElementDescriptor descriptor = tag.getDescriptor(); + if (descriptor != null && SCRIPT_TAG.equals(descriptor.getName())) { + scriptTags.add(tag); + } + } } + return true; } - } - return true; + }; + XmlUtil.processXmlElements(document,psiElementProcessor, true); } - }, true); - } - myCachedScriptTags = scriptTags.toArray(new XmlTag[scriptTags.size()]); + return new Result(scriptTags.toArray(new XmlTag[scriptTags.size()]), element); + } + }, false); element.putUserData(CachedScriptTagsKey, myCachedScriptTags); } if (ProcessingDeclarationsFlag.get() != null) return true; - + try { ProcessingDeclarationsFlag.set(""); - for (XmlTag tag : myCachedScriptTags) { + for (XmlTag tag : myCachedScriptTags.getValue()) { final XmlTagChild[] children = tag.getValue().getChildren(); for (XmlTagChild child : children) { if (!child.processDeclarations(processor, state, null, place)) return false; } - if(tag.getAttributeValue("src") != null) { + if (tag.getAttributeValue("src") != null) { final XmlAttribute attribute = tag.getAttribute("src", null); if (attribute != null) { final PsiFile psiFile = FileReferenceUtil.findFile(attribute.getValueElement()); if (psiFile != null && psiFile.isValid()) { - if(!psiFile.processDeclarations(processor, state, null, place)) + if (!psiFile.processDeclarations(processor, state, null, place)) { return false; + } } } } } - } finally { + } + finally { ProcessingDeclarationsFlag.set(null); } From de90ad7d316c02b38ddef1954cf04732fbad489b Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Tue, 25 Jan 2011 09:40:55 +0300 Subject: [PATCH 36/53] Corrected (x; y) -> visual position mapping in situation when target offset points to line feed --- .../src/com/intellij/openapi/editor/impl/EditorImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 13f4ed7e29b6..3887e3583e17 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 @@ -1015,7 +1015,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi charWidth = EditorUtil.charWidth(c, fontType, this); } - if (charWidth <= 0) { + if (charWidth < 0) { charWidth = spaceSize; } From 09d0d80b04fc1fa6d0d53b06ddeda25d9dcebb4e Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Tue, 25 Jan 2011 10:47:13 +0300 Subject: [PATCH 37/53] IDEA-64546 Editor: Correct code selection by vertical caret position change 1. Don't perform automatic selection expansion to collapsed fold region in situation when current selection ends just before fold region start; 2. Corrected lead selection offset calculation in situation when selection is automatically expanded to collapsed fold region; --- .../editor/impl/SelectionModelImpl.java | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java index 73bf8957b66a..98de2ccac0ea 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java @@ -311,7 +311,13 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi FoldRegion endFold = foldingModel.getCollapsedRegionAtOffset(endOffset); if (endFold != null) { - endOffset = endFold.getEndOffset(); + VisualPosition visualFoldStart = myEditor.offsetToVisualPosition(endFold.getStartOffset()); + // All visual positions that lay at collapsed fold region placeholder are mapped to the same offset. Hence, there are + // at least two distinct situations - selection end is located inside collapsed fold region placeholder and just before it. + // We want to expand selection to the fold region end at the former case and keep selection as-is at the latest one. + if (visualFoldStart.column < endPosition.column) { + endOffset = endFold.getEndOffset(); + } } int oldSelectionStart; @@ -583,6 +589,20 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi if (marker != null) { int startOffset = marker.getStartOffset(); int endOffset = marker.getEndOffset(); + if (caretOffset != startOffset && caretOffset != endOffset) { + // Try to check if current selection is tweaked by fold region. + FoldingModelEx foldingModel = myEditor.getFoldingModel(); + FoldRegion foldRegion = foldingModel.getCollapsedRegionAtOffset(caretOffset); + if (foldRegion != null) { + if (foldRegion.getStartOffset() == startOffset) { + return endOffset; + } + else if (foldRegion.getEndOffset() == endOffset) { + return startOffset; + } + } + } + if (caretOffset == endOffset) { return startOffset; } From 4e146072845c8c29960956289471e6d3853cff29 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Tue, 25 Jan 2011 11:18:23 +0300 Subject: [PATCH 38/53] IDEA-63820 Allow "throws" to be placed on the new line without indent 1. Added ability to configure java formatter in a way to align 'throws' keyword to method start; 2. Corresponding tests are added; --- ...JavaLanguageCodeStyleSettingsProvider.java | 3 ++- .../psi/formatter/java/AbstractJavaBlock.java | 1 + .../java/JavaFormatterAlignmentTest.java | 22 +++++++++++++++++++ .../codeStyle/CommonCodeStyleSettings.java | 1 + .../codeStyle/WrappingAndBracesPanel.java | 1 + .../src/messages/ApplicationBundle.properties | 1 + 6 files changed, 28 insertions(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/ide/JavaLanguageCodeStyleSettingsProvider.java b/java/java-impl/src/com/intellij/ide/JavaLanguageCodeStyleSettingsProvider.java index 464e6761a0eb..5e851f65886b 100644 --- a/java/java-impl/src/com/intellij/ide/JavaLanguageCodeStyleSettingsProvider.java +++ b/java/java-impl/src/com/intellij/ide/JavaLanguageCodeStyleSettingsProvider.java @@ -215,7 +215,8 @@ public class JavaLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSett " x--;\n" + " } while (x > 10) \n" + " }\n" + - " public static void test() { \n" + + " public static void test() \n" + + " throws Exception { \n" + " foo.foo().bar(\"arg1\", \n" + " \"arg2\"); \n" + " } \n" + diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java index 217cfa449d54..e6f14c03dc91 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java @@ -823,6 +823,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo if (role == ChildRole.TYPE_PARAMETER_LIST) return defaultAlignment; if (role == ChildRole.TYPE) return defaultAlignment; if (role == ChildRole.NAME) return defaultAlignment; + if (role == ChildRole.THROWS_LIST && mySettings.ALIGN_THROWS_KEYWORD) return defaultAlignment; return null; } diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterAlignmentTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterAlignmentTest.java index df01c1730213..962298ef0b6d 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterAlignmentTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterAlignmentTest.java @@ -251,4 +251,26 @@ public class JavaFormatterAlignmentTest extends AbstractJavaFormatterTest { "}" ); } + + public void testAlignThrowsKeyword() throws Exception { + // Inspired by IDEA-63820 + + getSettings().ALIGN_THROWS_KEYWORD = true; + doClassTest( + "public void test()\n" + + " throws Exception {}", + "public void test()\n" + + "throws Exception {\n" + + "}" + ); + + getSettings().ALIGN_THROWS_KEYWORD = false; + doClassTest( + "public void test()\n" + + " throws Exception {}", + "public void test()\n" + + " throws Exception {\n" + + "}" + ); + } } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java index 698cd3ad5a7f..44b1baa91379 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java @@ -299,6 +299,7 @@ public class CommonCodeStyleSettings { public boolean ALIGN_MULTILINE_ASSIGNMENT = false; public boolean ALIGN_MULTILINE_TERNARY_OPERATION = false; public boolean ALIGN_MULTILINE_THROWS_LIST = false; + public boolean ALIGN_THROWS_KEYWORD = false; public boolean ALIGN_MULTILINE_EXTENDS_LIST = false; public boolean ALIGN_MULTILINE_METHOD_BRACKETS = false; diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/WrappingAndBracesPanel.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/WrappingAndBracesPanel.java index eff6430a43be..038e7608b7c5 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/WrappingAndBracesPanel.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/WrappingAndBracesPanel.java @@ -49,6 +49,7 @@ public class WrappingAndBracesPanel extends OptionTableWithPreviewPanel { addOption("THROWS_LIST_WRAP", WRAPPING_THROWS_LIST, WRAP_OPTIONS, WRAP_VALUES); addOption("ALIGN_MULTILINE_THROWS_LIST", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_THROWS_LIST); + addOption("ALIGN_THROWS_KEYWORD", ApplicationBundle.message("wrapping.align.throws.keyword"), WRAPPING_THROWS_LIST); addOption("THROWS_KEYWORD_WRAP", WRAPPING_THROWS_KEYWORD, WRAP_OPTIONS_FOR_SINGLETON, WRAP_VALUES_FOR_SINGLETON); addOption("METHOD_PARAMETERS_WRAP", WRAPPING_METHOD_PARAMETERS, WRAP_OPTIONS, WRAP_VALUES); diff --git a/platform/platform-resources-en/src/messages/ApplicationBundle.properties b/platform/platform-resources-en/src/messages/ApplicationBundle.properties index eeca36cec25f..fcdb403e126b 100644 --- a/platform/platform-resources-en/src/messages/ApplicationBundle.properties +++ b/platform/platform-resources-en/src/messages/ApplicationBundle.properties @@ -180,6 +180,7 @@ wrapping.extends.implements.list=Extends/implements list wrapping.extends.implements.keyword=Extends/implements keyword wrapping.throws.list=Throws list wrapping.throws.keyword=Throws keyword +wrapping.align.throws.keyword=Align 'throws' to method start wrapping.ternary.operation=Ternary operation wrapping.assignment.variables.groups=Fields/variables groups wrapping.assignment.statement=Assignment statement From 302f10f400b3d76640f0849ef26192d0b98c09d0 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Mon, 24 Jan 2011 16:07:22 +0300 Subject: [PATCH 39/53] EA-25099 - NPE: XMLExternalAnnotator.addMessagesForTreeChild (annotator should be stateless) --- .../lang/xml/XMLExternalAnnotator.java | 107 +++++++++--------- 1 file changed, 55 insertions(+), 52 deletions(-) diff --git a/xml/impl/src/com/intellij/lang/xml/XMLExternalAnnotator.java b/xml/impl/src/com/intellij/lang/xml/XMLExternalAnnotator.java index 6a8a4ec0d21d..c43886ecc2eb 100644 --- a/xml/impl/src/com/intellij/lang/xml/XMLExternalAnnotator.java +++ b/xml/impl/src/com/intellij/lang/xml/XMLExternalAnnotator.java @@ -33,8 +33,7 @@ import com.intellij.xml.util.XmlTagUtil; /** * @author ven */ -public class XMLExternalAnnotator implements ExternalAnnotator, Validator.ValidationHost { - private AnnotationHolder myHolder; +public class XMLExternalAnnotator implements ExternalAnnotator { public void annotate(PsiFile file, AnnotationHolder holder) { if (!(file instanceof XmlFile)) return; @@ -44,64 +43,68 @@ public class XMLExternalAnnotator implements ExternalAnnotator, Validator.Valida XmlNSDescriptor nsDescriptor = rootTag == null ? null : rootTag.getNSDescriptor(rootTag.getNamespace(), false); if (nsDescriptor instanceof Validator && !HtmlUtil.isHtml5Document(document)) { - myHolder = holder; - try { //noinspection unchecked - ((Validator)nsDescriptor).validate(document, this); - } - finally { - myHolder = null; - } + ((Validator)nsDescriptor).validate(document, new MyHost(holder)); } } - private static final ErrorType[] types = ErrorType.values(); - - public void addMessage(PsiElement context, String message, int type) { - addMessage(context, message, types[type]); - } - - public void addMessage(final PsiElement context, final String message, final ErrorType type, final IntentionAction... fixes) { - if (message != null && message.length() > 0) { - if (context instanceof XmlTag) { - addMessagesForTag((XmlTag)context, message, type, fixes); - } - else { - if (type == Validator.ValidationHost.ErrorType.ERROR) { - appendFixes(myHolder.createErrorAnnotation(context, message), fixes); - } else { - appendFixes(myHolder.createWarningAnnotation(context, message), fixes); - } - } - } - } - - private void addMessagesForTag(XmlTag tag, String message, ErrorType type, IntentionAction... actions) { - XmlToken childByRole = XmlTagUtil.getStartTagNameElement(tag); - - addMessagesForTreeChild(childByRole, type, message, actions); - - childByRole = XmlTagUtil.getEndTagNameElement(tag); - addMessagesForTreeChild(childByRole, type, message, actions); - } - - private void addMessagesForTreeChild(final XmlToken childByRole, final ErrorType type, final String message, IntentionAction... actions) { - if (childByRole != null) { - Annotation annotation; - if (type == ErrorType.ERROR) { - annotation = myHolder.createErrorAnnotation(childByRole, message); - } - else { - annotation = myHolder.createWarningAnnotation(childByRole, message); - } - - appendFixes(annotation, actions); - } - } + private static final Validator.ValidationHost.ErrorType[] types = Validator.ValidationHost.ErrorType.values(); private static void appendFixes(final Annotation annotation, final IntentionAction... actions) { if (actions != null) { for(IntentionAction action:actions) annotation.registerFix(action); } } + + private static class MyHost implements Validator.ValidationHost { + + private final AnnotationHolder myHolder; + + public MyHost(AnnotationHolder holder) { + + myHolder = holder; + } + + public void addMessage(PsiElement context, String message, int type) { + addMessage(context, message, types[type]); + } + + public void addMessage(final PsiElement context, final String message, final ErrorType type, final IntentionAction... fixes) { + if (message != null && message.length() > 0) { + if (context instanceof XmlTag) { + addMessagesForTag((XmlTag)context, message, type, fixes); + } + else { + if (type == Validator.ValidationHost.ErrorType.ERROR) { + appendFixes(myHolder.createErrorAnnotation(context, message), fixes); + } else { + appendFixes(myHolder.createWarningAnnotation(context, message), fixes); + } + } + } + } + + private void addMessagesForTag(XmlTag tag, String message, ErrorType type, IntentionAction... actions) { + XmlToken childByRole = XmlTagUtil.getStartTagNameElement(tag); + + addMessagesForTreeChild(childByRole, type, message, actions); + + childByRole = XmlTagUtil.getEndTagNameElement(tag); + addMessagesForTreeChild(childByRole, type, message, actions); + } + + private void addMessagesForTreeChild(final XmlToken childByRole, final ErrorType type, final String message, IntentionAction... actions) { + if (childByRole != null) { + Annotation annotation; + if (type == ErrorType.ERROR) { + annotation = myHolder.createErrorAnnotation(childByRole, message); + } + else { + annotation = myHolder.createWarningAnnotation(childByRole, message); + } + + appendFixes(annotation, actions); + } + } + } } From 4180783a3ec048249761f1e29dd10351c9e1b0c0 Mon Sep 17 00:00:00 2001 From: "Rustam.Vishnyakov" Date: Tue, 25 Jan 2011 12:37:43 +0300 Subject: [PATCH 40/53] JavaScript library files scope for completion (performance improvements for WI-4830) - reapplied --- .../ScriptingLibraryMappings.java | 25 +++++++++++++++++++ .../scripting/ScriptingLibrariesScope.java | 13 +++------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java index e3cdb712de0c..1563f90cb3f1 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java @@ -47,6 +47,7 @@ public class ScriptingLibraryMappings extends LanguagePerFileMappings myCompoundLibMap = new HashMap(); private CompoundLibrary myProjectLibs = new CompoundLibrary(); + private Set myProjectLibFiles; public ScriptingLibraryMappings(final Project project, final LibraryType libraryType) { super(project); @@ -95,6 +96,7 @@ public class ScriptingLibraryMappings extends LanguagePerFileMappings mappings) { super.setMappings(mappings); updateDependencies(mappings); + updateProjectLibraryFiles(); } private static boolean dependencyExists(ModuleRootManager rootManager, Library library) { @@ -171,6 +173,7 @@ public class ScriptingLibraryMappings extends LanguagePerFileMappings(); + for (CompoundLibrary container : myCompoundLibMap.values()) { + for (ScriptingLibraryTable.LibraryModel libModel : container.getLibraries()) { + myProjectLibFiles.addAll(Arrays.asList(libModel.getSourceFiles())); + myProjectLibFiles.addAll(Arrays.asList(libModel.getCompactFiles())); + } + } + for (ScriptingLibraryTable.LibraryModel libModel : myProjectLibs.getLibraries()) { + myProjectLibFiles.addAll(Arrays.asList(libModel.getSourceFiles())); + myProjectLibFiles.addAll(Arrays.asList(libModel.getCompactFiles())); + } + } + + public Set getProjectLibraryFiles() { + if (myProjectLibFiles == null) { + updateProjectLibraryFiles(); + } + return myProjectLibFiles; + } + + } diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibrariesScope.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibrariesScope.java index 75d549c0dcbc..3775379d474f 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibrariesScope.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibrariesScope.java @@ -30,7 +30,7 @@ public class ScriptingLibrariesScope extends GlobalSearchScope { private GlobalSearchScope myBaseScope; private ScriptingIndexableSetContributor myContributor; - private Set myLibraryFiles; + protected Set myLibraryFiles; public ScriptingLibrariesScope(GlobalSearchScope baseScope, Class providerClass) { super(baseScope.getProject()); @@ -38,21 +38,16 @@ public class ScriptingLibrariesScope extends GlobalSearchScope { IndexableSetContributor contributor = IndexableSetContributor.EP_NAME.findExtension(providerClass); if (contributor instanceof ScriptingIndexableSetContributor) { myContributor = (ScriptingIndexableSetContributor)contributor; - updateLibraryFiles(); + setLibraryFiles(); } } - public void updateLibraryFiles() { + public void setLibraryFiles() { myLibraryFiles = myContributor.getLibraryFiles(myBaseScope.getProject()); } public boolean contains(VirtualFile file) { - return myBaseScope.contains(file) | contributorContains(file); - } - - private boolean contributorContains(VirtualFile file) { - if (myContributor == null) return false; - return myLibraryFiles.contains(file); + return myBaseScope.contains(file) | (myLibraryFiles == null ? false : myLibraryFiles.contains(file)); } @Override From 0e67e00a04ce86237bc6be10a0a9300903de94cb Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Jan 2011 11:05:41 +0100 Subject: [PATCH 41/53] escape < in the groovy quick doc --- .../lang/documentation/GroovyDocumentationProvider.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/documentation/GroovyDocumentationProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/documentation/GroovyDocumentationProvider.java index 96a251590ffd..e8c77a325055 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/documentation/GroovyDocumentationProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/documentation/GroovyDocumentationProvider.java @@ -24,6 +24,7 @@ import com.intellij.lang.documentation.CodeDocumentationProvider; import com.intellij.lang.documentation.ExternalDocumentationProvider; import com.intellij.lang.java.JavaDocumentationProvider; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.impl.source.javadoc.PsiDocParamRef; import com.intellij.psi.javadoc.PsiDocComment; @@ -162,7 +163,8 @@ public class GroovyDocumentationProvider implements CodeDocumentationProvider, E if (originalElement instanceof GrReferenceExpression) { final PsiType inferredType = ((GrReferenceExpression)originalElement).getType(); if (inferredType != null) { - buffer.append("[inferred type] ").append(inferredType.getCanonicalText()); + buffer.append("[inferred type] "); + appendTypeString(buffer, inferredType); return; } } @@ -256,7 +258,7 @@ public class GroovyDocumentationProvider implements CodeDocumentationProvider, E private static void appendTypeString(StringBuffer buffer, PsiType type) { if (type != null) { - buffer.append(type.getCanonicalText()); + buffer.append(StringUtil.escapeXml(type.getCanonicalText())); } else { buffer.append(GrModifier.DEF); From ef13dce84078d4b8d5fc47e2d5ff2e8f61886ed6 Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Tue, 25 Jan 2011 13:51:26 +0300 Subject: [PATCH 42/53] Do not wait for frame to be activated for project-level notifications --- .../intellij/notification/Notifications.java | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/platform/platform-api/src/com/intellij/notification/Notifications.java b/platform/platform-api/src/com/intellij/notification/Notifications.java index 2f71c57a27a5..e056d4ee7f37 100644 --- a/platform/platform-api/src/com/intellij/notification/Notifications.java +++ b/platform/platform-api/src/com/intellij/notification/Notifications.java @@ -49,19 +49,36 @@ public interface Notifications { } public static void notify(@NotNull final Notification notification, @NotNull final NotificationDisplayType defaultDisplayType, @Nullable final Project project) { - if (project != null && !project.isInitialized()) { - StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() { - public void run() { - project.getMessageBus().syncPublisher(TOPIC).notify(notification, defaultDisplayType); - } - }); + if (project != null && !project.isDisposed()) { + if (!project.isInitialized()) { + StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() { + public void run() { + project.getMessageBus().syncPublisher(TOPIC).notify(notification, defaultDisplayType); + } + }); + } + else { + if (EventQueue.isDispatchThread()) { + project.getMessageBus().syncPublisher(TOPIC).notify(notification, defaultDisplayType); + } + else { + //noinspection SSBasedInspection + SwingUtilities.invokeLater(new Runnable() { + public void run() { + project.getMessageBus().syncPublisher(TOPIC).notify(notification, defaultDisplayType); + } + }); + } + } + return; } FrameStateManager.getInstance().getApplicationActive().doWhenDone(new Runnable() { @Override public void run() { - final MessageBus bus = project == null ? ApplicationManager.getApplication().getMessageBus() : (project.isDisposed() ? null : project.getMessageBus()); + final MessageBus bus = + project == null ? ApplicationManager.getApplication().getMessageBus() : (project.isDisposed() ? null : project.getMessageBus()); if (bus != null) { if (EventQueue.isDispatchThread()) { bus.syncPublisher(TOPIC).notify(notification, defaultDisplayType); From 0460fe92cabfa67ea1168099220cd937d0fa7916 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Tue, 25 Jan 2011 14:03:00 +0300 Subject: [PATCH 43/53] do not strongly hold tree to avoid leak --- .../intellij/psi/impl/source/xml/XmlEntityRefImpl.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java index 3771b58326d8..31246794c167 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java +++ b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java @@ -66,16 +66,19 @@ public class XmlEntityRefImpl extends XmlElementImpl implements XmlEntityRef { return cachedValue != null ? cachedValue.getValue():null; } - public static void cacheParticularEntity(PsiFile file, final XmlEntityDecl decl) { + public static void cacheParticularEntity(PsiFile file, XmlEntityDecl decl) { synchronized(PsiLock.LOCK) { final Map> cachingMap = getCachingMap(file); final String name = decl.getName(); if (cachingMap.containsKey(name)) return; + final SmartPsiElementPointer declPointer = SmartPointerManager.getInstance(file.getProject()).createSmartPsiElementPointer(decl); + cachingMap.put( name, CachedValuesManager.getManager(file.getProject()).createCachedValue(new CachedValueProvider() { public Result compute() { - if (decl.isValid() && name.equals(decl.getName())) - return new Result(decl,decl); + PsiElement declElement = declPointer.getElement(); + if (declElement instanceof XmlEntityDecl && declElement.isValid() && name.equals(((XmlEntityDecl)declElement).getName())) + return new Result((XmlEntityDecl)declElement, declElement); cachingMap.put(name,null); return new Result(null,null); } From 2d2d9afd6fbb867b52d5a2b13da7e60664c92030 Mon Sep 17 00:00:00 2001 From: "andrey.zaytsev" Date: Tue, 25 Jan 2011 14:11:58 +0300 Subject: [PATCH 44/53] Find dialog refactoring and validation --- .../com/intellij/find/impl/FindDialog.java | 212 ++++++++++++------ 1 file changed, 144 insertions(+), 68 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java index 2337b752c294..40ddea6db2b2 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java @@ -57,6 +57,7 @@ import com.intellij.ui.components.labels.LinkListener; import com.intellij.util.ArrayUtil; import com.intellij.util.Consumer; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.text.BadLocationException; @@ -110,6 +111,7 @@ class FindDialog extends DialogWrapper { super(project, true); myProject = project; myModel = model; + this.myOkHandler = myOkHandler; if (myModel.isReplaceState()){ @@ -274,6 +276,22 @@ class FindDialog extends DialogWrapper { validateFindButton(); } + public FindModel getModel() { + return myModel; + } + + @Nullable + public FindModel getCurrentModel() { + FindModel validateModel = (FindModel)myModel.clone(); + applyTo(validateModel, false); + + + if (getValidationInfo(validateModel) == null) { + return validateModel; + } + return null; + } + private static int getCaretPosition(JComboBox comboBox) { Component editorComponent = comboBox.getEditor().getEditorComponent(); if (editorComponent instanceof JTextField){ @@ -293,7 +311,6 @@ class FindDialog extends DialogWrapper { private void validateFindButton() { final String toFind = getStringToFind(); - if (toFind == null || toFind.length() == 0){ setOKStatus(false); return; @@ -416,76 +433,130 @@ class FindDialog extends DialogWrapper { private void doOKAction(boolean findAll) { FindModel validateModel = (FindModel)myModel.clone(); - applyTo(validateModel); - validateModel.setFindAll(findAll); - if (validateModel.getDirectoryName() != null) { - PsiDirectory directory = FindInProjectUtil.getPsiDirectory(validateModel, myProject); - if (directory == null) { + applyTo(validateModel, findAll); + + ValidationInfo validationInfo = getValidationInfo(validateModel); + + if (validationInfo == null) { + + myModel.copyFrom(validateModel); + updateFindSettings(); + + super.doOKAction(); + myOkHandler.run(); + } else { + String message = validationInfo.message; + if (message != null) { Messages.showMessageDialog( myProject, - FindBundle.message("find.directory.not.found.error", validateModel.getDirectoryName()), + message, CommonBundle.getErrorTitle(), Messages.getErrorIcon() ); - return; } } + } - if (validateModel.isRegularExpressions()) { - String toFind = validateModel.getStringToFind(); - try { - Pattern pattern = Pattern.compile(toFind, validateModel.isCaseSensitive() ? Pattern.MULTILINE : Pattern.MULTILINE | Pattern.CASE_INSENSITIVE); - if (pattern.matcher("").matches() && !toFind.endsWith("$") && !toFind.startsWith("^")) { - throw new PatternSyntaxException(FindBundle.message("find.empty.match.regular.expression.error"),toFind, -1); - } - } - catch(PatternSyntaxException e){ - Messages.showMessageDialog( - myProject, - FindBundle.message("find.invalid.regular.expression.error", toFind, e.getDescription()), - CommonBundle.getErrorTitle(), - Messages.getErrorIcon() - ); - return; - } + private void updateFindSettings() { + FindSettings findSettings = FindSettings.getInstance(); + findSettings.setCaseSensitive(myModel.isCaseSensitive()); + if (myModel.isReplaceState()) { + findSettings.setPreserveCase(myModel.isPreserveCase()); } - validateModel.setFileFilter( null ); - FindSettings.getInstance().setFileMask(null); + findSettings.setWholeWordsOnly(myModel.isWholeWordsOnly()); + findSettings.setInStringLiteralsOnly(myModel.isInStringLiteralsOnly()); + findSettings.setInCommentsOnly(myModel.isInCommentsOnly()); - if (useFileFilter!=null && useFileFilter.isSelected() && - myFileFilter.getSelectedItem()!=null - ) { - final String mask = (String)myFileFilter.getSelectedItem(); + findSettings.setRegularExpressions(myModel.isRegularExpressions()); + if (!myModel.isMultipleFiles()){ + findSettings.setForward(myModel.isForward()); + findSettings.setFromCursor(myModel.isFromCursor()); - if (mask.length() > 0) { - try { - FindInProjectUtil.createFileMaskRegExp(mask); // verify that the regexp compiles - validateModel.setFileFilter(mask); - FindSettings.getInstance().setFileMask(mask); - } - catch (PatternSyntaxException ex) { - Messages.showMessageDialog(myProject, FindBundle.message("find.filter.invalid.file.mask.error", myFileFilter.getSelectedItem()), - CommonBundle.getErrorTitle(), Messages.getErrorIcon()); - return; - } + findSettings.setGlobal(myModel.isGlobal()); + } else{ + String directoryName = myModel.getDirectoryName(); + if (directoryName != null && !directoryName.isEmpty()) { + findSettings.setWithSubdirectories(myModel.isWithSubdirectories()); } - else { - Messages.showMessageDialog(myProject, FindBundle.message("find.filter.empty.file.mask.error"), CommonBundle.getErrorTitle(), - Messages.getErrorIcon()); - return; + else if (myRbModule.isSelected()) { + } + else if (myRbCustomScope.isSelected()) { + SearchScope selectedScope = myScopeCombo.getSelectedScope(); + String customScopeName = selectedScope == null ? null : selectedScope.getDisplayName(); + findSettings.setCustomScope(customScopeName); } } if (myCbToSkipResultsWhenOneUsage != null){ - FindSettings.getInstance().setSkipResultsWithOneUsage( + findSettings.setSkipResultsWithOneUsage( isSkipResultsWhenOneUsage() ); } - myModel.copyFrom(validateModel); - super.doOKAction(); - myOkHandler.run(); + findSettings.setFileMask(myModel.getFileFilter()); + } + + @Override + protected boolean postponeValidation() { + return true; + } + + private ValidationInfo getValidationInfo(FindModel model) { + if (myRbDirectory != null && myRbDirectory.isEnabled() && myRbDirectory.isSelected()) { + PsiDirectory directory = FindInProjectUtil.getPsiDirectory(model, myProject); + if (directory == null) { + return new ValidationInfo(FindBundle.message("find.directory.not.found.error", getDirectory()), myDirectoryComboBox); + } + } + + String toFind = (String)myInputComboBox.getSelectedItem(); + if (toFind != null && toFind.isEmpty()) { + return new ValidationInfo("String to find is empty", myInputComboBox); + } + + if (myCbRegularExpressions != null && myCbRegularExpressions.isEnabled()) { + try { + boolean isCaseSensitive = myCbCaseSensitive != null && myCbCaseSensitive.isEnabled(); + Pattern pattern = + Pattern.compile(toFind, isCaseSensitive ? Pattern.MULTILINE : Pattern.MULTILINE | Pattern.CASE_INSENSITIVE); + if (pattern.matcher("").matches() && !toFind.endsWith("$") && !toFind.startsWith("^")) { + return new ValidationInfo(FindBundle.message("find.empty.match.regular.expression.error"), myInputComboBox); + } + } + catch (PatternSyntaxException e) { + return new ValidationInfo(FindBundle.message("find.invalid.regular.expression.error", toFind, e.getDescription()), myInputComboBox); + } + } + + final String mask = myFileFilter == null ? null : (String)myFileFilter.getSelectedItem(); + + if (mask != null) { + if (mask.length() == 0) { + return new ValidationInfo(FindBundle.message("find.filter.empty.file.mask.error"), myFileFilter); + } + else { + try { + FindInProjectUtil.createFileMaskRegExp(mask); // verify that the regexp compiles + } + catch (PatternSyntaxException ex) { + return new ValidationInfo(FindBundle.message("find.filter.invalid.file.mask.error", mask), myFileFilter); + } + } + } + return null; + } + + @Override + protected ValidationInfo doValidate() { + FindModel validateModel = (FindModel)myModel.clone(); + applyTo(validateModel, false); + + ValidationInfo result = getValidationInfo(validateModel); + + setOKStatus(result == null); + + return result; } public void doHelpAction() { @@ -768,7 +839,7 @@ class FindDialog extends DialogWrapper { public void consume(final VirtualFile[] files) { if (files.length != 0) { myDirectoryComboBox.setSelectedItem(files[0].getPresentableUrl()); - validateFindButton(); + //validateFindButton(); } } }); @@ -845,10 +916,12 @@ class FindDialog extends DialogWrapper { } private String getStringToFind() { - return (String)myInputComboBox.getEditor().getItem(); + String string = (String)myInputComboBox.getEditor().getItem(); + return string == null ? "" : string; } private String getStringToReplace() { - return (String)myReplaceComboBox.getEditor().getItem(); + String item = (String)myReplaceComboBox.getEditor().getItem(); + return item == null ? "" : item; } private String getDirectory() { @@ -886,27 +959,26 @@ class FindDialog extends DialogWrapper { } } - private void applyTo(FindModel model) { - FindSettings findSettings = FindSettings.getInstance(); + + + private void applyTo(FindModel model, boolean findAll) { + model.setCaseSensitive(myCbCaseSensitive.isSelected()); - findSettings.setCaseSensitive(myCbCaseSensitive.isSelected()); if (model.isReplaceState()) { model.setPreserveCase(myCbPreserveCase.isSelected()); - findSettings.setPreserveCase(myCbPreserveCase.isSelected()); } model.setWholeWordsOnly(myCbWholeWordsOnly.isSelected()); - findSettings.setWholeWordsOnly(myCbWholeWordsOnly.isSelected()); model.setInStringLiteralsOnly(myCbInStringLiteralsOnly.isSelected()); - findSettings.setInStringLiteralsOnly(myCbInStringLiteralsOnly.isSelected()); model.setInCommentsOnly(myCbInCommentsOnly.isSelected()); - findSettings.setInCommentsOnly(myCbInCommentsOnly.isSelected()); model.setRegularExpressions(myCbRegularExpressions.isSelected()); - findSettings.setRegularExpressions(myCbRegularExpressions.isSelected()); - model.setStringToFind(getStringToFind()); + String stringToFind = getStringToFind(); + if (stringToFind.length() > 0) { + model.setStringToFind(stringToFind); + } if (model.isReplaceState()){ model.setPromptOnReplace(true); @@ -920,11 +992,8 @@ class FindDialog extends DialogWrapper { if (!model.isMultipleFiles()){ model.setForward(myRbForward.isSelected()); - findSettings.setForward(myRbForward.isSelected()); model.setFromCursor(myRbFromCursor.isSelected()); - findSettings.setFromCursor(myRbFromCursor.isSelected()); model.setGlobal(myRbGlobal.isSelected()); - findSettings.setGlobal(myRbGlobal.isSelected()); } else{ if (myCbToOpenInNewTab != null){ @@ -942,7 +1011,6 @@ class FindDialog extends DialogWrapper { String directory = getDirectory(); model.setDirectoryName(directory == null ? "" : directory); model.setWithSubdirectories(myCbWithSubdirectories.isSelected()); - findSettings.setWithSubdirectories(myCbWithSubdirectories.isSelected()); } else if (myRbModule.isSelected()) { model.setModuleName((String)myModuleComboBox.getSelectedItem()); @@ -953,9 +1021,17 @@ class FindDialog extends DialogWrapper { model.setCustomScopeName(customScopeName); model.setCustomScope(selectedScope == null ? null : selectedScope); model.setCustomScope(true); - findSettings.setCustomScope(customScopeName); } } + + model.setFindAll(findAll); + + String mask = null; + if (useFileFilter!=null && useFileFilter.isSelected()) { + mask = (String)myFileFilter.getSelectedItem(); + } + model.setFileFilter(mask); + } @@ -1061,7 +1137,7 @@ class FindDialog extends DialogWrapper { setStringsToComboBox(FindSettings.getInstance().getRecentReplaceStrings(), myReplaceComboBox, myModel.getStringToReplace()); } updateControls(); - validateFindButton(); + } } From 2a412899d2a8c30d8c1b46c72d165386aeb45a5e Mon Sep 17 00:00:00 2001 From: andrey zaytsev Date: Tue, 25 Jan 2011 14:29:50 +0300 Subject: [PATCH 45/53] IDEA#64170: live-preview of search results in all find-dialogs. --- .../com/intellij/find/impl/FindDialog.java | 7 + .../intellij/find/impl/LiveOccurrence.java | 27 ++ .../com/intellij/find/impl/LivePreview.java | 421 ++++++++++++++++++ .../find/impl/LivePreviewController.java | 138 ++++++ .../find/impl/MomentoUserActivityWatcher.java | 31 ++ .../openapi/ui/popup/BalloonBuilder.java | 4 + .../com/intellij/ide/IdeTooltipManager.java | 3 +- .../src/com/intellij/ui/BalloonImpl.java | 17 +- .../ui/popup/BalloonPopupBuilderImpl.java | 16 +- 9 files changed, 658 insertions(+), 6 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/find/impl/LiveOccurrence.java create mode 100644 platform/lang-impl/src/com/intellij/find/impl/LivePreview.java create mode 100644 platform/lang-impl/src/com/intellij/find/impl/LivePreviewController.java create mode 100644 platform/lang-impl/src/com/intellij/find/impl/MomentoUserActivityWatcher.java diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java index 40ddea6db2b2..d8aae724b221 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java @@ -107,6 +107,9 @@ class FindDialog extends DialogWrapper { private JRadioButton myRbCustomScope; private ScopeChooserCombo myScopeCombo; + private LivePreviewController myLivePreviewController; + + public FindDialog(Project project, FindModel model, Runnable myOkHandler){ super(project, true); myProject = project; @@ -135,6 +138,7 @@ class FindDialog extends DialogWrapper { setOKButtonIcon(IconLoader.getIcon("/actions/find.png")); init(); initByModel(); + myLivePreviewController = new LivePreviewController(this, new LivePreview(myProject), getContentPane()); } @Override @@ -143,6 +147,9 @@ class FindDialog extends DialogWrapper { e.getKey().removeDocumentListener(e.getValue()); } myComboBoxListeners.clear(); + if (myLivePreviewController != null) { + myLivePreviewController.cleanUp(); + } super.dispose(); } diff --git a/platform/lang-impl/src/com/intellij/find/impl/LiveOccurrence.java b/platform/lang-impl/src/com/intellij/find/impl/LiveOccurrence.java new file mode 100644 index 000000000000..9297f07ecaeb --- /dev/null +++ b/platform/lang-impl/src/com/intellij/find/impl/LiveOccurrence.java @@ -0,0 +1,27 @@ +package com.intellij.find.impl; + +import com.intellij.openapi.util.TextRange; + +import java.util.ArrayList; +import java.util.Collection; + +public class LiveOccurrence { + private TextRange myPrimaryRange; + private Collection mySecondaryRanges = new ArrayList(); + + public TextRange getPrimaryRange() { + return myPrimaryRange; + } + + public Collection getSecondaryRanges() { + return mySecondaryRanges; + } + + public void setPrimaryRange(TextRange primaryRange) { + this.myPrimaryRange = primaryRange; + } + + public void setSecondaryRanges(Collection secondaryRanges) { + this.mySecondaryRanges = secondaryRanges; + } +} diff --git a/platform/lang-impl/src/com/intellij/find/impl/LivePreview.java b/platform/lang-impl/src/com/intellij/find/impl/LivePreview.java new file mode 100644 index 000000000000..3f70b91db5e1 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/find/impl/LivePreview.java @@ -0,0 +1,421 @@ +package com.intellij.find.impl; + + +import com.intellij.codeInsight.highlighting.HighlightManager; +import com.intellij.ide.IdeTooltipManager; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.editor.VisualPosition; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.event.VisibleAreaEvent; +import com.intellij.openapi.editor.event.VisibleAreaListener; +import com.intellij.openapi.editor.markup.CustomHighlighterRenderer; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.TextEditor; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.popup.Balloon; +import com.intellij.openapi.ui.popup.BalloonBuilder; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.awt.RelativePoint; +import com.intellij.util.Alarm; +import com.intellij.util.containers.HashSet; +import com.intellij.util.ui.PositionTracker; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.awt.*; +import java.util.*; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; + +public class LivePreview extends DocumentAdapter { + + private final Collection myHighlighters = new HashSet(); + private RangeHighlighter myCursorHighlighter; + private final List myVisibleAreaListenersToRemove = new ArrayList(); + + public interface Delegate { + @NotNull + List performSearchInBackgroundInReadAction(Editor editor); + + @Nullable + String getReplacementPreviewText(Editor editor, LiveOccurrence liveOccurrence); + } + + private static final int USER_ACTIVITY_TRIGGERING_DELAY = 300; + + private static final TextAttributes OTHER_TARGETS_ATTRIBUTES = new TextAttributes(Color.BLACK, Color.GREEN, null, null, 0); + private static final TextAttributes MAIN_TARGET_ATTRIBUTES = new TextAttributes(Color.BLACK, Color.YELLOW, null, null, 0); + + private final Alarm myLivePreviewAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); + + private final Project myProject; + private Editor myEditor; + + private Delegate myDelegate; + + private LiveOccurrence myCursor; + private List mySearchResults; + + private Balloon myReplacementBalloon; + + public LivePreview(Project project) { + this.myProject = project; + updateEditorReference(); + } + + public Delegate getDelegate() { + return myDelegate; + } + + public void setDelegate(Delegate delegate) { + this.myDelegate = delegate; + } + + @Nullable + public Editor updateEditorReference() { + if (myProject == null) return null; + FileEditorManagerEx instanceEx = FileEditorManagerEx.getInstanceEx(myProject); + if (instanceEx != null) { + VirtualFile currentFile = instanceEx.getCurrentFile(); + if (currentFile != null) { + FileEditor[] editors = instanceEx.getEditors(currentFile); + if (editors.length > 0) { + FileEditor fileEditor = editors[0]; + boolean focusedFound = false; + for (FileEditor e : editors) { + if (e instanceof TextEditor && ((TextEditor)e).getEditor().getContentComponent().hasFocus()) { + fileEditor = e; + focusedFound = true; + } + } + boolean needToUpdate = true; + if (!focusedFound) { + for (FileEditor e : editors) { + if (e instanceof TextEditor && ((TextEditor)e).getEditor() == myEditor) { + needToUpdate = false; + } + } + } + if (needToUpdate && fileEditor instanceof TextEditor) { + Editor editor1 = ((TextEditor) fileEditor).getEditor(); + if (editor1 != myEditor) { + cleanUp(); + } + if (myEditor != null) { + myEditor.getDocument().removeDocumentListener(this); + } + myEditor = editor1; + myEditor.getDocument().addDocumentListener(this); + } + } else { + myEditor = null; + } + } else { + myEditor = null; + } + } + return myEditor; + } + + @Override + public void documentChanged(DocumentEvent e) { + update(); + } + + public void update() { + myLivePreviewAlarm.cancelAllRequests(); + if (updateEditorReference() != null) { + myLivePreviewAlarm.addRequest(new Runnable() { + @Override + public void run() { + updateInBackground(); + } + }, USER_ACTIVITY_TRIGGERING_DELAY); + } + } + + public void cleanUp() { + if (myReplacementBalloon != null) { + myReplacementBalloon.hide(); + } + if (myEditor != null) { + for (VisibleAreaListener visibleAreaListener : myVisibleAreaListenersToRemove) { + myEditor.getScrollingModel().removeVisibleAreaListener(visibleAreaListener); + } + myVisibleAreaListenersToRemove.clear(); + for (RangeHighlighter h : myHighlighters) { + HighlightManager.getInstance(myProject).removeSegmentHighlighter(myEditor, h); + } + if (myCursorHighlighter != null) { + HighlightManager.getInstance(myProject).removeSegmentHighlighter(myEditor, myCursorHighlighter); + myCursorHighlighter = null; + } + } + } + + private void updateInBackground() { + if (myDelegate == null) return; + final TextRange oldCursorRange = myCursor != null ? myCursor.getPrimaryRange() : null; + mySearchResults = performSearchInBackground(); + Collections.sort(mySearchResults, new Comparator() { + @Override + public int compare(LiveOccurrence liveOccurrence, LiveOccurrence liveOccurence1) { + return liveOccurrence.getPrimaryRange().getStartOffset() - liveOccurence1.getPrimaryRange().getStartOffset(); + } + }); + if (mySearchResults != null) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + cleanUp(); + highlightUsages(oldCursorRange); + } + }); + } + } + + private List performSearchInBackground() { + final AtomicReference> occurrences = new AtomicReference>(); + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + occurrences.set(myDelegate.performSearchInBackgroundInReadAction(myEditor)); + } + }); + return occurrences.get(); + } + + private void highlightUsages(TextRange oldCursorRange) { + if (myEditor == null) return; + LiveOccurrence firstVisibleOccurrence = null; + LiveOccurrence firstOccurrence = null; + int offset = Integer.MAX_VALUE; + for (LiveOccurrence o : mySearchResults) { + if (insideVisibleArea(myEditor, o.getPrimaryRange())) { + if (firstVisibleOccurrence == null || o.getPrimaryRange().getStartOffset() < firstVisibleOccurrence.getPrimaryRange().getStartOffset()) { + firstVisibleOccurrence = o; + } + } + if (o.getPrimaryRange().getStartOffset() < offset) { + offset = o.getPrimaryRange().getStartOffset(); + firstOccurrence = o; + } + + for (TextRange textRange : o.getSecondaryRanges()) { + highlightRange(textRange, OTHER_TARGETS_ATTRIBUTES, myHighlighters); + } + highlightRange(o.getPrimaryRange(), MAIN_TARGET_ATTRIBUTES, myHighlighters); + } + + if (!tryToRepairOldCursor(oldCursorRange)) { + setCursor(firstVisibleOccurrence != null ? firstVisibleOccurrence : firstOccurrence); + } + } + + private boolean tryToRepairOldCursor(TextRange oldCursorRange) { + if (oldCursorRange == null) return false; + LiveOccurrence mayBeOldCursor = null; + for (LiveOccurrence searchResult : mySearchResults) { + if (searchResult.getPrimaryRange().intersects(oldCursorRange)) { + mayBeOldCursor = searchResult; + break; + } + } + if (mayBeOldCursor != null && insideVisibleArea(myEditor, mayBeOldCursor.getPrimaryRange())) { + setCursor(mayBeOldCursor); + return true; + } + return false; + } + + @Nullable + private LiveOccurrence prevOccurrence(LiveOccurrence o) { + if (mySearchResults == null) return null; + for (int i = 0; i < mySearchResults.size(); ++i) { + if (o == mySearchResults.get(i)) { + if (i > 0) { + return mySearchResults.get(i-1); + } + } + } + return null; + } + + @Nullable + private LiveOccurrence nextOccurrence(LiveOccurrence o) { + if (mySearchResults == null) return null; + boolean found = false; + for (LiveOccurrence occurrence : mySearchResults) { + if (found) { + return occurrence; + } + if (o == occurrence) { + found = true; + } + } + return null; + } + + public void prevOccurrence() { + LiveOccurrence prev = prevOccurrence(myCursor); + if (prev == null && !mySearchResults.isEmpty()) { + prev = mySearchResults.get(mySearchResults.size()-1); + } + moveCursorTo(prev); + } + + public void nextOccurrence() { + LiveOccurrence next = nextOccurrence(myCursor); + if (next == null && !mySearchResults.isEmpty()) { + next = mySearchResults.get(0); + } + moveCursorTo(next); + } + + public void moveCursorTo(LiveOccurrence next) { + if (next != null) { + setCursor(next); + } else { + showReplacementPreview(); + } + } + + private void setCursor(LiveOccurrence liveOccurrence) { + hideBalloon(); + myCursor = liveOccurrence; + + if (myCursorHighlighter != null) { + HighlightManager.getInstance(myProject).removeSegmentHighlighter(myEditor, myCursorHighlighter); + myCursorHighlighter = null; + } + if (myCursor != null) { + ArrayList dummy = new ArrayList(); + highlightRange(myCursor.getPrimaryRange(), new TextAttributes(null, null, null, null, 0), dummy); + if (!dummy.isEmpty()) { + myCursorHighlighter = dummy.get(0); + myCursorHighlighter.setCustomRenderer(new CustomHighlighterRenderer() { + @Override + public void paint(Editor editor, RangeHighlighter highlighter, Graphics g) { + Graphics2D g2d = (Graphics2D)g; + VisualPosition startVp = editor.offsetToVisualPosition(highlighter.getStartOffset()); + VisualPosition endVp = editor.offsetToVisualPosition(highlighter.getEndOffset()); + Point start = editor.visualPositionToXY(startVp); + Point end = editor.visualPositionToXY(endVp); + g2d.setColor(Color.YELLOW); + Point startP = new Point(start.x-5, start.y-5); + int lineHeight = editor.getLineHeight(); + Point endP = new Point(start.x-5, end.y+ lineHeight +10); + g2d.setPaint(new GradientPaint(startP, Color.YELLOW, endP, new Color(255, 200, 0))); + + g2d.fillRoundRect(startP.x, startP.y, + end.x - start.x+10, lineHeight +10, 10, 10); + g2d.setColor(Color.GRAY); + g2d.drawRoundRect(start.x - 5, start.y - 5, + end.x - start.x + 10, lineHeight + 10, 10, 10); + } + }); + } + + if (!insideVisibleArea(myEditor, myCursor.getPrimaryRange())) { + myEditor.getScrollingModel().scrollTo(myEditor.offsetToLogicalPosition(myCursor.getPrimaryRange().getStartOffset()), + ScrollType.CENTER); + myEditor.getScrollingModel().runActionOnScrollingFinished(new Runnable() { + @Override + public void run() { + showReplacementPreview(); + } + }); + } else { + showReplacementPreview(); + } + } + } + + private void showReplacementPreview() { + hideBalloon(); + if (myDelegate != null && myCursor != null) { + String replacementPreviewText = myDelegate.getReplacementPreviewText(myEditor, myCursor); + if (replacementPreviewText != null) { + + JLabel balloonContent = new JLabel(replacementPreviewText); + balloonContent.setForeground(Color.WHITE); + + BalloonBuilder balloonBuilder = JBPopupFactory.getInstance().createBalloonBuilder(balloonContent); + balloonBuilder.setFadeoutTime(0); + balloonBuilder.setFillColor(IdeTooltipManager.GRAPHITE_COLOR); + balloonBuilder.setAnimationCycle(0); + balloonBuilder.setHideOnClickOutside(false); + balloonBuilder.setHideOnKeyOutside(false); + balloonBuilder.setHideOnAction(false); + myReplacementBalloon = balloonBuilder.createBalloon(); + final int startOffset = myCursor.getPrimaryRange().getStartOffset(); + final int endOffset = myCursor.getPrimaryRange().getEndOffset(); + + myReplacementBalloon.show(new PositionTracker(myEditor.getContentComponent()) { + @Override + public RelativePoint recalculateLocation(final Balloon object) { + Point startPoint = myEditor.visualPositionToXY(myEditor.offsetToVisualPosition(startOffset)); + Point endPoint = myEditor.visualPositionToXY(myEditor.offsetToVisualPosition(endOffset)); + Point point = new Point((startPoint.x + endPoint.x)/2, startPoint.y); + if (!insideVisibleArea(myEditor, myCursor.getPrimaryRange())) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + object.hide(); + } + }); + + VisibleAreaListener visibleAreaListener = new VisibleAreaListener() { + @Override + public void visibleAreaChanged(VisibleAreaEvent e) { + if (insideVisibleArea(myEditor, myCursor.getPrimaryRange())) { + showReplacementPreview(); + final VisibleAreaListener visibleAreaListener = this; + myEditor.getScrollingModel().removeVisibleAreaListener(visibleAreaListener); + myVisibleAreaListenersToRemove.remove(visibleAreaListener); + } + } + }; + myEditor.getScrollingModel().addVisibleAreaListener(visibleAreaListener); + myVisibleAreaListenersToRemove.add(visibleAreaListener); + + } + return new RelativePoint(myEditor.getContentComponent(), point); + } + }, Balloon.Position.above); + } + } + } + + private void hideBalloon() { + if (myReplacementBalloon != null) { + myReplacementBalloon.hide(); + myReplacementBalloon = null; + } + } + + private void highlightRange(TextRange textRange, TextAttributes attributes, Collection highlighters) { + HighlightManager highlightManager = HighlightManager.getInstance(myProject); + if (highlightManager != null) { + highlightManager.addRangeHighlight(myEditor, + textRange.getStartOffset(), textRange.getEndOffset(), + attributes, true, highlighters); + } + } + + private static boolean insideVisibleArea(Editor e, TextRange r) { + Rectangle visibleArea = e.getScrollingModel().getVisibleArea(); + Point point = e.logicalPositionToXY(e.offsetToLogicalPosition(r.getStartOffset())); + + return visibleArea.contains(point); + } +} diff --git a/platform/lang-impl/src/com/intellij/find/impl/LivePreviewController.java b/platform/lang-impl/src/com/intellij/find/impl/LivePreviewController.java new file mode 100644 index 000000000000..b8d787f19919 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/find/impl/LivePreviewController.java @@ -0,0 +1,138 @@ +package com.intellij.find.impl; + +import com.intellij.find.FindManager; +import com.intellij.find.FindModel; +import com.intellij.find.FindResult; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.UserActivityListener; +import com.intellij.ui.UserActivityWatcher; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class LivePreviewController implements LivePreview.Delegate, UserActivityListener { + + private static final String EMPTY_STRING_DISPLAY_TEXT = ""; + private final FindDialog myFindDialog; + private final LivePreview myLivePreview; + private final UserActivityWatcher myWatcher = new MomentoUserActivityWatcher(); + private int myMatchesLimit = 100; + + public LivePreviewController(FindDialog findDialog, LivePreview livePreview, Component toWatch) { + myFindDialog = findDialog; + myLivePreview = livePreview; + myLivePreview.setDelegate(this); + myWatcher.register(toWatch); + myWatcher.addUserActivityListener(this); + myFindDialog.getWindow().addWindowFocusListener(new WindowFocusListener() { + @Override + public void windowGainedFocus(WindowEvent windowEvent) { + myLivePreview.update(); + } + + @Override + public void windowLostFocus(WindowEvent windowEvent) { + } + }); + + JComponent contentPane = (JComponent)findDialog.getContentPane(); + new AnAction() { + + @Override + public void actionPerformed(AnActionEvent e) { + myLivePreview.nextOccurrence(); + } + }.registerCustomShortcutSet(KeyEvent.VK_F3, 0, contentPane); + + new AnAction() { + + @Override + public void actionPerformed(AnActionEvent e) { + myLivePreview.prevOccurrence(); + } + }.registerCustomShortcutSet(KeyEvent.VK_F3, KeyEvent.SHIFT_MASK, contentPane); + } + + public void cleanUp() { + myWatcher.removeUserActivityListener(this); + myLivePreview.cleanUp(); + } + + public void setMatchesLimit(int matchesLimit) { + myMatchesLimit = matchesLimit; + } + + public int getMatchesLimit() { + return myMatchesLimit; + } + + @NotNull + @Override + public List performSearchInBackgroundInReadAction(Editor editor) { + ArrayList occurrences = new ArrayList(); + FindModel currentModel = myFindDialog.getCurrentModel(); + if (currentModel != null) { + int offset = 0; + VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(editor.getDocument()); + ArrayList results = new ArrayList(); + + while (true) { + FindManager findManager = FindManager.getInstance(editor.getProject()); + FindResult result = findManager.findString(editor.getDocument().getCharsSequence(), offset, currentModel, virtualFile); + if (!result.isStringFound()) break; + int newOffset = result.getEndOffset(); + if (offset == newOffset) break; + offset = newOffset; + results.add(result); + + if (results.size() > myMatchesLimit) break; + } + if (results.size() < myMatchesLimit) { + findResultsToOccurrences(results, occurrences); + } + } + return occurrences; + } + + @Override + public String getReplacementPreviewText(Editor editor, LiveOccurrence liveOccurrence) { + String foundString = editor.getDocument().getText(liveOccurrence.getPrimaryRange()); + String documentText = editor.getDocument().getText(); + FindModel currentModel = myFindDialog.getCurrentModel(); + String stringToReplace = null; + + if (currentModel != null) { + if (currentModel.isReplaceState()) { + FindManager findManager = FindManager.getInstance(editor.getProject()); + stringToReplace = findManager.getStringToReplace(foundString, currentModel, + liveOccurrence.getPrimaryRange().getStartOffset(), documentText); + if (stringToReplace != null && stringToReplace.isEmpty()) { + stringToReplace = EMPTY_STRING_DISPLAY_TEXT; + } + } + } + return stringToReplace; + } + + private static void findResultsToOccurrences(ArrayList results, Collection occurrences) { + for (FindResult r : results) { + LiveOccurrence occurrence = new LiveOccurrence(); + occurrence.setPrimaryRange(r); + occurrences.add(occurrence); + } + } + + @Override + public void stateChanged() { + myLivePreview.update(); + } +} diff --git a/platform/lang-impl/src/com/intellij/find/impl/MomentoUserActivityWatcher.java b/platform/lang-impl/src/com/intellij/find/impl/MomentoUserActivityWatcher.java new file mode 100644 index 000000000000..010c5fdbd46d --- /dev/null +++ b/platform/lang-impl/src/com/intellij/find/impl/MomentoUserActivityWatcher.java @@ -0,0 +1,31 @@ +package com.intellij.find.impl; + +import com.intellij.ui.UserActivityWatcher; + +import java.awt.*; +import java.util.HashSet; +import java.util.Set; + + +public class MomentoUserActivityWatcher extends UserActivityWatcher { + + Set components = new HashSet(); + + @Override + protected void processComponent(Component parentComponent) { + if (!components.contains(parentComponent)) { + super.processComponent(parentComponent); + components.add(parentComponent); + } + } + + @Override + protected void unprocessComponent(Component component) { + components.remove(component); + super.unprocessComponent(component); + } + + public boolean isWatched(Component c) { + return components.contains(c); + } +} diff --git a/platform/platform-api/src/com/intellij/openapi/ui/popup/BalloonBuilder.java b/platform/platform-api/src/com/intellij/openapi/ui/popup/BalloonBuilder.java index 17fec4ebed64..1bbaf6010828 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/popup/BalloonBuilder.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/popup/BalloonBuilder.java @@ -69,4 +69,8 @@ public interface BalloonBuilder { @NotNull BalloonBuilder setPositionChangeYShift(int positionChangeYShift); + + boolean isHideOnAction(); + + BalloonBuilder setHideOnAction(boolean hideOnAction); } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java b/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java index 9dcee560e5ea..4238707e2b61 100644 --- a/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java +++ b/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java @@ -53,6 +53,7 @@ import java.awt.event.MouseEvent; public class IdeTooltipManager implements ApplicationComponent, AWTEventListener { + public static final Color GRAPHITE_COLOR = new Color(100, 100, 100, 230); private RegistryValue myIsEnabled; private Component myCurrentComponent; @@ -304,7 +305,7 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener } public Color getTextBackground(boolean awtTooltip) { - return useGraphite(awtTooltip) ? new Color(100, 100, 100, 230) : UIUtil.getToolTipBackground(); + return useGraphite(awtTooltip) ? GRAPHITE_COLOR : UIUtil.getToolTipBackground(); } public String getUlImg(boolean awtTooltip) { diff --git a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java index c7f115096577..8cba5a58fec3 100644 --- a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java @@ -197,6 +197,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi private final JComponent myContent; private final boolean myHideOnMouse; private final boolean myHideOnKey; + private boolean myHideOnAction; private final boolean myEnableCloseButton; private final Icon myCloseButton = IconLoader.getIcon("/general/balloonClose.png"); @@ -205,6 +206,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi Color fillColor, boolean hideOnMouse, boolean hideOnKey, + boolean hideOnAction, boolean showPointer, boolean enableCloseButton, long fadeoutTime, @@ -220,6 +222,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi myContent = content; myHideOnMouse = hideOnMouse; myHideOnKey = hideOnKey; + myHideOnAction = hideOnAction; myShowPointer = showPointer; myEnableCloseButton = enableCloseButton; myHideOnFrameResize = hideOnFrameResize; @@ -380,6 +383,14 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi Toolkit.getDefaultToolkit().addAWTEventListener(myAwtActivityListener, MouseEvent.MOUSE_EVENT_MASK | MouseEvent.MOUSE_MOTION_EVENT_MASK | KeyEvent.KEY_EVENT_MASK); + ActionManager.getInstance().addAnActionListener(new AnActionListener.Adapter() { + @Override + public void beforeActionPerformed(AnAction action, DataContext dataContext, AnActionEvent event) { + if (myHideOnAction) { + hide(); + } + } + }, this); } private Rectangle getRecForPosition(Position position, boolean adjust) { @@ -462,13 +473,13 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi } myAnimator = new Animator("Balloon", 10, myAnimationCycle, false, 0, 1, forward) { public void paintNow(final float frame, final float totalFrames, final float cycle) { - if (myComp.getParent() == null) return; + if (myComp == null || myComp.getParent() == null) return; myComp.setAlpha(frame / totalFrames); } @Override protected void paintCycleEnd() { - if (myComp.getParent() == null) return; + if (myComp == null || myComp.getParent() == null) return; if (isForward()) { myComp.clear(); @@ -1230,7 +1241,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi //pane.setBorder(new LineBorder(Color.blue)); - balloon.set(new BalloonImpl(new JLabel("FUCK"), Color.black, MessageType.ERROR.getPopupBackground(), true, true, true, true, 0, true, null, false, 500, 5, 0, 0)); + balloon.set(new BalloonImpl(new JLabel("FUCK"), Color.black, MessageType.ERROR.getPopupBackground(), true, true, true, true, true, 0, true, null, false, 500, 5, 0, 0)); balloon.get().setShowPointer(true); if (e.isShiftDown()) { diff --git a/platform/platform-impl/src/com/intellij/ui/popup/BalloonPopupBuilderImpl.java b/platform/platform-impl/src/com/intellij/ui/popup/BalloonPopupBuilderImpl.java index 34b814462429..8023a052d83d 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/BalloonPopupBuilderImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/BalloonPopupBuilderImpl.java @@ -46,11 +46,23 @@ public class BalloonPopupBuilderImpl implements BalloonBuilder { private int myCalloutShift; private int myPositionChangeXShift; private int myPositionChangeYShift; + private boolean myHideOnAction = true; public BalloonPopupBuilderImpl(@NotNull final JComponent content) { myContent = content; } + @Override + public boolean isHideOnAction() { + return myHideOnAction; + } + + @Override + public BalloonBuilder setHideOnAction(boolean hideOnAction) { + myHideOnAction = hideOnAction; + return this; + } + @NotNull public BalloonBuilder setPreferredPosition(final Balloon.Position position) { myPrefferedPosition = position; @@ -122,7 +134,7 @@ public class BalloonPopupBuilderImpl implements BalloonBuilder { @NotNull public Balloon createBalloon() { - return new BalloonImpl(myContent, myBorder, myFill, myHideOnMouseOutside, myHideOnKeyOutside, myShowCalllout, myCloseButtonEnabled, myFadeoutTime, myHideOnFrameResize, myClickHandler, myCloseOnClick, myAnimationCycle, + return new BalloonImpl(myContent, myBorder, myFill, myHideOnMouseOutside, myHideOnKeyOutside, myHideOnAction, myShowCalllout, myCloseButtonEnabled, myFadeoutTime, myHideOnFrameResize, myClickHandler, myCloseOnClick, myAnimationCycle, myCalloutShift, myPositionChangeXShift, myPositionChangeYShift); } @@ -145,4 +157,4 @@ public class BalloonPopupBuilderImpl implements BalloonBuilder { myCalloutShift = length; return this; } -} \ No newline at end of file +} From 96ec4da8300d55f96515bc89d631b6898c0a191e Mon Sep 17 00:00:00 2001 From: anna Date: Tue, 25 Jan 2011 13:02:39 +0100 Subject: [PATCH 46/53] rename: fix rename over read-only files --- .../rename/PsiElementRenameHandler.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/PsiElementRenameHandler.java b/platform/lang-impl/src/com/intellij/refactoring/rename/PsiElementRenameHandler.java index a089ec7ba528..9f184dab1168 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/PsiElementRenameHandler.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/PsiElementRenameHandler.java @@ -99,10 +99,6 @@ public class PsiElementRenameHandler implements RenameHandler { if (element == null) return ""; if (!(element instanceof PsiFile) && CollectHighlightsUtil.isOutsideSourceRootJavaFile(element.getContainingFile())) return ""; - if (!element.isWritable()) { - return RefactoringBundle.getCannotRefactorMessage("This element cannot be renamed."); - } - boolean hasRenameProcessor = RenamePsiElementProcessor.forElement(element) != RenamePsiElementProcessor.DEFAULT; boolean hasWritableMetaData = element instanceof PsiMetaOwner && ((PsiMetaOwner)element).getMetaData() instanceof PsiWritableMetaData; @@ -110,9 +106,15 @@ public class PsiElementRenameHandler implements RenameHandler { return RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("error.wrong.caret.position.symbol.to.rename")); } - if (!PsiManager.getInstance(project).isInProject(element) && element.isPhysical()) { - return RefactoringBundle - .getCannotRefactorMessage(RefactoringBundle.message("error.out.of.project.element", UsageViewUtil.getType(element))); + if (!PsiManager.getInstance(project).isInProject(element)) { + if (element.isPhysical()) { + return RefactoringBundle + .getCannotRefactorMessage(RefactoringBundle.message("error.out.of.project.element", UsageViewUtil.getType(element))); + } + + if (!element.isWritable()) { + return RefactoringBundle.getCannotRefactorMessage("This element cannot be renamed."); + } } if (InjectedLanguageUtil.isInInjectedLanguagePrefixSuffix(element)) { From 3502c44e76c688ab886422637ef3ed7297bb0732 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Tue, 25 Jan 2011 15:47:45 +0300 Subject: [PATCH 47/53] IDEA-63313 CamelHump immediately after digit is not taken into account 1. Corrected 'camel humps' selection when target work contains digit just before the 'hump'; 2. Corresponding test is added; --- .../intellij/openapi/editor/actions/EditorActionUtil.java | 8 ++++++-- .../testFramework/LightPlatformCodeInsightTestCase.java | 8 ++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java index ecdaca94248f..a3f1a005670d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java @@ -165,9 +165,9 @@ public class EditorActionUtil { if (isCamel) { if (firstIsIdentifierPart && secondIsIdentifierPart && - (Character.isLowerCase(prev) && Character.isUpperCase(current) || + (isLowerCaseOrDigit(prev) && Character.isUpperCase(current) || prev == '_' && current != '_' || - Character.isUpperCase(prev) && Character.isUpperCase(current) && Character.isLowerCase(next))) { + Character.isUpperCase(prev) && Character.isUpperCase(current) && isLowerCaseOrDigit(next))) { return true; } } @@ -175,6 +175,10 @@ public class EditorActionUtil { return (Character.isWhitespace(prev) || firstIsIdentifierPart) && !Character.isWhitespace(current) && !secondIsIdentifierPart; } + + private static boolean isLowerCaseOrDigit(char c) { + return Character.isLowerCase(c) || Character.isDigit(c); + } public static boolean isWordEnd(CharSequence text, int offset, boolean isCamel) { char prev = offset > 0 ? text.charAt(offset - 1) : 0; diff --git a/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java b/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java index 298b52ea9311..9f8487354b82 100644 --- a/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java @@ -492,6 +492,14 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest doAction(IdeActions.ACTION_EDITOR_PASTE); } + protected static void moveCaretToPreviousWordWithSelection() { + doAction("EditorPreviousWordWithSelection"); + } + + protected static void moveCaretToNextWordWithSelection() { + doAction("EditorNextWordWithSelection"); + } + protected static void lineComment() { new CommentByLineCommentHandler().invoke(getProject(), getEditor(), getFile()); } From e067a6cc5d385b738649ab6ef24e87982c6a0f85 Mon Sep 17 00:00:00 2001 From: "Rustam.Vishnyakov" Date: Tue, 25 Jan 2011 15:53:14 +0300 Subject: [PATCH 48/53] JavaScript library files scope for completion - minor but important fixes --- .../scriptingContext/ScriptingLibraryMappings.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java index 1563f90cb3f1..c38de1ac7e61 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java @@ -406,16 +406,14 @@ public class ScriptingLibraryMappings extends LanguagePerFileMappings(); - for (CompoundLibrary container : myCompoundLibMap.values()) { - for (ScriptingLibraryTable.LibraryModel libModel : container.getLibraries()) { - myProjectLibFiles.addAll(Arrays.asList(libModel.getSourceFiles())); - myProjectLibFiles.addAll(Arrays.asList(libModel.getCompactFiles())); + for (ScriptingLibraryTable.LibraryModel container : getMappings().values()) { + if (container instanceof CompoundLibrary) { + for (ScriptingLibraryTable.LibraryModel libModel : ((CompoundLibrary)container).getLibraries()) { + myProjectLibFiles.addAll(Arrays.asList(libModel.getSourceFiles())); + myProjectLibFiles.addAll(Arrays.asList(libModel.getCompactFiles())); + } } } - for (ScriptingLibraryTable.LibraryModel libModel : myProjectLibs.getLibraries()) { - myProjectLibFiles.addAll(Arrays.asList(libModel.getSourceFiles())); - myProjectLibFiles.addAll(Arrays.asList(libModel.getCompactFiles())); - } } public Set getProjectLibraryFiles() { From 71b015b334264743626883aef487ef662affc0f0 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Jan 2011 12:39:59 +0100 Subject: [PATCH 49/53] a pretty domChildrenDescription presentable name in the doc --- .../psi/impl/DefaultPomTargetDescriptionProvider.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/DefaultPomTargetDescriptionProvider.java b/platform/lang-impl/src/com/intellij/psi/impl/DefaultPomTargetDescriptionProvider.java index cd9bd8172a27..278bec95cd4e 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/DefaultPomTargetDescriptionProvider.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/DefaultPomTargetDescriptionProvider.java @@ -35,14 +35,19 @@ public class DefaultPomTargetDescriptionProvider extends PomDescriptionProvider if (element instanceof PsiElement) return null; if (location == UsageViewTypeLocation.INSTANCE) { - return TypeNameManager.getTypeName(element.getClass()); + return getTypeName(element); } if (location == UsageViewNodeTextLocation.INSTANCE) { - return TypeNameManager.getTypeName(element.getClass()) + " " + StringUtil.notNullize(element instanceof PomNamedTarget ? ((PomNamedTarget)element).getName() : null, "''"); + return getTypeName(element) + " " + StringUtil.notNullize(element instanceof PomNamedTarget ? ((PomNamedTarget)element).getName() : null, "''"); } if (location instanceof HighlightUsagesDescriptionLocation) { - return TypeNameManager.getTypeName(element.getClass()); + return getTypeName(element); } return null; } + + private static String getTypeName(PomTarget element) { + final String s = TypeNameManager._getTypeName(element.getClass()); + return s == null ? "Element" : s; + } } From 9e239e6d76ed4063167c5e092c8e11bf4ffd363b Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Jan 2011 13:52:15 +0100 Subject: [PATCH 50/53] don't let groovy's type inference go exponential because of deeply nested generics: erase types when checking dfa state equality (IDEA-64296) --- .../psi/dataFlow/types/TypesSemilattice.java | 3 ++- .../groovy/lang/GroovyHighlightingTest.java | 10 ++++++++ .../VeryLongDfaWithComplexGenerics.groovy | 25 +++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 plugins/groovy/testdata/highlighting/VeryLongDfaWithComplexGenerics.groovy diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/types/TypesSemilattice.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/types/TypesSemilattice.java index c85d8486118f..74e665d30fef 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/types/TypesSemilattice.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/types/TypesSemilattice.java @@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.lang.psi.dataFlow.types; import com.intellij.psi.PsiManager; import com.intellij.psi.PsiType; +import com.intellij.psi.util.TypeConversionUtil; import com.intellij.util.containers.HashMap; import org.jetbrains.plugins.groovy.lang.psi.dataFlow.Semilattice; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; @@ -72,7 +73,7 @@ public class TypesSemilattice implements Semilattice> { if (t1 != null || t2 != null) return false; } else { - if (!t1.equals(t2)) return false; + if (!TypeConversionUtil.erasure(t1).equals(TypeConversionUtil.erasure(t2))) return false; } } return true; diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java index b9f3f55187f0..e2693ef2ab23 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java @@ -12,6 +12,7 @@ import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.testFramework.IdeaTestUtil; import com.intellij.testFramework.LightProjectDescriptor; import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; @@ -288,6 +289,15 @@ public class GroovyHighlightingTest extends LightCodeInsightFixtureTestCase { public void testSOEInFieldDeclarations() {doTest();} + public void testVeryLongDfaWithComplexGenerics() { + IdeaTestUtil.assertTiming("", 10000, 1, new Runnable() { + @Override + public void run() { + doTest(new GroovyAssignabilityCheckInspection(), new UnusedDefInspection()); + } + }); + } + public void testWrongAnnotation() {doTest();} public void testAmbiguousMethods() { diff --git a/plugins/groovy/testdata/highlighting/VeryLongDfaWithComplexGenerics.groovy b/plugins/groovy/testdata/highlighting/VeryLongDfaWithComplexGenerics.groovy new file mode 100644 index 000000000000..a506027b33d0 --- /dev/null +++ b/plugins/groovy/testdata/highlighting/VeryLongDfaWithComplexGenerics.groovy @@ -0,0 +1,25 @@ +class TroubleCase { + + private Foo fooBar; + private Foo fooBaz; + + private void troubleMethod(boolean b) { + def icDao = (b?fooBaz:fooBar); + + for(Object x: new ArrayList()) { + } + + } +} + +public interface Foo {} +public class Bar implements Cloneable, Zoo {} +public interface Zoo, FM extends Hoo> {} +public interface Hoo {} +public class Baz implements Cloneable, Zoo {} +public class Goo {} +public class Too implements Hoo {} +public class Coo implements Serializable, Cloneable, Hoo {} +public class Woo implements Serializable, Cloneable, Hoo {} +public class Yoo implements Serializable, Cloneable, Hoo {} +public class Doo {} \ No newline at end of file From cd2f20719a516ce622225847feb11842b49df48c Mon Sep 17 00:00:00 2001 From: nik Date: Tue, 25 Jan 2011 16:43:36 +0300 Subject: [PATCH 51/53] xdebugger: added option to show 'debug' tool window only when debug process is suspended --- .../intellij/xdebugger/XDebuggerManager.java | 11 +++- .../xdebugger/impl/XDebugSessionImpl.java | 56 ++++++++++++++----- .../xdebugger/impl/XDebuggerManagerImpl.java | 23 +++++--- 3 files changed, 67 insertions(+), 23 deletions(-) diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerManager.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerManager.java index bb9e8432e9e0..53336a09bb64 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerManager.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerManager.java @@ -21,7 +21,6 @@ import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.ProgramRunner; import com.intellij.execution.ui.ExecutionConsole; import com.intellij.execution.ui.RunContentDescriptor; -import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import com.intellij.xdebugger.breakpoints.XBreakpointManager; import org.jetbrains.annotations.NotNull; @@ -71,4 +70,14 @@ public abstract class XDebuggerManager { @NotNull public abstract XDebugSession startSessionAndShowTab(@NotNull String sessionName, @Nullable RunContentDescriptor contentToReuse, @NotNull XDebugProcessStarter starter) throws ExecutionException; + + /** + * Start a new debugging session and open 'Debug' tool window + * @param sessionName title of 'Debug' tool window + * @param showToolWindowOnSuspendOnly if {@code true} 'Debug' tool window won't be shown until debug process is suspended on a breakpoint + */ + @NotNull + public abstract XDebugSession startSessionAndShowTab(@NotNull String sessionName, @Nullable RunContentDescriptor contentToReuse, + boolean showToolWindowOnSuspendOnly, + @NotNull XDebugProcessStarter starter) throws ExecutionException; } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java index b9124eb339f1..147c26d606b9 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java @@ -15,7 +15,9 @@ */ package com.intellij.xdebugger.impl; +import com.intellij.execution.ExecutionManager; import com.intellij.execution.configurations.RunProfile; +import com.intellij.execution.executors.DefaultDebugExecutor; import com.intellij.execution.filters.HyperlinkInfo; import com.intellij.execution.filters.OpenFileHyperlinkInfo; import com.intellij.execution.process.ProcessHandler; @@ -74,27 +76,30 @@ public class XDebugSessionImpl implements XDebugSession { private MyDependentBreakpointListener myDependentBreakpointListener; private String mySessionName; private XDebugSessionTab mySessionTab; + private XDebugSessionData mySessionData; private final EventDispatcher myDispatcher = EventDispatcher.create(XDebugSessionListener.class); private Project myProject; private @Nullable ExecutionEnvironment myEnvironment; private ProgramRunner myRunner; private boolean myStopped; private boolean myPauseActionSupported; + private boolean myShowTabOnSuspend; public XDebugSessionImpl(final @NotNull ExecutionEnvironment env, final @NotNull ProgramRunner runner, XDebuggerManagerImpl debuggerManager) { - this(env, runner, debuggerManager, env.getRunProfile().getName()); + this(env, runner, debuggerManager, env.getRunProfile().getName(), false); } public XDebugSessionImpl(final @Nullable ExecutionEnvironment env, final @Nullable ProgramRunner runner, XDebuggerManagerImpl debuggerManager, - final @NotNull String sessionName) { + final @NotNull String sessionName, final boolean showTabOnSuspend) { myEnvironment = env; myRunner = runner; mySessionName = sessionName; myDebuggerManager = debuggerManager; + myShowTabOnSuspend = showTabOnSuspend; myProject = debuggerManager.getProject(); ValueLookupManager.getInstance(myProject).startListening(); } @@ -106,16 +111,27 @@ public class XDebugSessionImpl implements XDebugSession { @NotNull public RunContentDescriptor getRunContentDescriptor() { - LOG.assertTrue(mySessionTab != null, "Call init() first!"); + assertSessionTabInitialized(); return mySessionTab.getRunContentDescriptor(); } + private void assertSessionTabInitialized() { + if (myShowTabOnSuspend) { + LOG.error("Debug tool window isn't shown yet because debug process isn't suspended"); + } + else { + LOG.assertTrue(mySessionTab != null, "Debug tool window not initialized yet!"); + } + } + public void setPauseActionSupported(final boolean isSupported) { myPauseActionSupported = isSupported; } public void rebuildViews() { - mySessionTab.rebuildViews(); + if (!myShowTabOnSuspend) { + mySessionTab.rebuildViews(); + } } @Nullable @@ -162,6 +178,7 @@ public class XDebugSessionImpl implements XDebugSession { public XDebugSessionTab init(final XDebugProcess process, @NotNull final XDebugSessionData sessionData) { LOG.assertTrue(myDebugProcess == null); myDebugProcess = process; + mySessionData = sessionData; XBreakpointManagerImpl breakpointManager = myDebuggerManager.getBreakpointManager(); XDependentBreakpointManager dependentBreakpointManager = breakpointManager.getDependentBreakpointManager(); @@ -173,8 +190,9 @@ public class XDebugSessionImpl implements XDebugSession { myDependentBreakpointListener = new MyDependentBreakpointListener(); dependentBreakpointManager.addListener(myDependentBreakpointListener); - initSessionTab(sessionData); - process.sessionInitialized(); + if (!myShowTabOnSuspend) { + initSessionTab(); + } return mySessionTab; } @@ -183,13 +201,14 @@ public class XDebugSessionImpl implements XDebugSession { return mySessionTab; } - private void initSessionTab(@NotNull XDebugSessionData sessionData) { + private void initSessionTab() { mySessionTab = new XDebugSessionTab(myProject, mySessionName); if (myEnvironment != null) { mySessionTab.setEnvironment(myEnvironment); } Disposer.register(myProject, mySessionTab); - mySessionTab.attachToSession(this, myRunner, myEnvironment, sessionData); + mySessionTab.attachToSession(this, myRunner, myEnvironment, mySessionData); + myDebugProcess.sessionInitialized(); } private void disableSlaveBreakpoints(final XDependentBreakpointManager dependentBreakpointManager) { @@ -205,6 +224,15 @@ public class XDebugSessionImpl implements XDebugSession { } } + public void showSessionTab() { + RunContentDescriptor descriptor = getRunContentDescriptor(); + ExecutionManager.getInstance(getProject()).getContentManager().showRunContent(DefaultDebugExecutor.getDebugExecutorInstance(), descriptor); + ProcessHandler handler = descriptor.getProcessHandler(); + if (handler != null) { + handler.startNotify(); + } + } + private static > XBreakpointType getBreakpointTypeClass(final XBreakpointHandler handler) { return XDebuggerUtil.getInstance().findBreakpointType(handler.getBreakpointTypeClass()); } @@ -483,9 +511,10 @@ public class XDebugSessionImpl implements XDebugSession { } private void printMessage(final String message, final String hyperLinkText, @Nullable final HyperlinkInfo info) { + assertSessionTabInitialized(); DebuggerUIUtil.invokeOnEventDispatch(new Runnable() { public void run() { - final ConsoleView consoleView = getConsoleView(); + final ConsoleView consoleView = (ConsoleView)mySessionTab.getConsole(); consoleView.print(message, ConsoleViewContentType.SYSTEM_OUTPUT); if (info != null) { consoleView.printHyperlink(hyperLinkText, info); @@ -498,10 +527,6 @@ public class XDebugSessionImpl implements XDebugSession { }); } - private ConsoleView getConsoleView() { - return (ConsoleView)mySessionTab.getConsole(); - } - public void positionReached(@NotNull final XSuspendContext suspendContext) { enableBreakpoints(); mySuspendContext = suspendContext; @@ -515,6 +540,11 @@ public class XDebugSessionImpl implements XDebugSession { } UIUtil.invokeLaterIfNeeded(new Runnable() { public void run() { + if (myShowTabOnSuspend) { + myShowTabOnSuspend = false; + initSessionTab(); + showSessionTab(); + } mySessionTab.toFront(); } }); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerManagerImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerManagerImpl.java index 6375eb31cb68..f07b6d15291c 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerManagerImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerManagerImpl.java @@ -16,7 +16,6 @@ package com.intellij.xdebugger.impl; import com.intellij.execution.ExecutionException; -import com.intellij.execution.ExecutionManager; import com.intellij.execution.Executor; import com.intellij.execution.executors.DefaultDebugExecutor; import com.intellij.execution.process.ProcessHandler; @@ -150,18 +149,24 @@ public class XDebuggerManagerImpl extends XDebuggerManager implements ProjectCom @NotNull public XDebugSession startSessionAndShowTab(@NotNull String sessionName, @Nullable RunContentDescriptor contentToReuse, - @NotNull XDebugProcessStarter starter) throws ExecutionException { - XDebugSession session = startSession(contentToReuse, starter, new XDebugSessionImpl(null, null, this, sessionName)); - RunContentDescriptor descriptor = session.getRunContentDescriptor(); - ExecutionManager.getInstance(myProject).getContentManager().showRunContent(DefaultDebugExecutor.getDebugExecutorInstance(), descriptor); - ProcessHandler handler = descriptor.getProcessHandler(); - if (handler != null) { - handler.startNotify(); + @NotNull XDebugProcessStarter starter) throws ExecutionException { + return startSessionAndShowTab(sessionName, contentToReuse, false, starter); + } + + @NotNull + @Override + public XDebugSession startSessionAndShowTab(@NotNull String sessionName, @Nullable RunContentDescriptor contentToReuse, + boolean showToolWindowOnSuspendOnly, + @NotNull XDebugProcessStarter starter) throws ExecutionException { + XDebugSessionImpl session = startSession(contentToReuse, starter, new XDebugSessionImpl(null, null, this, sessionName, + showToolWindowOnSuspendOnly)); + if (!showToolWindowOnSuspendOnly) { + session.showSessionTab(); } return session; } - private XDebugSession startSession(final RunContentDescriptor contentToReuse, final XDebugProcessStarter processStarter, + private XDebugSessionImpl startSession(final RunContentDescriptor contentToReuse, final XDebugProcessStarter processStarter, final XDebugSessionImpl session) throws ExecutionException { XDebugProcess process = processStarter.start(session); From a4a3bc01d5470672d466f5e3dba9c19e2542d9a0 Mon Sep 17 00:00:00 2001 From: "Rustam.Vishnyakov" Date: Tue, 25 Jan 2011 17:23:04 +0300 Subject: [PATCH 52/53] Dynamically forming JS library scope, removed JSLibraryScopeFilter --- .../ScriptingLibraryMappings.java | 54 +++++++++++-------- .../ui/EditLibraryDialog.java | 9 ++-- .../scripting/ScriptingLibraryTable.java | 12 ++--- 3 files changed, 43 insertions(+), 32 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java index c38de1ac7e61..376cd7b3cf0d 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java @@ -47,7 +47,6 @@ public class ScriptingLibraryMappings extends LanguagePerFileMappings myCompoundLibMap = new HashMap(); private CompoundLibrary myProjectLibs = new CompoundLibrary(); - private Set myProjectLibFiles; public ScriptingLibraryMappings(final Project project, final LibraryType libraryType) { super(project); @@ -96,7 +95,6 @@ public class ScriptingLibraryMappings extends LanguagePerFileMappings mappings) { super.setMappings(mappings); updateDependencies(mappings); - updateProjectLibraryFiles(); } private static boolean dependencyExists(ModuleRootManager rootManager, Library library) { @@ -173,7 +171,6 @@ public class ScriptingLibraryMappings extends LanguagePerFileMappings getSourceFiles() { + Set sourceFiles = new HashSet(); + for (ScriptingLibraryTable.LibraryModel libModel : myLibraries.values()) { + sourceFiles.addAll(libModel.getSourceFiles()); + } + return sourceFiles; + } + + @Override + public Set getCompactFiles() { + Set compactFiles = new HashSet(); + for (ScriptingLibraryTable.LibraryModel libModel : myLibraries.values()) { + compactFiles.addAll(libModel.getCompactFiles()); + } + return compactFiles; + } } /** @@ -403,26 +418,21 @@ public class ScriptingLibraryMappings extends LanguagePerFileMappings(); - for (ScriptingLibraryTable.LibraryModel container : getMappings().values()) { - if (container instanceof CompoundLibrary) { - for (ScriptingLibraryTable.LibraryModel libModel : ((CompoundLibrary)container).getLibraries()) { - myProjectLibFiles.addAll(Arrays.asList(libModel.getSourceFiles())); - myProjectLibFiles.addAll(Arrays.asList(libModel.getCompactFiles())); - } - } - } - } - - public Set getProjectLibraryFiles() { - if (myProjectLibFiles == null) { - updateProjectLibraryFiles(); - } - return myProjectLibFiles; + + public Set getLibraryFilesFor(VirtualFile srcFile) { + Set libFiles = new HashSet(); + collectLibraryFilesFor(srcFile, libFiles); + return libFiles; } - + private void collectLibraryFilesFor(VirtualFile file, Set libFiles) { + if (file == null) return; + ScriptingLibraryTable.LibraryModel libraryModel = getMapping(file); + if (libraryModel != null) { + libFiles.addAll(libraryModel.getCompactFiles()); + libFiles.addAll(libraryModel.getSourceFiles()); + } + collectLibraryFilesFor(file.getParent(), libFiles); + } } diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.java b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.java index 5618ea8e8dc3..e50517cb219e 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.java +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.java @@ -44,6 +44,7 @@ import java.awt.*; import java.awt.event.*; import java.util.ArrayList; import java.util.Arrays; +import java.util.Set; public class EditLibraryDialog extends DialogWrapper { @@ -290,11 +291,11 @@ public class EditLibraryDialog extends DialogWrapper { fireTableDataChanged(); } - public void setFiles(VirtualFile[] sourceFiles, VirtualFile[] compactFiles) { + public void setFiles(Set sourceFiles, Set compactFiles) { myFiles.clear(); - myFiles.addAll(Arrays.asList(sourceFiles)); - myFiles.addAll(Arrays.asList(compactFiles)); - myCompactFiles.addAll(Arrays.asList(compactFiles)); + myFiles.addAll(sourceFiles); + myFiles.addAll(compactFiles); + myCompactFiles.addAll(compactFiles); } public void setFileType(VirtualFile file, boolean isCompact) { diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibraryTable.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibraryTable.java index 2cbaa05d6d6e..a01a247226d9 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibraryTable.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibraryTable.java @@ -79,7 +79,7 @@ public class ScriptingLibraryTable { if (myCompactFilesCache == null) { myCompactFilesCache = new HashSet(); for (LibraryModel libraryModel : myLibraryModels) { - myCompactFilesCache.addAll(Arrays.asList(libraryModel.getCompactFiles())); + myCompactFilesCache.addAll(libraryModel.getCompactFiles()); } } return myCompactFilesCache.contains(file); @@ -183,12 +183,12 @@ public class ScriptingLibraryTable { myDocUrls.addAll(Arrays.asList(docUrls)); } - public VirtualFile[] getSourceFiles() { - return mySourceFiles.toArray(new VirtualFile[mySourceFiles.size()]); + public Set getSourceFiles() { + return mySourceFiles; } - public VirtualFile[] getCompactFiles() { - return myCompactFiles.toArray(new VirtualFile[myCompactFiles.size()]); + public Set getCompactFiles() { + return myCompactFiles; } public String[] getDocUrls() { @@ -196,7 +196,7 @@ public class ScriptingLibraryTable { } @NotNull - public VirtualFile[] getFiles(OrderRootType rootType) { + public Set getFiles(OrderRootType rootType) { if (rootType == COMPACT_ROOT_TYPE) { return getCompactFiles(); } From 2dea0c439dec5b2ff2c93cba680b9e6c75290e12 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Tue, 25 Jan 2011 17:43:02 +0300 Subject: [PATCH 53/53] svn doesnt run empty processes on typing --- .../src/org/jetbrains/idea/svn/SvnFileSystemListener.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListener.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListener.java index 7b0bdc05fb5b..757ed9891529 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListener.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListener.java @@ -628,7 +628,7 @@ public class SvnFileSystemListener extends CommandAdapter implements LocalFileOp if (value != VcsShowConfirmationOption.Value.DO_NOTHING_SILENTLY) { final AbstractVcsHelper vcsHelper = AbstractVcsHelper.getInstance(project); final Collection filesToProcess = promptAboutAddition(vcs, addedVFiles, value, vcsHelper); - if (filesToProcess != null) { + if (filesToProcess != null && !filesToProcess.isEmpty()) { final List exceptions = new ArrayList(); runInBackground(project, "Adding files to Subversion", createAdditionRunnable(project, vcs, copyFromMap, filesToProcess, exceptions)); @@ -758,7 +758,7 @@ public class SvnFileSystemListener extends CommandAdapter implements LocalFileOp final AbstractVcsHelper vcsHelper = AbstractVcsHelper.getInstance(project); Collection filesToProcess; filesToProcess = promptAboutDeletion(deletedFiles, vcs, value, vcsHelper); - if (filesToProcess != null) { + if (filesToProcess != null && !filesToProcess.isEmpty()) { List exceptions = new ArrayList(); runInBackground(project, "Deleting files from Subversion", createDeleteRunnable(project, vcs, filesToProcess, exceptions)); if (!exceptions.isEmpty()) { @@ -845,6 +845,8 @@ public class SvnFileSystemListener extends CommandAdapter implements LocalFileOp } private void processMovedFiles(final Project project) { + if (myMovedFiles.isEmpty()) return; + final Runnable runnable = new Runnable() { public void run() { for (Iterator iterator = myMovedFiles.iterator(); iterator.hasNext();) {