From 834c98823137f32cdd1799a65ee38d35a2f4cdbb Mon Sep 17 00:00:00 2001 From: Sascha Weinreuter Date: Mon, 3 Jun 2013 18:01:35 +0200 Subject: [PATCH 01/49] EA-46782 - IOOBE: SegmentArray.getSegmentStart --- .../model/descriptors/RngElementDescriptor.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngElementDescriptor.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngElementDescriptor.java index 054460f7c38d..0bf6be45c92f 100644 --- a/xml/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngElementDescriptor.java +++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngElementDescriptor.java @@ -215,8 +215,9 @@ public class RngElementDescriptor implements XmlElementDescriptor { } public PsiElement getDeclaration() { - if (myDeclaration != null) { - final PsiElement element = myDeclaration.getElement(); + final SmartPsiElementPointer declaration = myDeclaration; + if (declaration != null) { + final PsiElement element = declaration.getElement(); if (element != null && element.isValid()) { return element; } @@ -225,7 +226,6 @@ public class RngElementDescriptor implements XmlElementDescriptor { final PsiElement decl = myNsDescriptor.getDeclaration(); if (decl == null/* || !decl.isValid()*/) { myDeclaration = null; - System.out.println("decl is null"); return null; } @@ -244,7 +244,7 @@ public class RngElementDescriptor implements XmlElementDescriptor { return getDeclarationImpl(element, location); } - private PsiElement getDeclarationImpl(PsiElement decl, Locator location) { + private static PsiElement getDeclarationImpl(PsiElement decl, Locator location) { final VirtualFile virtualFile = RngSchemaValidator.findVirtualFile(location.getSystemId()); if (virtualFile == null) { return decl; @@ -262,6 +262,9 @@ public class RngElementDescriptor implements XmlElementDescriptor { final Document document = PsiDocumentManager.getInstance(project).getDocument(file); assert document != null; + if (line <= 0 || document.getLineCount() < line - 1) { + return decl; + } final int startOffset = document.getLineStartOffset(line - 1); final PsiElement at; @@ -271,7 +274,8 @@ public class RngElementDescriptor implements XmlElementDescriptor { } at = file.findElementAt(startOffset + column - 2); } else { - at = PsiTreeUtil.nextLeaf(file.findElementAt(startOffset)); + PsiElement element = file.findElementAt(startOffset); + at = element != null ? PsiTreeUtil.nextLeaf(element) : null; } return PsiTreeUtil.getParentOfType(at, XmlTag.class); From 201e400af557b56600f7e6f594dc39341c1be03a Mon Sep 17 00:00:00 2001 From: Sascha Weinreuter Date: Mon, 3 Jun 2013 18:31:12 +0200 Subject: [PATCH 02/49] EA-42809 - CCE: RngDocumentationProvider.generateDoc EA-38467 - NPE: XmlTagImpl.getDescriptor --- .../relaxNG/RngDocumentationProvider.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/RngDocumentationProvider.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/RngDocumentationProvider.java index f3025ce1d2f9..de71f0d8126f 100644 --- a/xml/relaxng/src/org/intellij/plugins/relaxNG/RngDocumentationProvider.java +++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/RngDocumentationProvider.java @@ -17,15 +17,18 @@ package org.intellij.plugins.relaxNG; import com.intellij.lang.documentation.DocumentationProvider; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiManager; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.xml.XmlAttribute; import com.intellij.psi.xml.XmlElement; import com.intellij.psi.xml.XmlTag; +import com.intellij.util.containers.ContainerUtil; import com.intellij.xml.XmlAttributeDescriptor; import com.intellij.xml.XmlElementDescriptor; import com.intellij.xml.util.XmlStringUtil; +import gnu.trove.THashSet; import org.intellij.plugins.relaxNG.model.descriptors.CompositeDescriptor; import org.intellij.plugins.relaxNG.model.descriptors.RngElementDescriptor; import org.intellij.plugins.relaxNG.model.descriptors.RngXmlAttributeDescriptor; @@ -42,12 +45,18 @@ import java.util.List; * Date: 19.11.2007 */ public class RngDocumentationProvider implements DocumentationProvider { + private static final Logger LOG = Logger.getInstance(RngDocumentationProvider.class); + @NonNls private static final String COMPATIBILITY_ANNOTATIONS_1_0 = "http://relaxng.org/ns/compatibility/annotations/1.0"; @Nullable - public String generateDoc(PsiElement element, PsiElement originalElement) { + public String generateDoc(PsiElement element, @Nullable PsiElement originalElement) { final XmlElement c = PsiTreeUtil.getParentOfType(originalElement, XmlTag.class, XmlAttribute.class); + if (c != null && c.getManager() == null) { + LOG.warn("Invalid context element passed to generateDoc()", new Throwable("")); + return null; + } if (c instanceof XmlTag) { final XmlTag xmlElement = (XmlTag)c; final XmlElementDescriptor descriptor = xmlElement.getDescriptor(); @@ -55,9 +64,10 @@ public class RngDocumentationProvider implements DocumentationProvider { final StringBuilder sb = new StringBuilder(); final CompositeDescriptor d = (CompositeDescriptor)descriptor; final DElementPattern[] patterns = d.getElementPatterns(); + final THashSet elements = ContainerUtil.newIdentityTroveSet(); for (DElementPattern pattern : patterns) { final PsiElement psiElement = d.getDeclaration(pattern.getLocation()); - if (psiElement instanceof XmlTag) { + if (psiElement instanceof XmlTag && elements.add(psiElement)) { if (sb.length() > 0) { sb.append("
"); } @@ -78,13 +88,13 @@ public class RngDocumentationProvider implements DocumentationProvider { if (descriptor instanceof RngXmlAttributeDescriptor) { final RngXmlAttributeDescriptor d = (RngXmlAttributeDescriptor)descriptor; final StringBuilder sb = new StringBuilder(); - final Collection declaration = d.getDeclarations(); + final Collection declaration = ContainerUtil.newIdentityTroveSet(d.getDeclarations()); for (PsiElement psiElement : declaration) { if (psiElement instanceof XmlTag) { if (sb.length() > 0) { sb.append("
"); } - sb.append(getDocumentationFromTag((XmlTag)element, d.getName(), "Attribute")); + sb.append(getDocumentationFromTag((XmlTag)psiElement, d.getName(), "Attribute")); } } } From 656ff3919abd472e6db41e800bdaaada8eb49a73 Mon Sep 17 00:00:00 2001 From: Sascha Weinreuter Date: Tue, 4 Jun 2013 09:42:01 +0200 Subject: [PATCH 03/49] Cleanup, performance --- .../model/resolve/RelaxSymbolIndex.java | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/model/resolve/RelaxSymbolIndex.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/model/resolve/RelaxSymbolIndex.java index 29ff4e0616f1..7aa66701bb03 100644 --- a/xml/relaxng/src/org/intellij/plugins/relaxNG/model/resolve/RelaxSymbolIndex.java +++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/model/resolve/RelaxSymbolIndex.java @@ -45,6 +45,17 @@ public class RelaxSymbolIndex extends ScalarIndexExtension { @NonNls public static final ID NAME = ID.create("RelaxSymbolIndex"); + public static final FileBasedIndex.InputFilter INPUT_FILTER = new FileBasedIndex.InputFilter() { + @Override + public boolean acceptInput(VirtualFile file) { + if (file.getFileSystem() instanceof JarFileSystem) { + return false; // there is lots and lots of custom XML inside zip files + } + final FileType fileType = file.getFileType(); + return fileType == StdFileTypes.XML || fileType == RncFileType.getInstance(); + } + }; + public static Collection getSymbolNames(Project project) { return FileBasedIndex.getInstance().getAllKeys(NAME, project); } @@ -70,9 +81,10 @@ public class RelaxSymbolIndex extends ScalarIndexExtension { @NotNull public Map map(FileContent inputData) { final HashMap map = new HashMap(); - if (inputData.getFileType() == XmlFileType.INSTANCE) { + final FileType type = inputData.getFileType(); + if (type == XmlFileType.INSTANCE) { CharSequence inputDataContentAsText = inputData.getContentAsText(); - if (CharArrayUtil.indexOf(inputDataContentAsText, ApplicationLoader.RNG_NAMESPACE, 0) == -1) return Collections.EMPTY_MAP; + if (CharArrayUtil.indexOf(inputDataContentAsText, ApplicationLoader.RNG_NAMESPACE, 0) == -1) return Collections.emptyMap(); NanoXmlUtil.parse(CharArrayUtil.readerFromCharSequence(inputData.getContentAsText()), new NanoXmlUtil.IXMLBuilderAdapter() { NanoXmlUtil.IXMLBuilderAdapter attributeHandler; int depth; @@ -108,7 +120,7 @@ public class RelaxSymbolIndex extends ScalarIndexExtension { depth--; } }); - } else if (inputData.getFileType() == RncFileType.getInstance()) { + } else if (type == RncFileType.getInstance()) { final PsiFile file = inputData.getPsiFile(); if (file instanceof XmlFile) { final Grammar grammar = GrammarFactory.getGrammar((XmlFile)file); @@ -137,16 +149,7 @@ public class RelaxSymbolIndex extends ScalarIndexExtension { @Override public FileBasedIndex.InputFilter getInputFilter() { - return new FileBasedIndex.InputFilter() { - @Override - public boolean acceptInput(VirtualFile file) { - if (file.getFileSystem() instanceof JarFileSystem) { - return false; // there is lots and lots of custom XML inside zip files - } - final FileType fileType = file.getFileType(); - return fileType == StdFileTypes.XML || fileType == RncFileType.getInstance(); - } - }; + return INPUT_FILTER; } @Override @@ -243,7 +246,7 @@ public class RelaxSymbolIndex extends ScalarIndexExtension { @Override public ItemPresentation getPresentation() { - return myPresentation != null ? this : null; + return this; } @Override From 9044715033b13a9063b599275b7616d3bca1f1cb Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Thu, 20 Jun 2013 16:24:44 +0400 Subject: [PATCH 04/49] Do enforce line feed between a field and instance block initializer in a situation when formatter is not called explicitly --- .../psi/formatter/java/JavaSpacePropertyProcessor.java | 7 ++++++- .../psi/formatter/java/JavaFormatterIndentationTest.java | 4 ++-- .../testSrc/com/intellij/refactoring/MoveInnerTest.java | 2 +- .../src/com/intellij/formatting/FormatterImpl.java | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java index e81e167d3c45..1376f44c07ca 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java @@ -296,7 +296,12 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor { } else if (myRole1 == ChildRole.FIELD) { int lines = Math.max(getLinesAroundField(), getLinesAroundMethod()) + 1; - myResult = Spacing.createSpacing(0, mySettings.SPACE_BEFORE_CLASS_LBRACE ? 1 : 0, 0, true, mySettings.KEEP_BLANK_LINES_BEFORE_RBRACE, + // IJ has been keeping initialization block which starts at the same line as a field for a while. + // However, it's not convenient for a situation when particular code is created via PSI - it's easier to not bothering + // with whitespace elements when inserting, say, new initialization blocks. That's why we don't enforce new line + // only during explicit reformatting ('Reformat' action). + int minLineFeeds = FormatterUtil.isFormatterCalledExplicitly() ? 0 : 1; + myResult = Spacing.createSpacing(0, mySettings.SPACE_BEFORE_CLASS_LBRACE ? 1 : 0, 1, true, mySettings.KEEP_BLANK_LINES_BEFORE_RBRACE, lines); } else if (myRole1 == ChildRole.CLASS) { diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java index b61689b46a1d..be335471d355 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java @@ -40,7 +40,7 @@ public class JavaFormatterIndentationTest extends AbstractJavaFormatterTest { // Checking that closing curly brace of initialization block that is not the first block on a line is correctly indented. doTextTest("class Class {\n" + " private Type field; {\n" + " }\n" + "}", - "class Class {\n" + " private Type field; {\n" + " }\n" + "}"); + "class Class {\n" + " private Type field;\n\n {\n" + " }\n" + "}"); doTextTest( "class T {\n" + " private final DecimalFormat fmt = new DecimalFormat(); {\n" + @@ -49,7 +49,7 @@ public class JavaFormatterIndentationTest extends AbstractJavaFormatterTest { " }\n" + "}", "class T {\n" + - " private final DecimalFormat fmt = new DecimalFormat(); {\n" + + " private final DecimalFormat fmt = new DecimalFormat();\n\n {\n" + " fmt.setGroupingUsed(false);\n" + " fmt.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US));\n" + " }\n" + diff --git a/java/java-tests/testSrc/com/intellij/refactoring/MoveInnerTest.java b/java/java-tests/testSrc/com/intellij/refactoring/MoveInnerTest.java index 1fa21c507201..17c8894cf186 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/MoveInnerTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/MoveInnerTest.java @@ -60,7 +60,7 @@ public class MoveInnerTest extends MultiFileTestCase { doTest(createAction("p.A.B", "B", false, null, false, false, null)); } - public void _testScr30106() throws Exception { + public void testScr30106() throws Exception { doTest(createAction("p.A.B", "B", true, "outer", false, false, null)); } diff --git a/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java b/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java index 1640a59823d0..5a413501414e 100644 --- a/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java +++ b/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java @@ -718,7 +718,7 @@ public class FormatterImpl extends FormatterEx @NotNull public Spacing createSpacing(final int minSpaces, final int maxSpaces, final int minLineFeeds, final boolean keepLineBreaks, final int keepBlankLines, final int prefLineFeeds) { - return getSpacingImpl(minSpaces, maxSpaces, -1, false, false, keepLineBreaks, keepBlankLines, false, prefLineFeeds); + return getSpacingImpl(minSpaces, maxSpaces, minLineFeeds, false, false, keepLineBreaks, keepBlankLines, false, prefLineFeeds); } private final Map ourSharedProperties = new HashMap(); From dd8476babb03cf61a83300913de2a654860e8dab Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 20 Jun 2013 15:55:29 +0400 Subject: [PATCH 05/49] implement fix workaround: if abstract method is package local and package is not the same - suggest to make method protected/public instead (IDEA-61220) --- .../impl/analysis/HighlightClassUtil.java | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java index 4f6f0996ad29..5bcc31079aab 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java @@ -94,19 +94,32 @@ public class HighlightClassUtil { static HighlightInfo checkClassWithAbstractMethods(PsiClass aClass, PsiElement implementsFixElement, TextRange range) { PsiMethod abstractMethod = ClassUtil.getAnyAbstractMethod(aClass); - if (abstractMethod == null || abstractMethod.getContainingClass() == null) { + if (abstractMethod == null) { return null; } + + final PsiClass superClass = abstractMethod.getContainingClass(); + if (superClass == null) { + return null; + } + String baseClassName = HighlightUtil.formatClass(aClass, false); String methodName = JavaHighlightUtil.formatMethod(abstractMethod); String message = JavaErrorMessages.message(aClass instanceof PsiEnumConstantInitializer || implementsFixElement instanceof PsiEnumConstant ? "enum.constant.should.implement.method" : "class.must.be.abstract", baseClassName, methodName, - HighlightUtil.formatClass(abstractMethod.getContainingClass(), false)); + HighlightUtil.formatClass(superClass, false)); HighlightInfo errorResult = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range).descriptionAndTooltip(message).create(); - if (ClassUtil.getAnyMethodToImplement(aClass) != null) { - QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createImplementMethodsFix(implementsFixElement)); + final PsiMethod anyMethodToImplement = ClassUtil.getAnyMethodToImplement(aClass); + if (anyMethodToImplement != null) { + if (!anyMethodToImplement.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) || + JavaPsiFacade.getInstance(aClass.getProject()).arePackagesTheSame(aClass, superClass)) { + QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createImplementMethodsFix(implementsFixElement)); + } else { + QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createModifierListFix(anyMethodToImplement, PsiModifier.PROTECTED, true, true)); + QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createModifierListFix(anyMethodToImplement, PsiModifier.PUBLIC, true, true)); + } } if (!(aClass instanceof PsiAnonymousClass) && HighlightUtil.getIncompatibleModifier(PsiModifier.ABSTRACT, aClass.getModifierList()) == null) { From 058b3edd3ce0a74e216fec73e41c9c2c10d1f7f3 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Thu, 20 Jun 2013 16:57:25 +0400 Subject: [PATCH 06/49] [^vassily] better icon for detached frame on XWindow --- .../src/com/intellij/openapi/ui/FrameWrapper.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/FrameWrapper.java b/platform/platform-impl/src/com/intellij/openapi/ui/FrameWrapper.java index efe1d7e0d16f..5cb962c73cda 100644 --- a/platform/platform-impl/src/com/intellij/openapi/ui/FrameWrapper.java +++ b/platform/platform-impl/src/com/intellij/openapi/ui/FrameWrapper.java @@ -36,6 +36,7 @@ import com.intellij.openapi.wm.ex.WindowManagerEx; import com.intellij.openapi.wm.impl.IdeFrameImpl; import com.intellij.openapi.wm.impl.IdeGlassPaneImpl; import com.intellij.openapi.wm.impl.IdeMenuBar; +import com.intellij.ui.AppUIUtil; import com.intellij.ui.BalloonLayout; import com.intellij.ui.FocusTrackback; import com.intellij.util.ImageLoader; @@ -71,6 +72,7 @@ public class FrameWrapper implements Disposable, DataProvider { protected StatusBar myStatusBar; private boolean myShown; private boolean myIsDialog; + private boolean myImageWasChanged; public FrameWrapper(Project project) { this(project, null); @@ -159,7 +161,12 @@ public class FrameWrapper implements Disposable, DataProvider { } else { ((JDialog)frame).setTitle(myTitle); } - frame.setIconImage(myImage); + if (myImageWasChanged) { + frame.setIconImage(myImage); + } + else { + AppUIUtil.updateWindowIcon(myFrame); + } if (restoreBounds) { loadFrameState(); @@ -277,6 +284,7 @@ public class FrameWrapper implements Disposable, DataProvider { } public void setImage(Image image) { + myImageWasChanged = true; myImage = image; } From 4f081d2ed00771a3aaa93add5ad6a9a2fdf47343 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 20 Jun 2013 17:05:59 +0400 Subject: [PATCH 07/49] wording --- .../src/com/intellij/execution/impl/ConsoleViewImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java index b4768a21910f..b342ef7e8d51 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java @@ -747,7 +747,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo final EditorNotificationPanel comp = new EditorNotificationPanel() { { myLabel.setIcon(AllIcons.General.ExclMark); - myLabel.setText("Too many output to process"); + myLabel.setText("Too much output to process"); } }; add(comp, BorderLayout.NORTH); From 67f8766368784aa4f71f45ed2fb9aee6663e607d Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 20 Jun 2013 17:18:15 +0400 Subject: [PATCH 08/49] additional logging --- .../ui/breakpoints/LineBreakpoint.java | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java index 76f1b7982319..a778e1c126bb 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java @@ -36,6 +36,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.markup.RangeHighlighter; import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; @@ -44,12 +45,16 @@ import com.intellij.openapi.util.Key; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; +import com.intellij.psi.impl.java.stubs.index.JavaFullClassNameIndex; import com.intellij.psi.jsp.JspFile; +import com.intellij.psi.search.EverythingGlobalScope; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.ui.classFilter.ClassFilter; +import com.intellij.util.Function; import com.intellij.util.Processor; import com.intellij.util.StringBuilderSpinAllocator; +import com.intellij.util.containers.ContainerUtil; import com.intellij.xdebugger.XDebuggerUtil; import com.sun.jdi.*; import com.sun.jdi.event.LocatableEvent; @@ -203,6 +208,37 @@ public class LineBreakpoint extends BreakpointWithHighlighter { return true; } } + if (LOG.isDebugEnabled()) { + final GlobalSearchScope scope = debugProcess.getSearchScope(); + final boolean contains = scope.contains(breakpointFile); + final Project project = getProject(); + final List files = ContainerUtil.map( + JavaFullClassNameIndex.getInstance().get(className.hashCode(), project, scope), new Function() { + @Override + public VirtualFile fun(PsiClass aClass) { + return aClass.getContainingFile().getVirtualFile(); + } + }); + final List allFiles = ContainerUtil.map( + JavaFullClassNameIndex.getInstance().get(className.hashCode(), project, new EverythingGlobalScope(project)), new Function() { + @Override + public VirtualFile fun(PsiClass aClass) { + return aClass.getContainingFile().getVirtualFile(); + } + }); + final VirtualFile contentRoot = fileIndex.getContentRootForFile(breakpointFile); + final Module module = fileIndex.getModuleForFile(breakpointFile); + + LOG.debug("Did not find '" + + className + "' in " + scope + + "; contains=" + contains + + "; contentRoot=" + contentRoot + + "; module = " + module + + "; all files in index are: " + files+ + "; all possible files are: " + allFiles + ); + } + return false; } } @@ -218,7 +254,7 @@ public class LineBreakpoint extends BreakpointWithHighlighter { public Collection compute() { final PsiClass[] classes = JavaPsiFacade.getInstance(myProject).findClasses(topLevelClassName, scope); if (LOG.isDebugEnabled()) { - LOG.debug("Found "+ classes.length + " classes " + topLevelClassName + " in scope"); + LOG.debug("Found "+ classes.length + " classes " + topLevelClassName + " in scope "+scope); } if (classes.length == 0) { return null; From 87f8a202c28055b409c86de303676da163b2c190 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 20 Jun 2013 15:00:29 +0200 Subject: [PATCH 09/49] remove unused AbstractModificationTracker --- .../psi/impl/AbstractModificationTracker.java | 91 ------------------- 1 file changed, 91 deletions(-) delete mode 100644 platform/core-impl/src/com/intellij/psi/impl/AbstractModificationTracker.java diff --git a/platform/core-impl/src/com/intellij/psi/impl/AbstractModificationTracker.java b/platform/core-impl/src/com/intellij/psi/impl/AbstractModificationTracker.java deleted file mode 100644 index e8e5cc3e3899..000000000000 --- a/platform/core-impl/src/com/intellij/psi/impl/AbstractModificationTracker.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2000-2012 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.psi.impl; - -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import org.jetbrains.annotations.NotNull; - -/** - * @author Roman.Chernyatchik - */ -public abstract class AbstractModificationTracker implements PsiTreeChangePreprocessor { - private final PsiManagerImpl myPsiManager; - private PsiModificationTrackerImpl myModificationTracker; - - protected abstract boolean isInsideCodeBlock(PsiElement element); - - public AbstractModificationTracker(PsiManagerImpl psiManager) { - myPsiManager = psiManager; - } - - public PsiManagerImpl getPsiManager() { - return myPsiManager; - } - - protected void initTracker() { - myModificationTracker = (PsiModificationTrackerImpl) myPsiManager.getModificationTracker(); - myPsiManager.addTreeChangePreprocessor(this); - } - - @Override - public void treeChanged(@NotNull final PsiTreeChangeEventImpl event) { - boolean changedInsideCodeBlock = false; - - switch (event.getCode()) { - case BEFORE_CHILDREN_CHANGE: - if (event.getParent() instanceof PsiFile) { - changedInsideCodeBlock = true; - break; // May be caused by fake PSI event from PomTransaction. A real event will anyway follow. - } - - case CHILDREN_CHANGED : - if (event.isGenericChildrenChange()) return; - changedInsideCodeBlock = isInsideCodeBlock(event.getParent()); - break; - - case BEFORE_CHILD_ADDITION: - case BEFORE_CHILD_REMOVAL: - case CHILD_ADDED : - case CHILD_REMOVED : - case BEFORE_CHILD_REPLACEMENT: - case CHILD_REPLACED : - changedInsideCodeBlock = isInsideCodeBlock(event.getParent()) && - isInsideCodeBlock(event.getChild()) && - isInsideCodeBlock(event.getOldChild()) && - isInsideCodeBlock(event.getNewChild()); - break; - - case BEFORE_CHILD_MOVEMENT: - case CHILD_MOVED : - changedInsideCodeBlock = isInsideCodeBlock(event.getOldParent()) && isInsideCodeBlock(event.getNewParent()) && isInsideCodeBlock(event.getChild()); - break; - - case BEFORE_PROPERTY_CHANGE: - case PROPERTY_CHANGED : - changedInsideCodeBlock = false; - break; - } - - if (!changedInsideCodeBlock) { - processOutOfCodeBlockModification(event); - } - } - - protected void processOutOfCodeBlockModification(final PsiTreeChangeEventImpl event) { - myModificationTracker.incOutOfCodeBlockModificationCounter(); - } -} From 36adc622839b17a97a192afaee69ca77e433fa37 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 20 Jun 2013 15:04:37 +0200 Subject: [PATCH 10/49] let no out-of-code-block change be registered without a corresponding any-psi-change --- .../com/intellij/psi/impl/PsiModificationTrackerImpl.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java index d3c6b410abd8..5fefd4f0a40b 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java @@ -60,10 +60,12 @@ public class PsiModificationTrackerImpl implements PsiModificationTracker, PsiTr public void incCounter() { myModificationCount.getAndIncrement(); myJavaStructureModificationCount.getAndIncrement(); - incOutOfCodeBlockModificationCounter(); + myOutOfCodeBlockModificationCount.getAndIncrement(); + myPublisher.modificationCountChanged(); } public void incOutOfCodeBlockModificationCounter() { + myModificationCount.getAndIncrement(); myOutOfCodeBlockModificationCount.getAndIncrement(); myPublisher.modificationCountChanged(); } @@ -72,7 +74,7 @@ public class PsiModificationTrackerImpl implements PsiModificationTracker, PsiTr public void treeChanged(@NotNull PsiTreeChangeEventImpl event) { myModificationCount.getAndIncrement(); if (event.getParent() instanceof PsiDirectory) { - incOutOfCodeBlockModificationCounter(); + myOutOfCodeBlockModificationCount.getAndIncrement(); } myPublisher.modificationCountChanged(); From 5ea462e1ecc75c2e350683f3629dc3f823797027 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Thu, 20 Jun 2013 18:03:32 +0400 Subject: [PATCH 11/49] [git] Fix possible race condition in http tests CountDownLatches were released before the corresponding variables were updated. Therefore the test could get old value. --- .../git4idea/test-stepdefs/git4idea/GitRemoteSteps.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/git4idea/test-stepdefs/git4idea/GitRemoteSteps.java b/plugins/git4idea/test-stepdefs/git4idea/GitRemoteSteps.java index 1958dacfc866..655fffad9364 100644 --- a/plugins/git4idea/test-stepdefs/git4idea/GitRemoteSteps.java +++ b/plugins/git4idea/test-stepdefs/git4idea/GitRemoteSteps.java @@ -105,8 +105,8 @@ public class GitRemoteSteps { @NotNull @Override public String askPassword(@NotNull String url) { - myPasswordAskedWaiter.countDown(); myPasswordAsked = true; + myPasswordAskedWaiter.countDown(); try { assertTrue("Password was not supplied during the reasonable period of time", myPasswordSuppliedWaiter.await(TIMEOUT, TimeUnit.SECONDS)); @@ -120,8 +120,8 @@ public class GitRemoteSteps { @NotNull @Override public String askUsername(@NotNull String url) { - myUsernameAskedWaiter.countDown(); myUsernameAsked = true; + myUsernameAskedWaiter.countDown(); try { assertTrue("Password was not supplied during the reasonable period of time", myUsernameSuppliedWaiter.await(TIMEOUT, TimeUnit.SECONDS)); @@ -134,13 +134,13 @@ public class GitRemoteSteps { void supplyPassword(@NotNull String password) { - myPasswordSuppliedWaiter.countDown(); myPassword = password; + myPasswordSuppliedWaiter.countDown(); } void supplyUsername(@NotNull String username) { - myUsernameSuppliedWaiter.countDown(); myUsername = username; + myUsernameSuppliedWaiter.countDown(); } void waitUntilPasswordIsAsked() throws InterruptedException { From 7b37437be9ef951d8c0a98c0e929a54b97a5e1a2 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 20 Jun 2013 14:07:48 +0200 Subject: [PATCH 12/49] more readable stub+ast debug info --- .../src/com/intellij/psi/impl/source/PsiFileImpl.java | 9 ++++----- .../src/com/intellij/psi/stubs/StubTreeLoaderImpl.java | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java index 33dd6fe72921..b84863ad1273 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java @@ -312,16 +312,15 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF String msg = message; msg += "\n file=" + this; - msg += "\n name=" + getName(); - msg += "\n modStamp=" + getModificationStamp(); + msg += ", modStamp=" + getModificationStamp(); msg += "\n stub debugInfo=" + stubTree.getDebugInfo(); msg += "\n document before=" + cachedDocument; ObjectStubTree latestIndexedStub = StubTreeLoader.getInstance().readFromVFile(getProject(), getVirtualFile()); msg += "\nlatestIndexedStub=" + latestIndexedStub; if (latestIndexedStub != null) { - msg += "\nsame size=" + (stubTree.getPlainList().size() == latestIndexedStub.getPlainList().size()); - msg += "\ndebugInfo=" + latestIndexedStub.getDebugInfo(); + msg += "\n same size=" + (stubTree.getPlainList().size() == latestIndexedStub.getPlainList().size()); + msg += "\n debugInfo=" + latestIndexedStub.getDebugInfo(); } FileViewProvider viewProvider = getViewProvider(); @@ -340,7 +339,7 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF msg += "; committed: " + PsiDocumentManager.getInstance(getProject()).isCommitted(document); } - throw new AssertionError(msg); + throw new AssertionError(msg + "\n------------\n"); } protected FileElement createFileElement(final CharSequence docText) { diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubTreeLoaderImpl.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubTreeLoaderImpl.java index 80ef8e752186..f50f398560cc 100644 --- a/platform/lang-impl/src/com/intellij/psi/stubs/StubTreeLoaderImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubTreeLoaderImpl.java @@ -97,7 +97,7 @@ public class StubTreeLoaderImpl extends StubTreeLoader { boolean wasIndexedAlready = ((FileBasedIndexImpl)FileBasedIndex.getInstance()).isFileUpToDate(vFile); Document document = FileDocumentManager.getInstance().getCachedDocument(vFile); - boolean saved = document == null || FileDocumentManager.getInstance().isDocumentUnsaved(document); + boolean saved = document == null || !FileDocumentManager.getInstance().isDocumentUnsaved(document); final List datas = FileBasedIndex.getInstance().getValues(StubUpdatingIndex.INDEX_ID, id, GlobalSearchScope .fileScope(project, vFile)); @@ -114,7 +114,7 @@ public class StubTreeLoaderImpl extends StubTreeLoader { ObjectStubTree tree = stub instanceof PsiFileStub ? new StubTree((PsiFileStub)stub) : new ObjectStubTree((ObjectStubBase)stub, true); tree.setDebugInfo("created from index: " + StubUpdatingIndex.getIndexingStampInfo(vFile) + ", wasIndexedAlready=" + wasIndexedAlready + - ", saved=" + saved + + ", docSaved=" + saved + ", queried at " + vFile.getTimeStamp()); return tree; } From c0d4f79caf8f019a2964da13635554aebc362bd8 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 20 Jun 2013 15:40:46 +0200 Subject: [PATCH 13/49] clear all resolve caches after stub-psi mismatch error --- .../intellij/psi/impl/source/PsiFileImpl.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java index b84863ad1273..1ce39d4f353e 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java @@ -59,6 +59,7 @@ import com.intellij.util.IncorrectOperationException; import com.intellij.util.PatchedWeakReference; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.text.CharArrayUtil; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -309,6 +310,7 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF protected void reportStubAstMismatch(String message, StubTree stubTree, Document cachedDocument) { rebuildStub(); clearStub(); + scheduleDropCachesWithInvalidStubPsi(); String msg = message; msg += "\n file=" + this; @@ -342,6 +344,20 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF throw new AssertionError(msg + "\n------------\n"); } + private void scheduleDropCachesWithInvalidStubPsi() { + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + ((PsiModificationTrackerImpl)getManager().getModificationTracker()).incCounter(); + } + }); + } + }); + } + protected FileElement createFileElement(final CharSequence docText) { final FileElement treeElement; final TreeElement contentLeaf = createContentLeafElement(docText); From 5b2526874ff44bb74d802f084b17b1df0a007af8 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 20 Jun 2013 16:08:35 +0200 Subject: [PATCH 14/49] revert removal --- .../psi/impl/AbstractModificationTracker.java | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 platform/core-impl/src/com/intellij/psi/impl/AbstractModificationTracker.java diff --git a/platform/core-impl/src/com/intellij/psi/impl/AbstractModificationTracker.java b/platform/core-impl/src/com/intellij/psi/impl/AbstractModificationTracker.java new file mode 100644 index 000000000000..dd4200a5d80a --- /dev/null +++ b/platform/core-impl/src/com/intellij/psi/impl/AbstractModificationTracker.java @@ -0,0 +1,91 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.impl; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NotNull; + +/** + * @author Roman.Chernyatchik + */ +public abstract class AbstractModificationTracker implements PsiTreeChangePreprocessor { + private final PsiManagerImpl myPsiManager; + private PsiModificationTrackerImpl myModificationTracker; + + protected abstract boolean isInsideCodeBlock(PsiElement element); + + public AbstractModificationTracker(PsiManagerImpl psiManager) { + myPsiManager = psiManager; + } + + public PsiManagerImpl getPsiManager() { + return myPsiManager; + } + + protected void initTracker() { + myModificationTracker = (PsiModificationTrackerImpl) myPsiManager.getModificationTracker(); + myPsiManager.addTreeChangePreprocessor(this); + } + + @Override + public void treeChanged(@NotNull final PsiTreeChangeEventImpl event) { + boolean changedInsideCodeBlock = false; + + switch (event.getCode()) { + case BEFORE_CHILDREN_CHANGE: + if (event.getParent() instanceof PsiFile) { + changedInsideCodeBlock = true; + break; // May be caused by fake PSI event from PomTransaction. A real event will anyway follow. + } + + case CHILDREN_CHANGED : + if (event.isGenericChildrenChange()) return; + changedInsideCodeBlock = isInsideCodeBlock(event.getParent()); + break; + + case BEFORE_CHILD_ADDITION: + case BEFORE_CHILD_REMOVAL: + case CHILD_ADDED : + case CHILD_REMOVED : + case BEFORE_CHILD_REPLACEMENT: + case CHILD_REPLACED : + changedInsideCodeBlock = isInsideCodeBlock(event.getParent()) && + isInsideCodeBlock(event.getChild()) && + isInsideCodeBlock(event.getOldChild()) && + isInsideCodeBlock(event.getNewChild()); + break; + + case BEFORE_CHILD_MOVEMENT: + case CHILD_MOVED : + changedInsideCodeBlock = isInsideCodeBlock(event.getOldParent()) && isInsideCodeBlock(event.getNewParent()) && isInsideCodeBlock(event.getChild()); + break; + + case BEFORE_PROPERTY_CHANGE: + case PROPERTY_CHANGED : + changedInsideCodeBlock = false; + break; + } + + if (!changedInsideCodeBlock) { + processOutOfCodeBlockModification(event); + } + } + + protected void processOutOfCodeBlockModification(final PsiTreeChangeEventImpl event) { + myModificationTracker.incOutOfCodeBlockModificationCounter(); + } +} From f6cb1ac41790d3210660f8dcde83037379b08c64 Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Thu, 20 Jun 2013 15:52:48 +0400 Subject: [PATCH 15/49] readActiveBookmark meth renamed to readCurrentBookmark --- plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java | 2 +- .../hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java index f34367498a9b..a6d802ef44cb 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java @@ -130,7 +130,7 @@ public class HgRepositoryImpl extends RepositoryImpl implements HgRepository { myCurrentBranch = myReader.readCurrentBranch(); myBranches = myReader.readBranches(); myBookmarks = myReader.readBookmarks(); - myCurrentBookmark = myReader.readActiveBookmark(); + myCurrentBookmark = myReader.readCurrentBookmark(); } } } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java index 69dc742052b8..f1a27c87dd76 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java @@ -132,7 +132,7 @@ public class HgRepositoryReader { } @Nullable - public String readActiveBookmark() { + public String readCurrentBookmark() { return myCurrentBookmark.exists() ? RepositoryUtil.tryLoadFile(myCurrentBookmark) : null; } } From 3e2d7bda5df5b6822d76899f026daba46b91ccf9 Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Thu, 20 Jun 2013 15:54:50 +0400 Subject: [PATCH 16/49] if-statement changed to opposite (code style) --- .../hg4idea/action/HgBranchPopupActions.java | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java index f5dc905b237e..762b561c56d1 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java @@ -105,22 +105,23 @@ public class HgBranchPopupActions { @Override public void actionPerformed(AnActionEvent e) { final String name = HgUtil.getNewBranchNameFromUser(myProject, "Create New Branch"); - if (name != null) { - try { - new HgBranchCreateCommand(myProject, myPreselectedRepo, name).execute(new HgCommandResultHandler() { - @Override - public void process(@Nullable HgCommandResult result) { - myProject.getMessageBus().syncPublisher(HgVcs.BRANCH_TOPIC).update(myProject, null); - if (HgErrorUtil.hasErrorsInCommandExecution(result)) { - new HgCommandResultNotifier(myProject) - .notifyError(result, "Creation failed", "Branch creation [" + name + "] failed"); - } + if (name == null) { + return; + } + try { + new HgBranchCreateCommand(myProject, myPreselectedRepo, name).execute(new HgCommandResultHandler() { + @Override + public void process(@Nullable HgCommandResult result) { + myProject.getMessageBus().syncPublisher(HgVcs.BRANCH_TOPIC).update(myProject, null); + if (HgErrorUtil.hasErrorsInCommandExecution(result)) { + new HgCommandResultNotifier(myProject) + .notifyError(result, "Creation failed", "Branch creation [" + name + "] failed"); } - }); - } - catch (HgCommandException exception) { - HgAbstractGlobalAction.handleException(myProject, exception); - } + } + }); + } + catch (HgCommandException exception) { + HgAbstractGlobalAction.handleException(myProject, exception); } } } From 312735d2a9404f1688004694e6c7e3eae571f5d2 Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Thu, 20 Jun 2013 16:19:21 +0400 Subject: [PATCH 17/49] tests for current bookmark added --- plugins/hg4idea/testData/repo/dot_hg/bookmarks.current | 1 + .../hg4idea/test/repo/HgRealRepositoryReaderTest.java | 5 +++++ .../testSrc/hg4idea/test/repo/HgRepositoryReaderTest.java | 8 ++++++++ 3 files changed, 14 insertions(+) create mode 100644 plugins/hg4idea/testData/repo/dot_hg/bookmarks.current diff --git a/plugins/hg4idea/testData/repo/dot_hg/bookmarks.current b/plugins/hg4idea/testData/repo/dot_hg/bookmarks.current new file mode 100644 index 000000000000..7ca946f4eb97 --- /dev/null +++ b/plugins/hg4idea/testData/repo/dot_hg/bookmarks.current @@ -0,0 +1 @@ +B_BookMark \ No newline at end of file diff --git a/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRealRepositoryReaderTest.java b/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRealRepositoryReaderTest.java index e52b22f6c639..1f76f13cfd7f 100644 --- a/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRealRepositoryReaderTest.java +++ b/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRealRepositoryReaderTest.java @@ -60,6 +60,11 @@ public class HgRealRepositoryReaderTest extends HgPlatformTest { TestRepositoryUtil.assertEqualCollections(myRepositoryReader.readBranches(), Arrays.asList("default", "branchA", "branchB")); } + public void testCurrentBookmark() { + hg("update B_BookMark"); + assertEquals(myRepositoryReader.readCurrentBookmark(), "B_BookMark"); + } + public void testBookmarks() { TestRepositoryUtil.assertEqualCollections(myRepositoryReader.readBookmarks(), Arrays.asList("A_BookMark", "B_BookMark", "C_BookMark")); } diff --git a/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRepositoryReaderTest.java b/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRepositoryReaderTest.java index 1ed1f0bf9496..17af02238e0b 100644 --- a/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRepositoryReaderTest.java +++ b/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRepositoryReaderTest.java @@ -50,9 +50,11 @@ public class HgRepositoryReaderTest extends HgPlatformTest { File cacheDir = new File(testHgDir, "cache"); File testBranchFile = new File(testHgDir, "branch"); File testBookmarkFile = new File(testHgDir, "bookmarks"); + File testCurrentBookmarkFile = new File(testHgDir, "bookmarks.current"); FileUtil.copyDir(cacheDir, new File(myHgDir, "cache")); FileUtil.copy(testBranchFile, new File(myHgDir, "branch")); FileUtil.copy(testBookmarkFile, new File(myHgDir, "bookmarks")); + FileUtil.copy(testCurrentBookmarkFile, new File(myHgDir, "bookmarks.current")); myRepositoryReader = new HgRepositoryReader(myHgDir); myBranches = readBranches(); @@ -91,6 +93,12 @@ public class HgRepositoryReaderTest extends HgPlatformTest { return branches; } + + public void testCurrentBookmark() { + assertEquals(myRepositoryReader.readCurrentBookmark(), "B_BookMark"); + } + + @NotNull private Collection readBookmarks() throws IOException { Collection bookmarks = new HashSet(); File bookmarksFile = new File(myHgDir, "bookmarks"); From 5777012ccb742d7ce8d30baef5f703bbfa30261a Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Thu, 20 Jun 2013 16:42:28 +0400 Subject: [PATCH 18/49] annotations added; bookmark creation for revision removed --- .../hg4idea/action/HgBranchPopupActions.java | 2 +- .../command/HgBookmarkCreateCommand.java | 7 ------ .../org/zmlx/hg4idea/ui/HgBookmarkDialog.form | 24 ++++--------------- .../org/zmlx/hg4idea/ui/HgBookmarkDialog.java | 17 +++++++------ .../test/repo/HgRepositoryReaderTest.java | 2 +- 5 files changed, 15 insertions(+), 37 deletions(-) diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java index 762b561c56d1..0b9842866794 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java @@ -154,7 +154,7 @@ public class HgBranchPopupActions { if (bookmarkDialog.isOK()) { try { final String name = bookmarkDialog.getName(); - new HgBookmarkCreateCommand(myProject, myPreselectedRepo, name, bookmarkDialog.getRevision(), + new HgBookmarkCreateCommand(myProject, myPreselectedRepo, name, bookmarkDialog.isActive()).execute(new HgCommandResultHandler() { @Override public void process(@Nullable HgCommandResult result) { diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgBookmarkCreateCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgBookmarkCreateCommand.java index c928ce0bb09f..89442efbc35e 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgBookmarkCreateCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgBookmarkCreateCommand.java @@ -19,18 +19,15 @@ public class HgBookmarkCreateCommand { @NotNull private final Project myProject; @NotNull private final VirtualFile myRepo; @Nullable private final String myBookmarkName; - @Nullable private final String myRevisionNumber; private final boolean isActive; public HgBookmarkCreateCommand(@NotNull Project project, @NotNull VirtualFile repo, @Nullable String bookmarkName, - @Nullable String revisionNumber, boolean active) { myProject = project; myRepo = repo; myBookmarkName = bookmarkName; - myRevisionNumber = revisionNumber; isActive = active; } @@ -40,10 +37,6 @@ public class HgBookmarkCreateCommand { } List arguments = new ArrayList(); arguments.add(myBookmarkName); - if (!StringUtil.isEmptyOrSpaces(myRevisionNumber)) { - arguments.add("--rev"); - arguments.add(myRevisionNumber); - } if (!isActive) { arguments.add("--inactive"); } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgBookmarkDialog.form b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgBookmarkDialog.form index e66baed3ed13..aa93ace47de0 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgBookmarkDialog.form +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgBookmarkDialog.form @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -37,27 +37,13 @@ - - - - - - - - - - - - - - - - - + + + diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgBookmarkDialog.java b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgBookmarkDialog.java index 161c5dfadce0..2340d875ee7d 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgBookmarkDialog.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgBookmarkDialog.java @@ -13,10 +13,9 @@ import javax.swing.*; * @author Nadya Zabrodina */ public class HgBookmarkDialog extends DialogWrapper { - private JPanel myContentPanel; - private JTextField myRevision; - private JTextField myBookmarkName; - private JCheckBox myActiveCheckbox; + @NotNull private JPanel myContentPanel; + @NotNull private JTextField myBookmarkName; + @NotNull private JCheckBox myActiveCheckbox; public HgBookmarkDialog(@Nullable Project project) { super(project, false); @@ -31,33 +30,33 @@ public class HgBookmarkDialog extends DialogWrapper { } @Override + @NotNull public JComponent getPreferredFocusedComponent() { return myBookmarkName; } @Override + @NotNull protected String getDimensionServiceKey() { return HgBookmarkDialog.class.getName(); } + @NotNull protected JComponent createCenterPanel() { return myContentPanel; } - @NotNull - public String getRevision() { - return myRevision.getText(); - } - public boolean isActive() { return !myActiveCheckbox.isSelected(); } + @Nullable public String getName() { return myBookmarkName.getText(); } @Override + @Nullable protected ValidationInfo doValidate() { String message = "You have to specify bookmark name."; if (StringUtil.isEmptyOrSpaces(getName())) { diff --git a/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRepositoryReaderTest.java b/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRepositoryReaderTest.java index 17af02238e0b..2a8051579c95 100644 --- a/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRepositoryReaderTest.java +++ b/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRepositoryReaderTest.java @@ -98,7 +98,7 @@ public class HgRepositoryReaderTest extends HgPlatformTest { assertEquals(myRepositoryReader.readCurrentBookmark(), "B_BookMark"); } - @NotNull + @NotNull private Collection readBookmarks() throws IOException { Collection bookmarks = new HashSet(); File bookmarksFile = new File(myHgDir, "bookmarks"); From e04fbe6cc9c6f31e80e9e1ef2dbf6a047d9dd5e6 Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Thu, 20 Jun 2013 18:29:01 +0400 Subject: [PATCH 19/49] IDEA-109185 Hg | Branches: if there is only one repository in the project show all icons inline, and don't show repository group --- .../src/org/zmlx/hg4idea/action/HgBranchPopup.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopup.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopup.java index 3eb7da84d8c6..9cbb1f0687a4 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopup.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopup.java @@ -94,18 +94,20 @@ public class HgBranchPopup { private ActionGroup createActions() { DefaultActionGroup popupGroup = new DefaultActionGroup(null, false); - fillPopupWithCurrentRepositoryActions(popupGroup, createRepositoriesActions()); - popupGroup.addSeparator(); return popupGroup; } + @Nullable private DefaultActionGroup createRepositoriesActions() { + List repositories = HgUtil.getHgRepositories(myProject); + if (repositories.size() == 1) { + return null; // if project has only one repository all branches, bookmarks and actions should be inline and no repository group needed + } DefaultActionGroup popupGroup = new DefaultActionGroup(null, false); popupGroup.addSeparator("Repositories"); - List repositories = HgUtil.getHgRepositories(myProject); boolean isMultiRepoConfig = repositories.size() > 1; for (VirtualFile repository : repositories) { HgRepository repo = HgRepositoryImpl.getFullInstance(repository, myProject, myProject); From 19f7f58433cdfa049f66930c45f881041ac80324 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 20 Jun 2013 18:16:26 +0400 Subject: [PATCH 20/49] Test fixed --- .../RemotelyConfigurableStatServiceTest.java | 131 +++++++++++------- 1 file changed, 83 insertions(+), 48 deletions(-) diff --git a/platform/platform-tests/testSrc/com/intellij/usagesStatistics/RemotelyConfigurableStatServiceTest.java b/platform/platform-tests/testSrc/com/intellij/usagesStatistics/RemotelyConfigurableStatServiceTest.java index cb2a332a61eb..6bf2093a2549 100644 --- a/platform/platform-tests/testSrc/com/intellij/usagesStatistics/RemotelyConfigurableStatServiceTest.java +++ b/platform/platform-tests/testSrc/com/intellij/usagesStatistics/RemotelyConfigurableStatServiceTest.java @@ -1,82 +1,117 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.usagesStatistics; import com.intellij.internal.statistic.StatisticsUploadAssistant; -import com.intellij.internal.statistic.connect.StatisticsHttpClientSender; import com.intellij.internal.statistic.connect.RemotelyConfigurableStatisticsService; import com.intellij.internal.statistic.connect.StatisticsConnectionService; +import com.intellij.internal.statistic.connect.StatisticsHttpClientSender; import com.intellij.internal.statistic.connect.StatisticsResult; -import junit.framework.Assert; -import junit.framework.TestCase; -import org.jetbrains.annotations.NonNls; +import com.intellij.testFramework.PlatformTestCase; +import com.intellij.util.net.NetUtils; import org.jetbrains.annotations.NotNull; +import org.junit.BeforeClass; +import org.junit.Test; import java.util.Set; -public class RemotelyConfigurableStatServiceTest extends TestCase { +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; - @NonNls - private static final String STAT_URL = "http://localhost:8080/stat.jsp"; +public class RemotelyConfigurableStatServiceTest { + private static String STAT_URL; + private static String STAT_CONFIG_URL; - @NonNls - private static final String STAT_CONFIG_URL = "http://localhost:8080/config.jsp"; + @SuppressWarnings("JUnitTestCaseWithNonTrivialConstructors") + public RemotelyConfigurableStatServiceTest() { + PlatformTestCase.initPlatformLangPrefix(); + } + @BeforeClass + public static void init() throws Exception { + int port = NetUtils.findAvailableSocketPort(); + STAT_URL = "http://localhost:" + port + "/stat.jsp"; + STAT_CONFIG_URL = "http://localhost:" + port + "/config.jsp"; + } + + @Test public void testStatisticsConnectionServiceDefaultSettings() { - final StatisticsConnectionService connectionService = new StatisticsConnectionService(STAT_CONFIG_URL, STAT_URL); + StatisticsConnectionService connectionService = new StatisticsConnectionService(STAT_CONFIG_URL, STAT_URL); + assertEquals(STAT_URL, connectionService.getServiceUrl()); - Assert.assertEquals(STAT_URL, connectionService.getServiceUrl()); - Assert.assertTrue(connectionService.isTransmissionPermitted()); - final String[] attributeNames = connectionService.getAttributeNames(); + assertTrue(connectionService.isTransmissionPermitted()); + String[] attributeNames = connectionService.getAttributeNames(); - Assert.assertEquals(attributeNames.length, 2); - Assert.assertEquals(attributeNames[0], "url"); - Assert.assertEquals(attributeNames[1], "permitted"); + assertEquals(attributeNames.length, 2); + assertEquals(attributeNames[0], "url"); + assertEquals(attributeNames[1], "permitted"); } + @Test public void testEmptyDataSending() { - RemotelyConfigurableStatisticsService service = new RemotelyConfigurableStatisticsService(new StatisticsConnectionService(), - new StatisticsHttpClientSender(), - new StatisticsUploadAssistant() { - @Override - public String getData(@NotNull Set disabledGroups) { - return ""; - } - }); - final StatisticsResult result = service.send(); - Assert.assertEquals(StatisticsResult.ResultCode.NOTHING_TO_SEND, result.getCode()); + RemotelyConfigurableStatisticsService service = + new RemotelyConfigurableStatisticsService(new StatisticsConnectionService(), + new StatisticsHttpClientSender(), + new StatisticsUploadAssistant() { + @Override + public String getData(@NotNull Set disabledGroups) { + return ""; + } + }); + StatisticsResult result = service.send(); + assertEquals(StatisticsResult.ResultCode.NOTHING_TO_SEND, result.getCode()); } + @Test public void testIncorrectUrlSending() { - RemotelyConfigurableStatisticsService service = new RemotelyConfigurableStatisticsService(new StatisticsConnectionService(STAT_CONFIG_URL, STAT_URL), - new StatisticsHttpClientSender(), - new StatisticsUploadAssistant() { - @Override - public String getData(@NotNull Set disabledGroups) { - return "group:key1=11"; - } - }); - final StatisticsResult result = service.send(); - Assert.assertEquals(StatisticsResult.ResultCode.SENT_WITH_ERRORS, result.getCode()); + RemotelyConfigurableStatisticsService service = + new RemotelyConfigurableStatisticsService(new StatisticsConnectionService(STAT_CONFIG_URL, STAT_URL), + new StatisticsHttpClientSender(), + new StatisticsUploadAssistant() { + @Override + public String getData(@NotNull Set disabledGroups) { + return "group:key1=11"; + } + }); + StatisticsResult result = service.send(); + assertEquals(StatisticsResult.ResultCode.SENT_WITH_ERRORS, result.getCode()); } + @Test public void testRemotelyDisabledTransmission() { - RemotelyConfigurableStatisticsService service = new RemotelyConfigurableStatisticsService(new StatisticsConnectionService() { - @Override - public Boolean isTransmissionPermitted() { - return false; - } - }, new StatisticsHttpClientSender(), - new StatisticsUploadAssistant()); - - final StatisticsResult result = service.send(); - Assert.assertEquals(StatisticsResult.ResultCode.NOT_PERMITTED_SERVER, result.getCode()); + RemotelyConfigurableStatisticsService service = + new RemotelyConfigurableStatisticsService(new StatisticsConnectionService() { + @Override + public Boolean isTransmissionPermitted() { + return false; + } + }, + new StatisticsHttpClientSender(), + new StatisticsUploadAssistant()); + StatisticsResult result = service.send(); + assertEquals(StatisticsResult.ResultCode.NOT_PERMITTED_SERVER, result.getCode()); } + @Test public void testErrorInRemoteConfiguration() { RemotelyConfigurableStatisticsService service = new RemotelyConfigurableStatisticsService(new StatisticsConnectionService(STAT_CONFIG_URL, null), new StatisticsHttpClientSender(), new StatisticsUploadAssistant()); - final StatisticsResult result = service.send(); - Assert.assertEquals(StatisticsResult.ResultCode.ERROR_IN_CONFIG, result.getCode()); + StatisticsResult result = service.send(); + assertEquals(StatisticsResult.ResultCode.ERROR_IN_CONFIG, result.getCode()); } } From 0840f9c268caebf82bcd6134a594a4a0b12e22a9 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Thu, 20 Jun 2013 16:30:41 +0400 Subject: [PATCH 21/49] IDEA-104500 Gradle: Allow to reuse common logic for other external systems Correctly handle 'unavailable project' situation --- .../notification/ExternalSystemIdeNotificationManager.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemIdeNotificationManager.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemIdeNotificationManager.java index 1adf63a91840..8242ca70c3f4 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemIdeNotificationManager.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemIdeNotificationManager.java @@ -41,7 +41,10 @@ public class ExternalSystemIdeNotificationManager { @NotNull String externalProjectName, @NotNull ProjectSystemId externalSystemId) { - ExternalSystemManager manager = ExternalSystemApiUtil.getManager(externalSystemId); + if (project.isDisposed() || !project.isOpen()) { + return; + } + ExternalSystemManager manager = ExternalSystemApiUtil.getManager(externalSystemId); if (!(manager instanceof ExternalSystemConfigurableAware)) { return; } From 8525992afb89820bd80e6457f2f422d592d9116a Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Thu, 20 Jun 2013 18:42:10 +0400 Subject: [PATCH 22/49] IDEA-109245 "Evaluate expression" should not wrap text automatically --- .../codeInsight/editorActions/AutoHardWrapHandler.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/AutoHardWrapHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/AutoHardWrapHandler.java index 57b4ac453581..d09e0bcf95ed 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/AutoHardWrapHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/AutoHardWrapHandler.java @@ -93,8 +93,10 @@ public class AutoHardWrapHandler { change.charTyped(editor, modificationStampBeforeTyping); } - // Return eagerly if we don't need to auto-wrap line on right margin exceeding. - if (project == null || !editor.getSettings().isWrapWhenTypingReachesRightMargin(project) + // Return eagerly if we don't need to auto-wrap line, e.g. because of right margin exceeding. + if (/*editor.isOneLineMode() + || */project == null + || !editor.getSettings().isWrapWhenTypingReachesRightMargin(project) || (TemplateManager.getInstance(project) != null && TemplateManager.getInstance(project).getActiveTemplate(editor) != null)) { return; @@ -108,6 +110,10 @@ public class AutoHardWrapHandler { // Check if right margin is exceeded. int margin = editor.getSettings().getRightMargin(project); + if (margin <= 0) { + return; + } + VisualPosition visEndLinePosition = editor.offsetToVisualPosition(endOffset); if (margin > visEndLinePosition.column) { if (change != null) { From ae9ae8849805d4cae68e13193cd016ddc2272ce8 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 20 Jun 2013 19:51:37 +0400 Subject: [PATCH 23/49] allow to select console from tests tree with tab (IDEA-66537) and return --- .../src/com/intellij/openapi/editor/actions/TabAction.java | 2 +- .../intellij/execution/testframework/ui/TestResultsPanel.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/TabAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/TabAction.java index ec2556f9e89b..5064ad11ffed 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/TabAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/TabAction.java @@ -57,7 +57,7 @@ public class TabAction extends EditorAction { @Override public boolean isEnabled(Editor editor, DataContext dataContext) { - return !editor.isOneLineMode() && !((EditorEx)editor).isEmbeddedIntoDialogWrapper(); + return !editor.isOneLineMode() && !((EditorEx)editor).isEmbeddedIntoDialogWrapper() && !editor.isViewer(); } } diff --git a/platform/testRunner/src/com/intellij/execution/testframework/ui/TestResultsPanel.java b/platform/testRunner/src/com/intellij/execution/testframework/ui/TestResultsPanel.java index 7429069c3b33..cf3bed4b403d 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/ui/TestResultsPanel.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/ui/TestResultsPanel.java @@ -139,6 +139,7 @@ public abstract class TestResultsPanel extends JPanel implements Disposable { private static JComponent createOutputTab(JComponent console, AnAction[] consoleActions) { JPanel outputTab = new JPanel(new BorderLayout()); + console.setFocusable(true); outputTab.add(console, BorderLayout.CENTER); final DefaultActionGroup actionGroup = new DefaultActionGroup(consoleActions); final ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, actionGroup, false); From 875c28089f63a3df1272954d2ce6e68e17ec2cd7 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 20 Jun 2013 20:55:53 +0400 Subject: [PATCH 24/49] only apply breakpoint isInScope() check to those classes that resolve to source content files. Disable scope check (and thus allow breakpoint requests) if there is at least one class found in library classes (IDEA-109283) --- .../debugger/ui/breakpoints/LineBreakpoint.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java index a778e1c126bb..9ca1bd12f697 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java @@ -277,12 +277,14 @@ public class LineBreakpoint extends BreakpointWithHighlighter { LOG.debug(msg.toString()); } - if (psiFile != null) { - final VirtualFile vFile = psiFile.getVirtualFile(); - if (vFile != null && fileIndex.isInSourceContent(vFile)) { - list.add(vFile); - } + if (psiFile == null) { + return null; } + final VirtualFile vFile = psiFile.getVirtualFile(); + if (vFile == null || !fileIndex.isInSourceContent(vFile)) { + return null; // this will switch off the check if at least one class is from libraries + } + list.add(vFile); } return list; } From 2e36ae10882c1298223572e8c49f1ade4d3ac8ce Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 20 Jun 2013 21:14:21 +0400 Subject: [PATCH 25/49] allow to inline array definition when accessExpression is used for write; exclude new expressions --- .../refactoring/inline/InlineLocalHandler.java | 5 +++-- .../refactoring/inline/InlineParameterHandler.java | 2 +- .../inlineLocal/ArrayMethodCallInitialized.java | 11 +++++++++++ .../inlineLocal/ArrayMethodCallInitialized.java.after | 10 ++++++++++ .../intellij/refactoring/inline/InlineLocalTest.java | 4 ++++ 5 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 java/java-tests/testData/refactoring/inlineLocal/ArrayMethodCallInitialized.java create mode 100644 java/java-tests/testData/refactoring/inlineLocal/ArrayMethodCallInitialized.java.after diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java index 317117537ac7..3c90eecd11f9 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java @@ -195,7 +195,7 @@ public class InlineLocalHandler extends JavaInlineActionHandler { } } - final PsiElement writeAccess = checkRefsInAugmentedAssignmentOrUnaryModified(refsToInline); + final PsiElement writeAccess = checkRefsInAugmentedAssignmentOrUnaryModified(refsToInline, defToInline); if (writeAccess != null) { HighlightManager.getInstance(project).addOccurrenceHighlights(editor, new PsiElement[]{writeAccess}, writeAttributes, true, null); String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("variable.is.accessed.for.writing", localName)); @@ -273,12 +273,13 @@ public class InlineLocalHandler extends JavaInlineActionHandler { } @Nullable - public static PsiElement checkRefsInAugmentedAssignmentOrUnaryModified(final PsiElement[] refsToInline) { + public static PsiElement checkRefsInAugmentedAssignmentOrUnaryModified(final PsiElement[] refsToInline, PsiElement defToInline) { for (PsiElement element : refsToInline) { PsiElement parent = element.getParent(); if (parent instanceof PsiArrayAccessExpression) { if (((PsiArrayAccessExpression)parent).getIndexExpression() == element) continue; + if (defToInline instanceof PsiExpression && !(defToInline instanceof PsiNewExpression)) continue; element = parent; parent = parent.getParent(); } diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterHandler.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterHandler.java index e22f0b86e2cd..58d4d1eb282d 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterHandler.java @@ -125,7 +125,7 @@ public class InlineParameterHandler extends JavaInlineActionHandler { if (rExpr != null) { final PsiElement[] refs = DefUseUtil.getRefs(codeBlock, psiParameter, refExpr); - if (InlineLocalHandler.checkRefsInAugmentedAssignmentOrUnaryModified(refs) == null) { + if (InlineLocalHandler.checkRefsInAugmentedAssignmentOrUnaryModified(refs, def) == null) { new WriteCommandAction(project) { @Override protected void run(Result result) throws Throwable { diff --git a/java/java-tests/testData/refactoring/inlineLocal/ArrayMethodCallInitialized.java b/java/java-tests/testData/refactoring/inlineLocal/ArrayMethodCallInitialized.java new file mode 100644 index 000000000000..aa7c17cf6fb1 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineLocal/ArrayMethodCallInitialized.java @@ -0,0 +1,11 @@ +public class A { + + public void testInlineRefactoring() { + int[] array = ar(); + array[1] = 22; + } + + private int[] ar() { + return new int[0]; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inlineLocal/ArrayMethodCallInitialized.java.after b/java/java-tests/testData/refactoring/inlineLocal/ArrayMethodCallInitialized.java.after new file mode 100644 index 000000000000..72d6b9f2b18e --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineLocal/ArrayMethodCallInitialized.java.after @@ -0,0 +1,10 @@ +public class A { + + public void testInlineRefactoring() { + ar()[1] = 22; + } + + private int[] ar() { + return new int[0]; + } +} \ 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 709db9911ea5..811d52f817c1 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineLocalTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineLocalTest.java @@ -140,6 +140,10 @@ public class InlineLocalTest extends LightCodeInsightTestCase { "Variable 'arr' is accessed for writing."); } + public void testArrayMethodCallInitialized() throws Exception { + doTest(true); + } + public void testArrayIndex() throws Exception { doTest(true); } From 1a604bb50de3f19e773d6f9e2348ff63f29a45b4 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 20 Jun 2013 21:15:03 +0400 Subject: [PATCH 26/49] process methods from all supers when cached --- .../src/com/intellij/psi/impl/PsiClassImplUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java index 71dff8a0704e..a0f3e9a3e045 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java @@ -570,8 +570,8 @@ public class PsiClassImplUtil { if (!processor.execute(candidateMethod, state.put(PsiSubstitutor.KEY, finalSubstitutor))) { resolved = true; } - if (resolved) return false; } + if (resolved) return false; if (visited != null) { for (Pair aList : list) { From daad7481ba771ec9ab548fe67f768a7eb8f5deff Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 20 Jun 2013 09:24:50 +0200 Subject: [PATCH 27/49] test external modification of a stubbed file with smart pointer switches the file to AST --- .../com/intellij/psi/StubAstSwitchTest.groovy | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/psi/StubAstSwitchTest.groovy b/java/java-tests/testSrc/com/intellij/psi/StubAstSwitchTest.groovy index b9a5732b83c6..da446c7a93b1 100644 --- a/java/java-tests/testSrc/com/intellij/psi/StubAstSwitchTest.groovy +++ b/java/java-tests/testSrc/com/intellij/psi/StubAstSwitchTest.groovy @@ -14,15 +14,16 @@ * limitations under the License. */ package com.intellij.psi - import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.fileEditor.FileDocumentManager +import com.intellij.openapi.vfs.VfsUtil import com.intellij.psi.impl.source.PsiFileImpl +import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.util.PsiTreeUtil -import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase import com.intellij.reference.SoftReference +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase import java.util.concurrent.CountDownLatch - /** * @author peter */ @@ -79,4 +80,21 @@ class StubAstSwitchTest extends LightCodeInsightFixtureTestCase { } latch.await() } + + public void "test external modification of a stubbed file with smart pointer switches the file to AST"() { + PsiFile file = myFixture.addFileToProject("A.java", "class A {}") + def oldClass = JavaPsiFacade.getInstance(project).findClass("A", GlobalSearchScope.allScope(project)) + def pointer = SmartPointerManager.getInstance(project).createSmartPsiElementPointer(oldClass) + + def document = FileDocumentManager.instance.getCachedDocument(file.virtualFile) + assert document + assert file == PsiDocumentManager.getInstance(project).getCachedPsiFile(document) + assert document == PsiDocumentManager.getInstance(project).getCachedDocument(file) + + assert ((PsiFileImpl)file).stub + + ApplicationManager.application.runWriteAction { VfsUtil.saveText(file.virtualFile, "import java.util.*; class A {}; class B {}") } + assert pointer.element == oldClass + assert ((PsiFileImpl)file).treeElement + } } From db323e6921f7e84265be6fd7512135123be98029 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 20 Jun 2013 19:40:56 +0200 Subject: [PATCH 28/49] keep several trees in a view provider synchronized in presence of gc --- .../psi/SingleRootFileViewProvider.java | 39 ++++++++-------- .../psi/impl/DocumentCommitProcessor.java | 4 +- .../psi/impl/PsiDocumentManagerBase.java | 45 +++++-------------- .../psi/impl/PsiToDocumentSynchronizer.java | 2 + .../intellij/psi/impl/source/PsiFileImpl.java | 4 -- .../psi/impl/DocumentCommitThread.java | 2 +- 6 files changed, 32 insertions(+), 64 deletions(-) diff --git a/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java b/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java index 3fa5eabc1224..a8c94f3545f1 100644 --- a/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java +++ b/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java @@ -30,7 +30,6 @@ import com.intellij.openapi.fileTypes.*; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.FileIndexFacade; -import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.openapi.vfs.NonPhysicalFileSystem; @@ -47,6 +46,7 @@ import com.intellij.psi.impl.source.tree.FileElement; import com.intellij.testFramework.LightVirtualFile; import com.intellij.util.LocalTimeCounter; import com.intellij.util.ReflectionCache; +import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -181,10 +181,10 @@ public class SingleRootFileViewProvider extends UserDataHolderBase implements Fi setContent(cachedDocument == null ? new VirtualFileContent() : new DocumentContent()); } - public void beforeDocumentChanged() { - final PsiFile psiFile = getCachedPsi(getBaseLanguage()); - if (psiFile instanceof PsiFileImpl && ((PsiFileImpl)psiFile).isContentsLoaded() && getContent() instanceof DocumentContent) { - setContent(new PsiFileContent((PsiFileImpl)psiFile, getModificationStamp())); + public void beforeDocumentChanged(@Nullable PsiFile psiCause) { + PsiFile psiFile = psiCause != null ? psiCause : getPsi(getBaseLanguage()); + if (psiFile instanceof PsiFileImpl) { + setContent(new PsiFileContent((PsiFileImpl)psiFile, psiCause == null ? getModificationStamp() : LocalTimeCounter.currentTime())); } } @@ -536,36 +536,33 @@ public class SingleRootFileViewProvider extends UserDataHolderBase implements Fi private class PsiFileContent implements Content { private final PsiFileImpl myFile; - private CharSequence myContent = null; + private volatile String myContent = null; private final long myModificationStamp; + + @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") + private final List myFileElementHardRefs = new SmartList(); private PsiFileContent(final PsiFileImpl file, final long modificationStamp) { myFile = file; myModificationStamp = modificationStamp; + for (PsiFile aFile : getAllFiles()) { + if (aFile instanceof PsiFileImpl) { + myFileElementHardRefs.add(((PsiFileImpl)aFile).calcTreeElement()); + } + } } @Override public CharSequence getText() { - if (!myFile.isContentsLoaded()) { - unsetPsiContent(); - return getContents(); + if (myContent == null) { + ApplicationManager.getApplication().assertReadAccessAllowed(); + myContent = myFile.calcTreeElement().getText(); } - if (myContent != null) return myContent; - return myContent = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - @NotNull - public CharSequence compute() { - return myFile.calcTreeElement().getText(); - } - }); + return myContent; } @Override public long getModificationStamp() { - if (!myFile.isContentsLoaded()) { - unsetPsiContent(); - return SingleRootFileViewProvider.this.getModificationStamp(); - } return myModificationStamp; } } diff --git a/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java b/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java index 75d9ef61f7ff..7673edd91102 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java +++ b/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java @@ -106,10 +106,8 @@ public abstract class DocumentCommitProcessor { @Nullable("returns runnable to execute under write action in AWT to finish the commit") public Processor doCommit(@NotNull final CommitTask task, @NotNull final PsiFile file, - final boolean synchronously, - @NotNull PsiDocumentManager documentManager) { + final boolean synchronously) { Document document = task.document; - ((PsiDocumentManagerBase)documentManager).clearTreeHardRef(document); final TextBlock textBlock = TextBlock.get(file); if (textBlock.isEmpty()) return null; final long startDocModificationTimeStamp = document.getModificationStamp(); diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java b/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java index 526ed14ed7ce..b3dc474d995c 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java +++ b/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java @@ -17,7 +17,6 @@ package com.intellij.psi.impl; import com.intellij.injected.editor.DocumentWindow; -import com.intellij.lang.ASTNode; import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; @@ -558,12 +557,6 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen return !myIsCommitInProgress && !myUncommittedDocuments.isEmpty(); } - private final Key TEMP_TREE_IN_DOCUMENT_KEY = Key.create("TEMP_TREE_IN_DOCUMENT_KEY"); - - void clearTreeHardRef(@NotNull Document document) { - document.putUserData(TEMP_TREE_IN_DOCUMENT_KEY, null); - } - @Override public void beforeDocumentChange(DocumentEvent event) { final Document document = event.getDocument(); @@ -576,39 +569,23 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen if (virtualFile.getFileType().isBinary()) return; final List files = viewProvider.getAllFiles(); - boolean hasLockedBlocks = false; + PsiFile psiCause = null; for (PsiFile file : files) { - if (file == null) continue; + mySmartPointerManager.fastenBelts(file, event.getOffset(), null); - if (file.isPhysical() && mySmartPointerManager != null) { // mock tests - mySmartPointerManager.fastenBelts(file, event.getOffset(), null); - } - - final TextBlock textBlock = TextBlock.get(file); - if (textBlock.isLocked()) { - hasLockedBlocks = true; - continue; - } - - if (file instanceof PsiFileImpl) { - myIsCommitInProgress = true; - try { - PsiFileImpl psiFile = (PsiFileImpl)file; - // tree should be initialized and be kept until commit - document.putUserData(TEMP_TREE_IN_DOCUMENT_KEY, psiFile.calcTreeElement()); - } - finally { - myIsCommitInProgress = false; - } + if (TextBlock.get(file).isLocked()) { + psiCause = file; } } - if (!hasLockedBlocks) + if (psiCause == null) { beforeDocumentChangeOnUnlockedDocument(viewProvider); + } + + ((SingleRootFileViewProvider)viewProvider).beforeDocumentChanged(psiCause); } protected void beforeDocumentChangeOnUnlockedDocument(@NotNull final FileViewProvider viewProvider) { - ((SingleRootFileViewProvider)viewProvider).beforeDocumentChanged(); } @Override @@ -622,10 +599,8 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen final List files = viewProvider.getAllFiles(); boolean commitNecessary = true; for (PsiFile file : files) { - if (file == null || file instanceof PsiFileImpl && ((PsiFileImpl)file).getTreeElement() == null) continue; - if (mySmartPointerManager != null) { // mock tests - mySmartPointerManager.unfastenBelts(file, event.getOffset()); - } + mySmartPointerManager.unfastenBelts(file, event.getOffset()); + final TextBlock textBlock = TextBlock.get(file); if (textBlock.isLocked()) { commitNecessary = false; diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java b/platform/core-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java index 13f477955eea..0d7e1dde2697 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java +++ b/platform/core-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java @@ -98,6 +98,8 @@ public class PsiToDocumentSynchronizer extends PsiTreeChangeAdapter { PsiDocumentManagerBase.checkConsistency(psiFile, document); } } + + psiFile.getViewProvider().contentsSynchronized(); } @Override diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java index 1ce39d4f353e..2a38d15d1453 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java @@ -214,10 +214,6 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF myStub = null; myTreeElementPointer = createTreeElementPointer(treeElement); - if (document != null && isPhysical()) { - TextBlock.get(this).clear(); - } - if (LOG.isDebugEnabled() && viewProvider.isPhysical()) { LOG.debug("Loaded text for file " + viewProvider.getVirtualFile().getPresentableUrl()); } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java b/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java index 768a905de142..bd7d8f950ac8 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java @@ -408,7 +408,7 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run List psiFiles = viewProvider.getAllFiles(); for (PsiFile file : psiFiles) { if (file.isValid() && file != excludeFile) { - Processor finishProcessor = doCommit(task, file, synchronously, documentManager); + Processor finishProcessor = doCommit(task, file, synchronously); if (finishProcessor != null) { finishProcessors.add(finishProcessor); } From 4a019151cb9b5542ea5ba9ed2f07b29cee0951f0 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Thu, 20 Jun 2013 23:28:04 +0400 Subject: [PATCH 29/49] DB rename fix: revert isInProject change & suppress warning for non-phys elements --- .../core-impl/src/com/intellij/psi/impl/PsiManagerImpl.java | 1 - .../intellij/refactoring/rename/PsiElementRenameHandler.java | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiManagerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/PsiManagerImpl.java index ce823bd41d0c..107f0526f8ee 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/PsiManagerImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/PsiManagerImpl.java @@ -118,7 +118,6 @@ public class PsiManagerImpl extends PsiManagerEx { @Override public boolean isInProject(@NotNull PsiElement element) { PsiFile file = element.getContainingFile(); - if (file == null && !element.isPhysical()) return element.getProject() == myProject; if (file != null && file.isPhysical() && file.getViewProvider().getVirtualFile() instanceof LightVirtualFile) return true; if (element instanceof PsiDirectoryContainer) { 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 3a92b33a85e3..158aac456e0c 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/PsiElementRenameHandler.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/PsiElementRenameHandler.java @@ -83,7 +83,9 @@ public class PsiElementRenameHandler implements RenameHandler { return; } - if (nameSuggestionContext != null && !PsiManager.getInstance(project).isInProject(nameSuggestionContext)) { + if (nameSuggestionContext != null && + nameSuggestionContext.isPhysical() && + !PsiManager.getInstance(project).isInProject(nameSuggestionContext)) { final String message = "Selected element is used from non-project files. These usages won't be renamed. Proceed anyway?"; if (ApplicationManager.getApplication().isUnitTestMode()) throw new CommonRefactoringUtil.RefactoringErrorHintException(message); if (Messages.showYesNoDialog(project, message, From 3d0b40140c81adce5dda7899527143d70a0adb94 Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 20 Jun 2013 21:12:17 +0400 Subject: [PATCH 30/49] IDEA-109234: The post-processing task in an Android artifact runs before the artifact is completely built --- .../artifacts/ArtifactBuildTaskProvider.java | 2 +- .../incremental/artifacts/IncArtifactBuilder.java | 1 + .../jps/ant/build/AntArtifactBuildTaskProvider.java | 12 ++++++++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/artifacts/ArtifactBuildTaskProvider.java b/jps/jps-builders/src/org/jetbrains/jps/builders/artifacts/ArtifactBuildTaskProvider.java index 0569e1917886..17cfe2f33162 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/artifacts/ArtifactBuildTaskProvider.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/artifacts/ArtifactBuildTaskProvider.java @@ -26,7 +26,7 @@ import java.util.List; */ public abstract class ArtifactBuildTaskProvider { public enum ArtifactBuildPhase { - PRE_PROCESSING, POST_PROCESSING + PRE_PROCESSING, FINISHING_BUILD, POST_PROCESSING } @NotNull diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/IncArtifactBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/IncArtifactBuilder.java index e4350bd1d50b..a83164eeba34 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/IncArtifactBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/IncArtifactBuilder.java @@ -173,6 +173,7 @@ public class IncArtifactBuilder extends TargetBuilder Date: Fri, 21 Jun 2013 09:16:59 +0200 Subject: [PATCH 31/49] invalidate indices on PCE --- .../src/com/intellij/util/indexing/FileBasedIndexImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java index 04b1009b03ec..d459932499a3 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java @@ -1764,6 +1764,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { } catch (ProcessCanceledException e) { cleanFileContent(fc, psiFile); + myChangedFilesCollector.invalidateIndicesForFile(file, true); throw e; } catch (StorageException e) { From b72a74f9a50bc67de3c4a257517235e1c8fc8103 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Fri, 21 Jun 2013 09:21:08 +0200 Subject: [PATCH 32/49] contents_changed produces children_changed event notification --- .../pom/wrappers/PsiEventWrapperAspect.java | 7 +- .../intellij/codeInsight/XmlEventsTest.java | 70 +++++++++++++++++-- 2 files changed, 67 insertions(+), 10 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/pom/wrappers/PsiEventWrapperAspect.java b/platform/lang-impl/src/com/intellij/pom/wrappers/PsiEventWrapperAspect.java index c30280439874..363c62248b61 100644 --- a/platform/lang-impl/src/com/intellij/pom/wrappers/PsiEventWrapperAspect.java +++ b/platform/lang-impl/src/com/intellij/pom/wrappers/PsiEventWrapperAspect.java @@ -32,6 +32,7 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.impl.PsiManagerImpl; import com.intellij.psi.impl.PsiTreeChangeEventImpl; import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.impl.source.tree.CompositeElement; import java.util.Collections; @@ -104,10 +105,10 @@ public class PsiEventWrapperAspect implements PomModelAspect{ break; case ChangeInfo.CONTENTS_CHANGED: psiEvent.setOffset(treeElement.getStartOffset()); - psiEvent.setOldChild(psiChild); - psiEvent.setNewChild(psiChild); + psiEvent.setParent(psiChild); psiEvent.setOldLength(changeByChild.getOldLength()); - manager.childReplaced(psiEvent); + psiEvent.setGeneric(treeElement instanceof CompositeElement); + manager.childrenChanged(psiEvent); break; case ChangeInfo.REMOVED: psiEvent.setOffset(changesByElement.getChildOffsetInNewTree(treeElement)); diff --git a/xml/tests/src/com/intellij/codeInsight/XmlEventsTest.java b/xml/tests/src/com/intellij/codeInsight/XmlEventsTest.java index 5ccbdba311a2..457a949f2fc3 100644 --- a/xml/tests/src/com/intellij/codeInsight/XmlEventsTest.java +++ b/xml/tests/src/com/intellij/codeInsight/XmlEventsTest.java @@ -15,16 +15,12 @@ import com.intellij.pom.event.PomChangeSet; import com.intellij.pom.event.PomModelEvent; import com.intellij.pom.event.PomModelListener; import com.intellij.pom.xml.XmlAspect; -import com.intellij.psi.PsiDocumentManager; -import com.intellij.psi.PsiFile; -import com.intellij.psi.XmlElementFactory; +import com.intellij.psi.*; import com.intellij.psi.impl.source.PsiFileImpl; -import com.intellij.psi.xml.XmlAttribute; -import com.intellij.psi.xml.XmlFile; -import com.intellij.psi.xml.XmlTag; -import com.intellij.psi.xml.XmlText; +import com.intellij.psi.xml.*; import com.intellij.testFramework.LightCodeInsightTestCase; import com.intellij.testFramework.PlatformTestUtil; +import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.FileNotFoundException; @@ -235,4 +231,64 @@ public class XmlEventsTest extends LightCodeInsightTestCase { text = StringUtil.convertLineSeparators(text); return text; } + + public void testDocumentChange() throws Exception { + final String xml = "" + + "\n" + + "\n" + + " \n" + + "\n" + + "\n" + + " \n" + + " \n" + + "\n" + + "\n"; + PsiFile file = createFile("file.xml", xml); + assertTrue(file instanceof XmlFile); + XmlDocument xmlDocument = ((XmlFile)file).getDocument(); + assertNotNull(xmlDocument); + final XmlTag tagFromText = xmlDocument.getRootTag(); + assertNotNull(tagFromText); + final PsiFileImpl containingFile = (PsiFileImpl)tagFromText.getContainingFile(); + final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(getProject()); + final Document document = documentManager.getDocument(containingFile); + assertNotNull(document); + + final TestListener listener = new TestListener(); + PsiManager.getInstance(getProject()).addPsiTreeChangeListener(listener); + + CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + int positionToInsert = xml.indexOf(" \n"; + document.insertString(positionToInsert, stringToInsert); + documentManager.commitDocument(document); + } + }); + } + }, "", null); + + PsiManager.getInstance(getProject()).removePsiTreeChangeListener(listener); + } + + private static class TestListener extends PsiTreeChangeAdapter { + @Override + public void childReplaced(@NotNull PsiTreeChangeEvent event) { + if (event.getNewChild() != null) { + assertNotSame("Received identical before and after children in childReplaced;", event.getOldChild(), event.getNewChild()); + } + } + } } From 5dcaad5100c7b6b63c1b6a7dcde461689b46438e Mon Sep 17 00:00:00 2001 From: Sascha Weinreuter Date: Fri, 21 Jun 2013 09:53:13 +0200 Subject: [PATCH 33/49] EA-47221 - NPE: CompactSyntaxLexerAdapter.getSourceLocation - this is always caused by broken IDEA/JDK installations --- .../relaxNG/compact/lexer/CompactSyntaxLexerAdapter.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/lexer/CompactSyntaxLexerAdapter.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/lexer/CompactSyntaxLexerAdapter.java index 7ae13da3c863..f16484decef1 100644 --- a/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/lexer/CompactSyntaxLexerAdapter.java +++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/lexer/CompactSyntaxLexerAdapter.java @@ -199,7 +199,7 @@ public class CompactSyntaxLexerAdapter extends LexerBase { return new CompactSyntaxTokenManager(new SimpleCharStream(preprocessor, 1, 1), initialState); } catch (NoSuchMethodError e) { final Class managerClass = CompactSyntaxTokenManager.class; - LOG.error("Unsupported version of RNGOM in classpath", e, + LOG.error("Unsupported version of RNGOM in classpath. Please check your IDEA and JDK installation.", e, "Actual parameter types: " + Arrays.toString(managerClass.getConstructors()[0].getParameterTypes()), "Location of " + managerClass.getName() + ": " + getSourceLocation(managerClass), "Location of " + CharStream.class.getName() + ": " + getSourceLocation(CharStream.class)); @@ -215,7 +215,9 @@ public class CompactSyntaxLexerAdapter extends LexerBase { return location.toExternalForm(); } } - final URL resource = clazz.getClassLoader().getResource(clazz.getName().replace('.', '/') + ".class"); + final String name = clazz.getName().replace('.', '/') + ".class"; + final ClassLoader loader = clazz.getClassLoader(); + final URL resource = loader != null ? loader.getResource(name) : ClassLoader.getSystemResource(name); return resource != null ? resource.toExternalForm() : ""; } From b29d887f92d8f5a79f7d12334ae17a12d9b14507 Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Fri, 21 Jun 2013 11:47:18 +0400 Subject: [PATCH 34/49] IDEA-109183 Hg Create new BookMark, and New Branch action: mnemonics added --- platform/dvcs/src/com/intellij/dvcs/ui/NewBranchAction.java | 2 +- .../src/org/zmlx/hg4idea/action/HgBranchPopupActions.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/dvcs/src/com/intellij/dvcs/ui/NewBranchAction.java b/platform/dvcs/src/com/intellij/dvcs/ui/NewBranchAction.java index 29481e236c2a..6fba1d26418b 100644 --- a/platform/dvcs/src/com/intellij/dvcs/ui/NewBranchAction.java +++ b/platform/dvcs/src/com/intellij/dvcs/ui/NewBranchAction.java @@ -33,7 +33,7 @@ public abstract class NewBranchAction extends DumbAwareAct protected Project myProject; public NewBranchAction(@NotNull Project project, @NotNull List repositories) { - super("New Branch", "Create and checkout new branch", IconUtil.getAddIcon()); + super("New &Branch", "Create and checkout new branch", IconUtil.getAddIcon()); myRepositories = repositories; myProject = project; } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java index 0b9842866794..7ab7b6043bec 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java @@ -132,7 +132,7 @@ public class HgBranchPopupActions { @NotNull final VirtualFile myPreselectedRepo; HgNewBookmarkAction(@NotNull Project project, @NotNull List repositories, @NotNull VirtualFile preselectedRepo) { - super("New Bookmark", "Create new bookmark", null); + super("New Book&mark", "Create new bookmark", null); myProject = project; myRepositories = repositories; myPreselectedRepo = preselectedRepo; From 31a6bf4f73075d4d418b231e8c3c0c111251f3fa Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Fri, 21 Jun 2013 12:01:56 +0400 Subject: [PATCH 35/49] IDEA-109188 Hg | Create New Branch error message title & description changed --- .../org/zmlx/hg4idea/action/HgAbstractGlobalAction.java | 7 ++++++- .../src/org/zmlx/hg4idea/action/HgBranchPopupActions.java | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java index 930cae34318b..8b306d19cda4 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java @@ -20,6 +20,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.zmlx.hg4idea.HgVcs; import org.zmlx.hg4idea.util.HgUtil; @@ -63,8 +64,12 @@ abstract class HgAbstractGlobalAction extends AnAction { protected abstract void execute(Project project, Collection repositories, @Nullable VirtualFile selectedRepo); public static void handleException(Project project, Exception e) { + handleException(project, "Error", e); + } + + public static void handleException(Project project, @NotNull String title, Exception e) { LOG.info(e); - new HgCommandResultNotifier(project).notifyError(null, "Error", e.getMessage()); + new HgCommandResultNotifier(project).notifyError(null, title, e.getMessage()); } protected void markDirtyAndHandleErrors(Project project, VirtualFile repository) { diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java index 7ab7b6043bec..83f8d26eb7b8 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java @@ -121,7 +121,7 @@ public class HgBranchPopupActions { }); } catch (HgCommandException exception) { - HgAbstractGlobalAction.handleException(myProject, exception); + HgAbstractGlobalAction.handleException(myProject, "Can't create new branch: ", exception); } } } From 03878f2d3fa46463806a6ee4a00728927f40a2c5 Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Fri, 21 Jun 2013 12:08:56 +0400 Subject: [PATCH 36/49] Annotations added in handleError method for actions --- .../src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java index 8b306d19cda4..c8ab2c58a895 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java @@ -63,11 +63,11 @@ abstract class HgAbstractGlobalAction extends AnAction { protected abstract void execute(Project project, Collection repositories, @Nullable VirtualFile selectedRepo); - public static void handleException(Project project, Exception e) { + public static void handleException(@Nullable Project project, @NotNull Exception e) { handleException(project, "Error", e); } - public static void handleException(Project project, @NotNull String title, Exception e) { + public static void handleException(@Nullable Project project, @NotNull String title, @NotNull Exception e) { LOG.info(e); new HgCommandResultNotifier(project).notifyError(null, title, e.getMessage()); } From cafcee7f12b1e55eb54cb7935f72cb57218d218f Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Fri, 21 Jun 2013 12:24:40 +0400 Subject: [PATCH 37/49] Change create bookmark dialog form (make temporally alignment with extra spaces). Need to modify. --- plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgBookmarkDialog.form | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgBookmarkDialog.form b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgBookmarkDialog.form index aa93ace47de0..158977c74d68 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgBookmarkDialog.form +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgBookmarkDialog.form @@ -26,7 +26,7 @@ - + @@ -43,7 +43,7 @@ - + From 66ec8b0b503659df3e4b2e6de0477127b9b2e4bb Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 21 Jun 2013 12:17:31 +0400 Subject: [PATCH 38/49] EA-47245 - assert: FileManagerImpl.getCachedPsiFile --- .../xml/impl/schema/SchemaDefinitionsSearch.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/xml/impl/src/com/intellij/xml/impl/schema/SchemaDefinitionsSearch.java b/xml/impl/src/com/intellij/xml/impl/schema/SchemaDefinitionsSearch.java index fe3a323cc28c..6811ca9a9f2a 100644 --- a/xml/impl/src/com/intellij/xml/impl/schema/SchemaDefinitionsSearch.java +++ b/xml/impl/src/com/intellij/xml/impl/schema/SchemaDefinitionsSearch.java @@ -63,13 +63,18 @@ public class SchemaDefinitionsSearch implements QueryExecutor() { + @Override + public String compute() { + return XmlNamespaceIndex.getNamespace(vf, project, file); + } + }); thisNs = thisNs == null ? getDefaultNs(file) : thisNs; // so thisNs can be null if (thisNs == null) return false; From b77a7c0de60401c3893c4a39e610f6c3b145832e Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 21 Jun 2013 12:22:05 +0400 Subject: [PATCH 39/49] logging for EA-47239 - AIOOBE: JavaWithTryFinallySurrounder.surroundStatements --- .../surroundWith/JavaWithTryFinallySurrounder.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithTryFinallySurrounder.java b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithTryFinallySurrounder.java index c9a13f65e8a1..e757ddeacc17 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithTryFinallySurrounder.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithTryFinallySurrounder.java @@ -16,6 +16,7 @@ package com.intellij.codeInsight.generation.surroundWith; import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.EditorModificationUtil; @@ -28,6 +29,8 @@ import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NonNls; class JavaWithTryFinallySurrounder extends JavaStatementsSurrounder{ + private static final Logger LOG = Logger.getInstance("#" + JavaWithTryFinallySurrounder.class.getName()); + @Override public String getTemplateDescription() { return CodeInsightBundle.message("surround.with.try.finally.template"); @@ -67,7 +70,9 @@ class JavaWithTryFinallySurrounder extends JavaStatementsSurrounder{ final Document document = editor.getDocument(); PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(document); editor.getSelectionModel().removeSelection(); - final PsiStatement firstTryStmt = tryBlock.getStatements()[0]; + final PsiStatement[] tryBlockStatements = tryBlock.getStatements(); + LOG.assertTrue(tryBlockStatements.length > 0, tryBlock.getText()); + final PsiStatement firstTryStmt = tryBlockStatements[0]; final int indent = firstTryStmt.getTextOffset() - document.getLineStartOffset(document.getLineNumber(firstTryStmt.getTextOffset())); EditorModificationUtil.insertStringAtCaret(editor, StringUtil.repeat(" ", indent), false, true); return new TextRange(editor.getCaretModel().getOffset(), editor.getCaretModel().getOffset()); From 8f840dc69d01db378d92629176192fe1a62385e0 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Fri, 21 Jun 2013 10:43:58 +0200 Subject: [PATCH 40/49] extra usage of scheduleForUpdate removed, the method made private --- .../src/com/intellij/util/indexing/FileBasedIndexImpl.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java index d459932499a3..fc5961c441e0 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java @@ -2004,7 +2004,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { } } - public void scheduleForUpdate(VirtualFile file) { + private void scheduleForUpdate(VirtualFile file) { myFilesToUpdate.add(file); } @@ -2207,10 +2207,6 @@ public class FileBasedIndexImpl extends FileBasedIndex { myForceUpdateSemaphore.down(); // process only files that can affect result processFileImpl(project, new com.intellij.ide.caches.FileContent(file), onlyRemoveOutdatedData); - } catch (ProcessCanceledException ex) { - LOG.assertTrue(!onlyRemoveOutdatedData); - myChangedFilesCollector.scheduleForUpdate(file); - throw ex; } finally { myForceUpdateSemaphore.up(); From 935a6cb9601ebefa5b4588125de842c95b75d508 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 21 Jun 2013 10:53:21 +0200 Subject: [PATCH 41/49] workaround for IDEA-109227 --- bin/scripts/unix/idea.sh | 2 +- build/scripts/utils.gant | 2 +- .../impl/src/com/intellij/compiler/server/BuildManager.java | 2 +- .../jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/scripts/unix/idea.sh b/bin/scripts/unix/idea.sh index 5308334765c5..42aec04781c8 100755 --- a/bin/scripts/unix/idea.sh +++ b/bin/scripts/unix/idea.sh @@ -159,7 +159,7 @@ if [ "$IS_EAP" = "true" ]; then OS_NAME=`echo $OS_TYPE | "$TR" '[:upper:]' '[:lower:]'` AGENT_LIB="yjpagent-$OS_NAME$BITS" if [ -r "$IDE_BIN_HOME/lib$AGENT_LIB.so" ]; then - AGENT="-agentlib:$AGENT_LIB=disablej2ee,disablealloc,sessionname=@@system_selector@@" + AGENT="-agentlib:$AGENT_LIB=disablej2ee,disablealloc,delay=10000,sessionname=@@system_selector@@" fi fi diff --git a/build/scripts/utils.gant b/build/scripts/utils.gant index 7a5798bdd4c4..f017f845bfd2 100644 --- a/build/scripts/utils.gant +++ b/build/scripts/utils.gant @@ -61,7 +61,7 @@ binding.setVariable("vmOptions32", { "$mem32 ${vmOptions()}".trim() }) binding.setVariable("vmOptions64", { "$mem64 ${vmOptions()}".trim() }) binding.setVariable("yjpOptions", { String systemSelector, String platformSuffix = "" -> - "-agentlib:yjpagent$platformSuffix=disablej2ee,disablealloc,disabletracing,onlylocal,builtinprobes=none,disableexceptiontelemetry,sessionname=$systemSelector".trim() + "-agentlib:yjpagent$platformSuffix=disablej2ee,disablealloc,disabletracing,onlylocal,builtinprobes=none,disableexceptiontelemetry,delay=10000,sessionname=$systemSelector".trim() }) binding.setVariable("vmOptions32yjp", { String systemSelector -> diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index 91697e246338..f72ceec1b440 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -861,7 +861,7 @@ public class BuildManager implements ApplicationComponent{ cp.addAll(myClasspathManager.getBuildProcessPluginsClasspath(project)); if (isProfilingMode) { cp.add(new File(workDirectory, "yjp-controller-api-redist.jar").getPath()); - cmdLine.addParameter("-agentlib:yjpagent=disablej2ee,disablealloc,sessionname=ExternalBuild"); + cmdLine.addParameter("-agentlib:yjpagent=disablej2ee,disablealloc,delay=10000,sessionname=ExternalBuild"); } cmdLine.addParameter("-classpath"); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java index f0d26c9840cc..69450a8460f4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java @@ -143,7 +143,7 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler { if (profileGroovyc) { parameters.getVMParametersList().defineProperty("java.library.path", PathManager.getBinPath()); parameters.getVMParametersList().defineProperty("profile.groovy.compiler", "true"); - parameters.getVMParametersList().add("-agentlib:yjpagent=disablej2ee,disablealloc,sessionname=GroovyCompiler"); + parameters.getVMParametersList().add("-agentlib:yjpagent=disablej2ee,disablealloc,delay=10000,sessionname=GroovyCompiler"); classPathBuilder.add(PathManager.findFileInLibDirectory("yjp-controller-api-redist.jar").getAbsolutePath()); } From d0452af68fbe35aaf723337ca74aeddf0cc5d42b Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 21 Jun 2013 11:16:55 +0200 Subject: [PATCH 42/49] EA-45804 (NPE: SocksAuthenticatorManager.unregister) --- .../connections/ssh/SocksAuthenticatorManager.java | 10 +++++++--- .../connections/ssh/SshProxyFactory.java | 13 ++++++------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/plugins/cvs/cvs-core/src/com/intellij/cvsSupport2/connections/ssh/SocksAuthenticatorManager.java b/plugins/cvs/cvs-core/src/com/intellij/cvsSupport2/connections/ssh/SocksAuthenticatorManager.java index e4ca2c4880f8..4a310d33d943 100644 --- a/plugins/cvs/cvs-core/src/com/intellij/cvsSupport2/connections/ssh/SocksAuthenticatorManager.java +++ b/plugins/cvs/cvs-core/src/com/intellij/cvsSupport2/connections/ssh/SocksAuthenticatorManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ */ package com.intellij.cvsSupport2.connections.ssh; +import com.intellij.cvsSupport2.config.ProxySettings; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.util.KeyValue; import com.intellij.openapi.util.Pair; @@ -30,9 +31,9 @@ import java.util.List; import java.util.Map; public class SocksAuthenticatorManager { - private final static String SOCKS_REQUESTING_PROTOCOL = "SOCKS"; + private final Object myLock; - private CvsProxySelector mySelector; + private volatile CvsProxySelector mySelector; public static SocksAuthenticatorManager getInstance() { return ServiceManager.getService(SocksAuthenticatorManager.class); @@ -53,6 +54,9 @@ public class SocksAuthenticatorManager { public void unregister(final ConnectionSettings connectionSettings) { SshLogger.debug("unregister in authenticator"); + if (!connectionSettings.isUseProxy()) return; + final int proxyType = connectionSettings.getProxyType(); + if (proxyType != ProxySettings.SOCKS4 && proxyType != ProxySettings.SOCKS5) return; mySelector.unregister(connectionSettings.getHostName(), connectionSettings.getPort()); CommonProxy.getInstance().removeCustomAuth(getClass().getName()); } diff --git a/plugins/cvs/cvs-core/src/com/intellij/cvsSupport2/connections/ssh/SshProxyFactory.java b/plugins/cvs/cvs-core/src/com/intellij/cvsSupport2/connections/ssh/SshProxyFactory.java index 02611b0e74f1..097002545145 100644 --- a/plugins/cvs/cvs-core/src/com/intellij/cvsSupport2/connections/ssh/SshProxyFactory.java +++ b/plugins/cvs/cvs-core/src/com/intellij/cvsSupport2/connections/ssh/SshProxyFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,19 +26,18 @@ import java.io.IOException; import java.net.Socket; public class SshProxyFactory { - private SshProxyFactory() { - } + + private SshProxyFactory() {} @Nullable public static ProxyData createAndRegister(final ConnectionSettings connectionSettings) { - ProxyData result = null; - if (! connectionSettings.isUseProxy()) return null; + if (!connectionSettings.isUseProxy()) return null; final int type = connectionSettings.getProxyType(); - if ((ProxySettings.SOCKS4 == type) || (ProxySettings.SOCKS5 == type)) { + ProxyData result = null; + if (ProxySettings.SOCKS4 == type || ProxySettings.SOCKS5 == type) { result = new SocksProxyData(connectionSettings); SocksAuthenticatorManager.getInstance().register(connectionSettings); } else if (ProxySettings.HTTP == type) { - /*String proxyHost, int proxyPort, String proxyUser, String proxyPass*/ result = new HTTPProxyData(connectionSettings.getProxyHostName(), connectionSettings.getProxyPort(), connectionSettings.getProxyLogin(), connectionSettings.getProxyPassword()); } From 6886722d5fa1cb169abe804e63dfd6bb82c32c7b Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 21 Jun 2013 13:24:09 +0400 Subject: [PATCH 43/49] TF-3689043 (now really disable .jar copying on Unix by default) --- build/conf/ideaCE.properties | 6 ++++-- .../intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java | 8 +++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/build/conf/ideaCE.properties b/build/conf/ideaCE.properties index 81afaed35094..8224c19bad6d 100644 --- a/build/conf/ideaCE.properties +++ b/build/conf/ideaCE.properties @@ -1,8 +1,10 @@ #--------------------------------------------------------------------- -# IDE copies library jars to prevent their locking. If copying is not desirable, specify "true" +# IDEA can copy library .jar files to prevent their locking. +# By default this behavior is enabled on Windows and disabled on other platforms. +# Uncomment this property to override. #--------------------------------------------------------------------- -idea.jars.nocopy=false +# idea.jars.nocopy=false #--------------------------------------------------------------------- # The VM option value to be used start the JVM in debug mode. diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java index 32e02ea2c49a..9cdc900d8117 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,13 +49,15 @@ public class JarFileSystemImpl extends JarFileSystem implements ApplicationCompo private static final class JarFileSystemImplLock { } private static final JarFileSystemImplLock LOCK = new JarFileSystemImplLock(); - private final Set myNoCopyJarPaths = - SystemProperties.getBooleanProperty("idea.jars.nocopy", !SystemInfo.isWindows) ? null : new ConcurrentHashSet(FileUtil.PATH_HASHING_STRATEGY); + private final Set myNoCopyJarPaths; private File myNoCopyJarDir; private final Map myHandlers = new THashMap(FileUtil.PATH_HASHING_STRATEGY); private String[] jarPathsCache; public JarFileSystemImpl(MessageBus bus) { + boolean noCopy = SystemProperties.getBooleanProperty("idea.jars.nocopy", !SystemInfo.isWindows); + myNoCopyJarPaths = noCopy ? null : new ConcurrentHashSet(FileUtil.PATH_HASHING_STRATEGY); + bus.connect().subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener.Adapter() { @Override public void after(@NotNull final List events) { From 744a1c0b26fdd42b2e5ac98d990e5fde0fe9714c Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 21 Jun 2013 13:27:58 +0400 Subject: [PATCH 44/49] Typo --- build/conf/ideaCE.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/conf/ideaCE.properties b/build/conf/ideaCE.properties index 8224c19bad6d..8c86bf315b02 100644 --- a/build/conf/ideaCE.properties +++ b/build/conf/ideaCE.properties @@ -7,7 +7,7 @@ # idea.jars.nocopy=false #--------------------------------------------------------------------- -# The VM option value to be used start the JVM in debug mode. +# The VM option value to be used to start a JVM in debug mode. # Some JREs define it in a different way (-XXdebug in Oracle VM) #--------------------------------------------------------------------- idea.xdebug.key=-Xdebug From 01ab2a0ab2e7febd05163ca20c0466e6ce5fe008 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Fri, 21 Jun 2013 11:53:39 +0200 Subject: [PATCH 45/49] myStart was not used in readCharsTo (IDEA-109329) --- .../util/src/com/intellij/util/text/CharArrayCharSequence.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/util/src/com/intellij/util/text/CharArrayCharSequence.java b/platform/util/src/com/intellij/util/text/CharArrayCharSequence.java index 7d821192e7c6..18f0715cd02a 100644 --- a/platform/util/src/com/intellij/util/text/CharArrayCharSequence.java +++ b/platform/util/src/com/intellij/util/text/CharArrayCharSequence.java @@ -105,7 +105,7 @@ public class CharArrayCharSequence implements CharSequenceBackedByArray { final int readChars = Math.min(len, length() - start); if (readChars <= 0) return -1; - System.arraycopy(myChars, start, cbuf, off, readChars); + System.arraycopy(myChars, myStart + start, cbuf, off, readChars); return readChars; } } From 22a0224d67cab1170367fddcdaefe2db257a191d Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 21 Jun 2013 12:00:44 +0200 Subject: [PATCH 46/49] enable proxy settings for ext root using internal ssh implementation --- .../config/ui/Cvs2SettingsEditPanel.java | 13 ++++++--- .../ext/ui/ExtConnectionDualPanel.java | 27 ++++++++++++++++--- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/config/ui/Cvs2SettingsEditPanel.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/config/ui/Cvs2SettingsEditPanel.java index 5766ea0aa7a4..480700068f81 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/config/ui/Cvs2SettingsEditPanel.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/config/ui/Cvs2SettingsEditPanel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -125,6 +125,7 @@ public class Cvs2SettingsEditPanel { public void addCvsRootChangeListener(CvsRootChangeListener cvsRootChangeListener) { myCvsRootConfigurationPanelView.addCvsRootChangeListener(cvsRootChangeListener); + myExtConnectionSettingsEditor.addCvsRootChangeListener(cvsRootChangeListener); } public void updateFrom(final CvsRootConfiguration configuration) { @@ -275,11 +276,17 @@ public class Cvs2SettingsEditPanel { } } - private static String getProxyPanelName(CvsRootData cvsRootData) { + private String getProxyPanelName(CvsRootData cvsRootData) { if (cvsRootData.METHOD == null) { return EMPTY; } - return cvsRootData.METHOD.supportsProxyConnection() ? NON_EMPTY_PROXY_SETTINGS : EMPTY; + if (cvsRootData.METHOD.supportsProxyConnection()) { + return NON_EMPTY_PROXY_SETTINGS; + } + if (cvsRootData.METHOD == CvsMethod.EXT_METHOD && myExtConnectionSettingsEditor.isUseInternalSshImplementation()) { + return NON_EMPTY_PROXY_SETTINGS; + } + return EMPTY; } private static String getSettingsPanelName(CvsRootData cvsRootData) { diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/connections/ext/ui/ExtConnectionDualPanel.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/connections/ext/ui/ExtConnectionDualPanel.java index aa53dec5e96a..ae5ac5cfe34b 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/connections/ext/ui/ExtConnectionDualPanel.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/connections/ext/ui/ExtConnectionDualPanel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,23 +19,27 @@ import com.intellij.CvsBundle; import com.intellij.cvsSupport2.config.ExtConfiguration; import com.intellij.cvsSupport2.config.SshSettings; import com.intellij.cvsSupport2.connections.ssh.ui.SshConnectionSettingsPanel; +import com.intellij.cvsSupport2.ui.CvsRootChangeListener; import com.intellij.openapi.project.Project; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NonNls; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.util.Collection; public class ExtConnectionDualPanel { private final ExtConnectionSettingsPanel myExtSettingsPanel; private final SshConnectionSettingsPanel mySshSettingsPanel; + private final Collection myCvsRootChangeListeners = ContainerUtil.createLockFreeCopyOnWriteList(); + private final JPanel myPanel = new JPanel(new BorderLayout()); private final JPanel myDualPanel = new JPanel(new CardLayout()); - private final JCheckBox myUseInternalImplementationCheckBox = - new JCheckBox(CvsBundle.message("checkbox.text.use.internal.ssh.implementation")); + private final JCheckBox myUseInternalImplementationCheckBox = new JCheckBox(CvsBundle.message("checkbox.text.use.internal.ssh.implementation")); @NonNls private static final String EXT = "EXT"; @NonNls private static final String SSH = "SSH"; @@ -52,12 +56,23 @@ public class ExtConnectionDualPanel { myUseInternalImplementationCheckBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { updatePage(); + notifyListeners(); } }); } + public void addCvsRootChangeListener(CvsRootChangeListener l) { + myCvsRootChangeListeners.add(l); + } + + private void notifyListeners() { + for (CvsRootChangeListener cvsRootChangeListener : myCvsRootChangeListeners) { + cvsRootChangeListener.onCvsRootChanged(); + } + } + private void updatePage() { - final CardLayout cardLayout = ((CardLayout)myDualPanel.getLayout()); + final CardLayout cardLayout = (CardLayout)myDualPanel.getLayout(); if (myUseInternalImplementationCheckBox.isSelected()){ cardLayout.show(myDualPanel, SSH); } else { @@ -91,4 +106,8 @@ public class ExtConnectionDualPanel { mySshSettingsPanel.saveTo(sshSettings); extConfiguration.USE_INTERNAL_SSH_IMPLEMENTATION = myUseInternalImplementationCheckBox.isSelected(); } + + public boolean isUseInternalSshImplementation() { + return myUseInternalImplementationCheckBox.isSelected(); + } } From 97046d0581062c339c5c3d3a5bbd9c0ce25e4786 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 21 Jun 2013 12:25:33 +0200 Subject: [PATCH 47/49] EA-47242 (AIOOBE: StringBufferReplaceableByStringInspection.isAppendCall) --- .../style/StringBufferReplaceableByStringInspection.java | 8 ++++---- .../StringBufferReplaceableByString.java | 9 +++++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java index 11fa11bc5e17..337e3305188f 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java @@ -337,11 +337,11 @@ public class StringBufferReplaceableByStringInspection extends BaseInspection { } final PsiExpressionList argumentList = methodCallExpression.getArgumentList(); final PsiExpression[] arguments = argumentList.getExpressions(); - if (arguments.length == 1) { - return true; + if (arguments.length == 3) { + return arguments[0].getType() instanceof PsiArrayType && + arguments[1].getType() == PsiType.INT && arguments[2].getType() == PsiType.INT; } - final PsiExpression argument = arguments[0]; - return argument.getType() instanceof PsiArrayType; + return arguments.length == 1; } public static boolean isToStringCall(PsiElement element) { diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/string_buffer_replaceable_by_string/StringBufferReplaceableByString.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/string_buffer_replaceable_by_string/StringBufferReplaceableByString.java index fad106d1f318..cfeea11c6468 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/string_buffer_replaceable_by_string/StringBufferReplaceableByString.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/string_buffer_replaceable_by_string/StringBufferReplaceableByString.java @@ -59,4 +59,13 @@ public class StringBufferReplaceableByString { (Math.random() < 0.5 ? a : b).append("BLA"); System.out.println(a + "/" + b); } + + String incomplete(char[] cs) { + StringBuilder a = new StringBuilder(); + a.append(cs, 1); + System.out.println(a.toString()); + StringBuilder b = new StringBuilder(); + b.append() + return b.toString(); + } } From 0b8b7aa9bfdc189728a98a55a749c7579b5164a4 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Fri, 21 Jun 2013 14:26:24 +0400 Subject: [PATCH 48/49] [git] Fix possible race condition in tests The flags are accessed from different threads => volatile --- .../testFramework/com/intellij/dvcs/test/MockVcsHelper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/dvcs/testFramework/com/intellij/dvcs/test/MockVcsHelper.java b/platform/dvcs/testFramework/com/intellij/dvcs/test/MockVcsHelper.java index 25b2b12f4fc3..98884e6e2b24 100644 --- a/platform/dvcs/testFramework/com/intellij/dvcs/test/MockVcsHelper.java +++ b/platform/dvcs/testFramework/com/intellij/dvcs/test/MockVcsHelper.java @@ -45,8 +45,8 @@ import java.util.Map; * @author Kirill Likhodedov */ public class MockVcsHelper extends AbstractVcsHelper { - private boolean myCommitDialogShown; - private boolean myMergeDialogShown; + private volatile boolean myCommitDialogShown; + private volatile boolean myMergeDialogShown; private CommitHandler myCommitHandler; private MergeHandler myMergeHandler; From c4f4b1fc006572ab6f2d7fe45aa08b71bd16e0a7 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Fri, 21 Jun 2013 14:37:13 +0400 Subject: [PATCH 49/49] [vcs] simplify --- .../vcs/history/impl/VcsHistoryDialog.java | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/impl/VcsHistoryDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/impl/VcsHistoryDialog.java index 0952fa2861df..0225e5e5263a 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/impl/VcsHistoryDialog.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/impl/VcsHistoryDialog.java @@ -459,22 +459,23 @@ public class VcsHistoryDialog extends DialogWrapper implements DataProvider { @Nullable private Block getBlock(VcsFileRevision revision) throws FilesTooBigForDiffException, VcsException { - if (myRevisionToContentMap.containsKey(revision)) + if (myRevisionToContentMap.containsKey(revision)) { return myRevisionToContentMap.get(revision); - - int index = myRevisions.indexOf(revision); + } final String revisionContent = getContentOf(revision); if (revisionContent == null) return null; - if (index == 0) { - Block currentBlock = new Block(myEditor.getDocument().getText(), mySelectionStart, mySelectionEnd); - myRevisionToContentMap.put(revision, new FindBlock(revisionContent, currentBlock).getBlockInThePrevVersion()); - } - else { - Block prevBlock = getBlock(myRevisions.get(index - 1)); - if (prevBlock == null) return null; - myRevisionToContentMap.put(revision, new FindBlock(revisionContent, prevBlock).getBlockInThePrevVersion()); - } + + int index = myRevisions.indexOf(revision); + Block blockByIndex = getBlock(index); + if (blockByIndex == null) return null; + + myRevisionToContentMap.put(revision, new FindBlock(revisionContent, blockByIndex).getBlockInThePrevVersion()); return myRevisionToContentMap.get(revision); } + + private Block getBlock(int index) throws FilesTooBigForDiffException, VcsException { + return index > 0 ? getBlock(myRevisions.get(index - 1)) : new Block(myEditor.getDocument().getText(), mySelectionStart, mySelectionEnd); + } + }