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/conf/ideaCE.properties b/build/conf/ideaCE.properties index 81afaed35094..8c86bf315b02 100644 --- a/build/conf/ideaCE.properties +++ b/build/conf/ideaCE.properties @@ -1,11 +1,13 @@ #--------------------------------------------------------------------- -# 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. +# 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 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/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..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 @@ -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; @@ -241,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; } 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) { 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()); 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-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-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) { 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/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 + } } 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/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); } 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 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/AbstractModificationTracker.java b/platform/core-impl/src/com/intellij/psi/impl/AbstractModificationTracker.java index e8e5cc3e3899..dd4200a5d80a 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/AbstractModificationTracker.java +++ b/platform/core-impl/src/com/intellij/psi/impl/AbstractModificationTracker.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. 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/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/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(); 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 33dd6fe72921..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 @@ -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; @@ -213,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()); } @@ -309,19 +306,19 @@ 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; - 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 +337,21 @@ 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"); + } + + 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) { 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/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; 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; } 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) { 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); 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(); 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/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); } 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; } 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, 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..fc5961c441e0 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) { @@ -2003,7 +2004,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { } } - public void scheduleForUpdate(VirtualFile file) { + private void scheduleForUpdate(VirtualFile file) { myFilesToUpdate.add(file); } @@ -2206,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(); 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/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; } 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) { 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()); } } 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); 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; } } 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); + } + } 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(); + } } diff --git a/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/build/AntArtifactBuildTaskProvider.java b/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/build/AntArtifactBuildTaskProvider.java index f86377fb4153..6a4c9c8fdf2e 100644 --- a/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/build/AntArtifactBuildTaskProvider.java +++ b/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/build/AntArtifactBuildTaskProvider.java @@ -29,6 +29,7 @@ import com.intellij.rt.ant.execution.AntMain2; import com.intellij.util.SystemProperties; import com.intellij.util.execution.ParametersListUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.ant.model.JpsAntBuildFileOptions; import org.jetbrains.jps.ant.model.JpsAntExtensionService; import org.jetbrains.jps.ant.model.JpsAntInstallation; @@ -73,9 +74,16 @@ public class AntArtifactBuildTaskProvider extends ArtifactBuildTaskProvider { return Collections.emptyList(); } + @Nullable private static JpsAntArtifactExtension getBuildExtension(JpsArtifact artifact, ArtifactBuildPhase buildPhase) { - return buildPhase == ArtifactBuildPhase.PRE_PROCESSING ? JpsAntExtensionService.getPreprocessingExtension(artifact) - : JpsAntExtensionService.getPostprocessingExtension(artifact); + switch (buildPhase) { + case PRE_PROCESSING: + return JpsAntExtensionService.getPreprocessingExtension(artifact); + case POST_PROCESSING: + return JpsAntExtensionService.getPostprocessingExtension(artifact); + default: + return null; + } } private static class AntArtifactBuildTask extends BuildTask { 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()); } 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(); + } } 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 { 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()); } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java index 930cae34318b..c8ab2c58a895 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; @@ -62,9 +63,13 @@ 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(@Nullable Project project, @NotNull String title, @NotNull 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/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); diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java index f5dc905b237e..83f8d26eb7b8 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, "Can't create new branch: ", exception); } } } @@ -131,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; @@ -153,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/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; } } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgBookmarkDialog.form b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgBookmarkDialog.form index e66baed3ed13..158977c74d68 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/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..2a8051579c95 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"); 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; 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")); } } } 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() : ""; } 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); 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()); + } + } + } }