From defaf535c37e46cd9a0c5a97b7bad4683c42d81a Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Mon, 24 Aug 2015 15:28:51 +0300 Subject: [PATCH 001/246] When checking if inside href or @link tag do not go way to far from desired offset (IDEA-144232) --- .../java/JavaLineWrapPositionStrategy.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/JavaLineWrapPositionStrategy.java b/java/java-impl/src/com/intellij/psi/formatter/java/JavaLineWrapPositionStrategy.java index fdd5ab651960..16c6c4a38f8b 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/JavaLineWrapPositionStrategy.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/JavaLineWrapPositionStrategy.java @@ -51,11 +51,19 @@ public class JavaLineWrapPositionStrategy extends DefaultLineWrapPositionStrateg private static boolean isInsideTag(Document document, int offset, String tagStart, String tagEnd) { CharSequence sequence = document.getCharsSequence(); - int lineNumber = document.getLineNumber(offset); - int lineStartOffset = document.getLineStartOffset(lineNumber); - int lineEndOffset = document.getLineEndOffset(lineNumber); + final int lineNumber = document.getLineNumber(offset); + final int lineStartOffset = document.getLineStartOffset(lineNumber); + final int lineEndOffset = document.getLineEndOffset(lineNumber); - return CharArrayUtil.indexOf(sequence, tagStart, lineStartOffset, offset) > 0 - && CharArrayUtil.indexOf(sequence, tagEnd, offset, lineEndOffset) > 0; + int searchStartOffset = lineStartOffset; + int searchEndOffset = lineEndOffset; + + if (lineEndOffset - lineStartOffset > 200) { + searchStartOffset = Math.max(offset - 100, lineStartOffset); + searchEndOffset = Math.min(offset + 100, lineEndOffset); + } + + return CharArrayUtil.indexOf(sequence, tagStart, searchStartOffset, offset) > 0 + && CharArrayUtil.indexOf(sequence, tagEnd, offset, searchEndOffset) > 0; } } \ No newline at end of file From ba379bda388fce283571cec439332833f68bc334 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Aug 2015 08:27:58 +0200 Subject: [PATCH 002/246] remove DecoratorCompletionStatistician --- .../DecoratorCompletionStatistician.java | 35 ------------------- .../src/META-INF/LangExtensions.xml | 2 -- 2 files changed, 37 deletions(-) delete mode 100644 platform/lang-impl/src/com/intellij/codeInsight/completion/DecoratorCompletionStatistician.java diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/DecoratorCompletionStatistician.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/DecoratorCompletionStatistician.java deleted file mode 100644 index 3b25a6ba0096..000000000000 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/DecoratorCompletionStatistician.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.codeInsight.completion; - -import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.codeInsight.lookup.LookupElementDecorator; -import com.intellij.psi.statistics.StatisticsInfo; -import com.intellij.psi.statistics.StatisticsManager; - -/** - * @author peter - */ -public class DecoratorCompletionStatistician extends CompletionStatistician{ - - @Override - public StatisticsInfo serialize(final LookupElement element, final CompletionLocation location) { - if (element instanceof LookupElementDecorator) { - return StatisticsManager.serialize(CompletionService.STATISTICS_KEY, ((LookupElementDecorator)element).getDelegate(), location); - } - return null; - } -} \ No newline at end of file diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index 368cc17b2813..a96bbb730bdb 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -500,8 +500,6 @@ - From c1a196ea1695d4c1b977c544932971dfec042706 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Tue, 25 Aug 2015 10:17:10 +0300 Subject: [PATCH 003/246] IDEA-143771 Expand recursively won't work if the current code block is already expanded --- .../folding/JavaFoldingTest.groovy | 24 +++++++++++++++++++ .../impl/actions/BaseFoldingHandler.java | 4 ++-- .../openapi/actionSystem/IdeActions.java | 1 + 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy index 78c6299ffb1c..80ed8a4a291b 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy @@ -1027,6 +1027,30 @@ class Foo { myFixture.performEditorAction(IdeActions.ACTION_EXPAND_ALL_TO_LEVEL_1) assertEquals 1, expandedFoldRegionsCount } + + public void "test expand recursively on expanded region containing collapsed regions"() { + def text = """ +class Foo { + public static void main() { + new Runnable(){ + public void run() { + } + }.run(); + } +} +""" + configure text + assertEquals 3, foldRegionsCount + myFixture.editor.caretModel.moveToOffset(text.indexOf("run")) + myFixture.performEditorAction(IdeActions.ACTION_COLLAPSE_REGION) + myFixture.editor.caretModel.moveToOffset(text.indexOf("new")) + myFixture.performEditorAction(IdeActions.ACTION_COLLAPSE_REGION) + assertEquals 1, expandedFoldRegionsCount + + myFixture.editor.caretModel.moveToOffset(text.indexOf("main")) + myFixture.performEditorAction(IdeActions.ACTION_EXPAND_REGION_RECURSIVELY) + assertEquals 3, expandedFoldRegionsCount + } public void "test single line closure unfolds when converted to multiline"() { boolean oldValue = Registry.is("editor.durable.folding.state") diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/actions/BaseFoldingHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/actions/BaseFoldingHandler.java index 8da22a780db4..1cfecb9a56ee 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/actions/BaseFoldingHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/actions/BaseFoldingHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -65,7 +65,7 @@ public abstract class BaseFoldingHandler extends EditorActionHandler { } int offset = caret.getOffset(); FoldRegion rootRegion = FoldingUtil.findFoldRegionStartingAtLine(editor, editor.getDocument().getLineNumber(offset)); - if (rootRegion == null || rootRegion.isExpanded() != toCollapse) { + if (rootRegion == null || toCollapse && !rootRegion.isExpanded()) { rootRegion = null; FoldRegion[] regions = FoldingUtil.getFoldRegionsAtOffset(editor, offset); for (FoldRegion region : regions) { diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java index 81536428826f..07ba96c59abc 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java @@ -172,6 +172,7 @@ public interface IdeActions { @NonNls String ACTION_COLLAPSE_ALL = "CollapseAll"; @NonNls String ACTION_EXPORT_TO_TEXT_FILE = "ExportToTextFile"; + @NonNls String ACTION_COLLAPSE_REGION = "CollapseRegion"; @NonNls String ACTION_EXPAND_ALL_REGIONS = "ExpandAllRegions"; @NonNls String ACTION_COLLAPSE_ALL_REGIONS = "CollapseAllRegions"; @NonNls String ACTION_EXPAND_REGION_RECURSIVELY = "ExpandRegionRecursively"; From dba3e36c97a6c04b1897f0961a4b591379a26011 Mon Sep 17 00:00:00 2001 From: "liana.bakradze" Date: Tue, 25 Aug 2015 10:27:44 +0300 Subject: [PATCH 004/246] copy file in archive if it doesn't contain answer placeholders --- .../src/com/jetbrains/edu/EduUtils.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/python/educational/src/com/jetbrains/edu/EduUtils.java b/python/educational/src/com/jetbrains/edu/EduUtils.java index cd4a0f8f3a10..353226deb714 100644 --- a/python/educational/src/com/jetbrains/edu/EduUtils.java +++ b/python/educational/src/com/jetbrains/edu/EduUtils.java @@ -10,6 +10,7 @@ import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.psi.PsiDirectory; @@ -132,6 +133,21 @@ public class EduUtils { LOG.error(e); } } + + if (taskFile.getAnswerPlaceholders().isEmpty()) { + String extension = FileUtilRt.getExtension(taskFileName); + String nameWithoutExtension = FileUtilRt.getNameWithoutExtension(taskFileName); + VirtualFile answerFile = answerFileDir.findChild(nameWithoutExtension + ".answer." + extension); + if (answerFile != null) { + try { + answerFile.copy(answerFileDir, userFileDir, taskFileName); + } + catch (IOException e) { + LOG.error(e); + } + } + return; + } try { userFileDir.createChildData(project, taskFileName); } From 0a00b1d1fb64b61608f2287ce8054526cce5ac2d Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Aug 2015 09:39:50 +0200 Subject: [PATCH 005/246] smart pointers should survive PSI changes --- .../smartPointers/SmartPsiElementPointersTest.java | 13 +++++++++++++ .../com/intellij/pom/core/impl/PomModelImpl.java | 5 +++++ .../impl/smartPointers/SmartPointerManagerImpl.java | 1 - 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/java/java-tests/testSrc/com/intellij/psi/impl/smartPointers/SmartPsiElementPointersTest.java b/java/java-tests/testSrc/com/intellij/psi/impl/smartPointers/SmartPsiElementPointersTest.java index 1f62e804e683..b6dcb69ea76f 100644 --- a/java/java-tests/testSrc/com/intellij/psi/impl/smartPointers/SmartPsiElementPointersTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/impl/smartPointers/SmartPsiElementPointersTest.java @@ -754,4 +754,17 @@ public class SmartPsiElementPointersTest extends CodeInsightTestCase { PsiDocumentManager.getInstance(myProject).commitAllDocuments(); assertEquals(TextRange.create(2, 3), pointer.getRange()); } + + public void testAnchorInfoSurvivesPsiChange() { + PsiJavaFile file = (PsiJavaFile)configureByText(JavaFileType.INSTANCE, "class C1{}\nclass C2 {}"); + + SmartPsiElementPointer pointer = + SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(file.getClasses()[1]); + PlatformTestUtil.tryGcSoftlyReachableObjects(); + assertNull(((SmartPointerEx) pointer).getCachedElement()); + + file.getClasses()[1].delete(); + + assertNotNull(pointer.getElement()); + } } diff --git a/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java b/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java index 7573217a5843..a37613c76fb0 100644 --- a/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java +++ b/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java @@ -40,6 +40,7 @@ import com.intellij.pom.tree.TreeAspectEvent; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.impl.*; +import com.intellij.psi.impl.smartPointers.SmartPointerManagerImpl; import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.psi.impl.source.text.BlockSupportImpl; import com.intellij.psi.impl.source.text.DiffLog; @@ -322,6 +323,10 @@ public class PomModelImpl extends UserDataHolderBase implements PomModel { throw new IllegalStateException("Attempt to modify PSI for non-committed Document!"); } + if (containingFileByTree != null) { + ((SmartPointerManagerImpl) SmartPointerManager.getInstance(myProject)).fastenBelts(containingFileByTree.getViewProvider().getVirtualFile()); + } + BlockSupportImpl.sendBeforeChildrenChangeEvent((PsiManagerImpl)PsiManager.getInstance(myProject), changeScope, true); Document document = containingFileByTree == null ? null : physical ? manager.getDocument(containingFileByTree) : diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java index 794e6fe349d5..469a350026a3 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java @@ -82,7 +82,6 @@ public class SmartPointerManagerImpl extends SmartPointerManager { } public void fastenBelts(@NotNull VirtualFile file) { - ApplicationManager.getApplication().assertIsDispatchThread(); processQueue(); synchronized (lock) { FilePointersList pointers = getPointers(file); From a49766c8432da36989a67f2fd9d817d72fe6c4c8 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Aug 2015 09:41:14 +0200 Subject: [PATCH 006/246] PsiFormatUtil: don't show type annotations by default --- .../src/com/intellij/psi/util/PsiFormatUtil.java | 8 +++++--- .../daemon/impl/analysis/HighlightMessageUtil.java | 2 +- .../src/com/intellij/psi/util/PsiFormatUtilBase.java | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiFormatUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiFormatUtil.java index 3cb6ea25561b..feccd0171c95 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/PsiFormatUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/PsiFormatUtil.java @@ -25,12 +25,12 @@ import org.jetbrains.annotations.Nullable; public class PsiFormatUtil extends PsiFormatUtilBase { @MagicConstant(flags = { SHOW_MODIFIERS, SHOW_TYPE, TYPE_AFTER, SHOW_CONTAINING_CLASS, SHOW_FQ_NAME, SHOW_NAME, SHOW_MODIFIERS, - SHOW_INITIALIZER, SHOW_RAW_TYPE, SHOW_RAW_NON_TOP_TYPE, SHOW_FQ_CLASS_NAMES}) + SHOW_INITIALIZER, SHOW_RAW_TYPE, SHOW_RAW_NON_TOP_TYPE, SHOW_FQ_CLASS_NAMES, USE_INTERNAL_CANONICAL_TEXT}) public @interface FormatVariableOptions { } @MagicConstant(flags = { SHOW_MODIFIERS, MODIFIERS_AFTER, SHOW_TYPE, TYPE_AFTER, SHOW_CONTAINING_CLASS, SHOW_FQ_NAME, SHOW_NAME, - SHOW_PARAMETERS, SHOW_THROWS, SHOW_RAW_TYPE, SHOW_RAW_NON_TOP_TYPE, SHOW_FQ_CLASS_NAMES}) + SHOW_PARAMETERS, SHOW_THROWS, SHOW_RAW_TYPE, SHOW_RAW_NON_TOP_TYPE, SHOW_FQ_CLASS_NAMES, USE_INTERNAL_CANONICAL_TEXT}) public @interface FormatMethodOptions { } @MagicConstant(flags = { @@ -388,7 +388,9 @@ public class PsiFormatUtil extends PsiFormatUtilBase { } } if (type == null) return "null"; - return (options & SHOW_FQ_CLASS_NAMES) == 0 ? type.getPresentableText() : type.getInternalCanonicalText(); + return (options & SHOW_FQ_CLASS_NAMES) == 0 ? type.getPresentableText() : + (options & USE_INTERNAL_CANONICAL_TEXT) == 0 ? type.getCanonicalText(false) : + type.getInternalCanonicalText(); } public static String formatReference(PsiJavaCodeReferenceElement ref, int options) { diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMessageUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMessageUtil.java index e15ab355db2f..cb1d26b946b3 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMessageUtil.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMessageUtil.java @@ -43,7 +43,7 @@ public class HighlightMessageUtil { else if (symbol instanceof PsiMethod) { symbolName = PsiFormatUtil.formatMethod((PsiMethod)symbol, substitutor, PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_PARAMETERS, - PsiFormatUtilBase.SHOW_TYPE | PsiFormatUtilBase.SHOW_FQ_CLASS_NAMES); + PsiFormatUtilBase.SHOW_TYPE | PsiFormatUtilBase.SHOW_FQ_CLASS_NAMES | PsiFormatUtilBase.USE_INTERNAL_CANONICAL_TEXT); } else if (symbol instanceof PsiVariable) { symbolName = ((PsiVariable)symbol).getName(); diff --git a/platform/core-api/src/com/intellij/psi/util/PsiFormatUtilBase.java b/platform/core-api/src/com/intellij/psi/util/PsiFormatUtilBase.java index cf308a904881..24b820cd84c0 100644 --- a/platform/core-api/src/com/intellij/psi/util/PsiFormatUtilBase.java +++ b/platform/core-api/src/com/intellij/psi/util/PsiFormatUtilBase.java @@ -38,6 +38,7 @@ public abstract class PsiFormatUtilBase { public static final int SHOW_ANONYMOUS_CLASS_VERBOSE = 0x8000; // class public static final int SHOW_RAW_TYPE = 0x10000; //type public static final int SHOW_RAW_NON_TOP_TYPE = 0x20000; + public static final int USE_INTERNAL_CANONICAL_TEXT = 0x40000; // variable/method/parameter types public static final int MAX_PARAMS_TO_SHOW = 7; protected static void appendSpaceIfNeeded(StringBuilder buffer) { From f1c0a39844b1715fb405d9ee6c3ce2b627ecc264 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 24 Aug 2015 17:51:52 +0200 Subject: [PATCH 007/246] move hamcrest-library to hamcrest lib --- .idea/compiler.xml | 1 + .idea/libraries/assertJ.xml | 3 --- .idea/libraries/hamcrest.xml | 11 +++++++++ .../testSrc/DefaultProjectStoreTest.kt | 5 ++-- .../testSrc/SchemeManagerTest.kt | 11 +++------ .../testSrc/StorageManagerTest.kt | 23 +++++++------------ .../testSrc/XmlElementStorageTest.kt | 12 ++++------ platform/extensions/extensions.iml | 1 + platform/lang-api/lang-api.iml | 3 +-- .../com/intellij/idea/LockSupportTest.java | 2 +- .../openapi/util/io/FileUtilLightTest.java | 21 ++++++++--------- .../com/intellij/util/io/UrlUtilTest.java | 6 ++--- .../engine/java-decompiler-engine.iml | 1 + .../testSrc/BareGitTest.kt | 12 ++++------ .../testSrc/CredentialsTest.kt | 22 ++++++++---------- .../settings-repository/testSrc/GitTest.kt | 14 +++++++++++ .../settings-repository/testSrc/LoadTest.kt | 19 ++++++++------- .../testSrc/RespositoryHelper.kt | 12 ++++------ python/testSrc/python-community-tests.iml | 1 + 19 files changed, 90 insertions(+), 90 deletions(-) create mode 100644 .idea/libraries/hamcrest.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 81c07f1ae53f..a926e428e3b8 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -34,6 +34,7 @@ + diff --git a/.idea/libraries/assertJ.xml b/.idea/libraries/assertJ.xml index aba65818e34c..68de8147dc27 100644 --- a/.idea/libraries/assertJ.xml +++ b/.idea/libraries/assertJ.xml @@ -2,15 +2,12 @@ - - - \ No newline at end of file diff --git a/.idea/libraries/hamcrest.xml b/.idea/libraries/hamcrest.xml new file mode 100644 index 000000000000..b58fc0f06bcc --- /dev/null +++ b/.idea/libraries/hamcrest.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/platform/configuration-store-impl/testSrc/DefaultProjectStoreTest.kt b/platform/configuration-store-impl/testSrc/DefaultProjectStoreTest.kt index 1438d0d07fb6..d3b6269745ce 100644 --- a/platform/configuration-store-impl/testSrc/DefaultProjectStoreTest.kt +++ b/platform/configuration-store-impl/testSrc/DefaultProjectStoreTest.kt @@ -12,8 +12,7 @@ import com.intellij.openapi.util.io.FileUtil import com.intellij.testFramework.ProjectRule import com.intellij.testFramework.RuleChain import com.intellij.testFramework.TemporaryDirectory -import org.hamcrest.CoreMatchers.equalTo -import org.hamcrest.MatcherAssert.assertThat +import org.assertj.core.api.Assertions.assertThat import org.junit.ClassRule import org.junit.Rule import org.junit.Test @@ -68,7 +67,7 @@ class DefaultProjectStoreTest { public Test fun `new project from default`() { createProject(tempDirManager) { - assertThat(it.service().getAllDependencies(), equalTo(requiredPlugins)) + assertThat(it.service().getAllDependencies()).isEqualTo(requiredPlugins) } } } \ No newline at end of file diff --git a/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt b/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt index f7d7de7e462a..42caad166d9a 100644 --- a/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt +++ b/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt @@ -36,11 +36,11 @@ import com.intellij.util.xmlb.annotations.Transient import com.intellij.util.xmlb.toByteArray import gnu.trove.THashMap import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.assertThatThrownBy import org.jdom.Element import org.junit.ClassRule import org.junit.Rule import org.junit.Test -import org.junit.rules.ExpectedException import java.io.File val FILE_SPEC = "REMOTE" @@ -56,9 +56,6 @@ class SchemeManagerTest { private val tempDirManager = TemporaryDirectory() public Rule fun getTemporaryFolder(): TemporaryDirectory = tempDirManager - private val thrown = ExpectedException.none() - public Rule fun getThrown(): ExpectedException = thrown - private var localBaseDir: File? = null private var remoteBaseDir: File? = null @@ -301,13 +298,11 @@ class SchemeManagerTest { } public Test fun `path must not contains ROOT_CONFIG macro`() { - thrown.expectMessage("Path must not contains ROOT_CONFIG macro, corrected: foo") - SchemesManagerFactory.getInstance().create("\$ROOT_CONFIG$/foo", TestSchemesProcessor()) + assertThatThrownBy({ SchemesManagerFactory.getInstance().create("\$ROOT_CONFIG$/foo", TestSchemesProcessor()) }).hasMessage("Path must not contains ROOT_CONFIG macro, corrected: foo") } public Test fun `path must be system-independent`() { - thrown.expectMessage("Path must be system-independent, use forward slash instead of backslash") - SchemesManagerFactory.getInstance().create("foo\\bar", TestSchemesProcessor()) + assertThatThrownBy({SchemesManagerFactory.getInstance().create("foo\\bar", TestSchemesProcessor())}).hasMessage("Path must be system-independent, use forward slash instead of backslash") } private fun createSchemeManager(dir: File) = SchemeManagerImpl(FILE_SPEC, TestSchemesProcessor(), RoamingType.PER_USER, null, dir) diff --git a/platform/configuration-store-impl/testSrc/StorageManagerTest.kt b/platform/configuration-store-impl/testSrc/StorageManagerTest.kt index 2f6d4529a52a..c71e24d3ad2f 100644 --- a/platform/configuration-store-impl/testSrc/StorageManagerTest.kt +++ b/platform/configuration-store-impl/testSrc/StorageManagerTest.kt @@ -21,14 +21,11 @@ import com.intellij.openapi.components.stateStore import com.intellij.testFramework.ProjectRule import com.intellij.util.SmartList import junit.framework.TestCase -import org.hamcrest.CoreMatchers.equalTo -import org.hamcrest.CoreMatchers.notNullValue -import org.junit.Assert.assertThat +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.assertThatThrownBy import org.junit.Before import org.junit.ClassRule -import org.junit.Rule import org.junit.Test -import org.junit.rules.ExpectedException import kotlin.properties.Delegates class StorageManagerTest { @@ -38,9 +35,6 @@ class StorageManagerTest { ClassRule val projectRule = ProjectRule() } - private val thrown = ExpectedException.none() - public Rule fun getThrown(): ExpectedException = thrown - private var storageManager: StateStorageManagerImpl by Delegates.notNull() public Before fun setUp() { @@ -49,19 +43,18 @@ class StorageManagerTest { } public Test fun createFileStateStorageMacroSubstituted() { - assertThat(storageManager.getStateStorage("$MACRO/test.xml", RoamingType.PER_USER), notNullValue()) + assertThat(storageManager.getStateStorage("$MACRO/test.xml", RoamingType.PER_USER)).isNotNull() } public Test fun `collapse macro`() { - assertThat(storageManager.collapseMacros("/temp/m1/foo"), equalTo("$MACRO/foo")) - assertThat(storageManager.collapseMacros("\\temp\\m1\\foo"), equalTo("\\temp\\m1\\foo")) + assertThat(storageManager.collapseMacros("/temp/m1/foo")).isEqualTo("$MACRO/foo") + assertThat(storageManager.collapseMacros("\\temp\\m1\\foo")).isEqualTo("\\temp\\m1\\foo") } public Test fun `add system-dependent macro`() { val key = "\$INVALID$" val expansion = "\\temp" - thrown.expectMessage("Macro $key set to system-dependent expansion $expansion") - storageManager.addMacro(key, expansion) + assertThatThrownBy({storageManager.addMacro(key, expansion) }).hasMessage("Macro $key set to system-dependent expansion $expansion") } public Test fun `create storage assertion thrown when unknown macro`() { @@ -70,13 +63,13 @@ class StorageManagerTest { TestCase.fail("Exception expected") } catch (e: IllegalArgumentException) { - assertThat(e.getMessage(), equalTo("Unknown macro: \$UNKNOWN_MACRO$ in storage file spec: \$UNKNOWN_MACRO$/test.xml")) + assertThat(e.getMessage()).isEqualTo("Unknown macro: \$UNKNOWN_MACRO$ in storage file spec: \$UNKNOWN_MACRO$/test.xml") } } public Test fun `create file storage macro substituted when expansion has$`() { storageManager.addMacro("\$DOLLAR_MACRO$", "/temp/d$") - assertThat(storageManager.getStateStorage("\$DOLLAR_MACRO$/test.xml", RoamingType.PER_USER), notNullValue()) + assertThat(storageManager.getStateStorage("\$DOLLAR_MACRO$/test.xml", RoamingType.PER_USER)).isNotNull() } } diff --git a/platform/configuration-store-impl/testSrc/XmlElementStorageTest.kt b/platform/configuration-store-impl/testSrc/XmlElementStorageTest.kt index 3563cdee49f8..8a991baba2e3 100644 --- a/platform/configuration-store-impl/testSrc/XmlElementStorageTest.kt +++ b/platform/configuration-store-impl/testSrc/XmlElementStorageTest.kt @@ -18,9 +18,7 @@ package com.intellij.configurationStore import com.intellij.openapi.util.JDOMBuilder.attr import com.intellij.openapi.util.JDOMBuilder.tag import junit.framework.TestCase -import org.hamcrest.CoreMatchers.notNullValue -import org.hamcrest.CoreMatchers.nullValue -import org.hamcrest.MatcherAssert.assertThat +import org.assertj.core.api.Assertions.assertThat import org.jdom.Element import org.junit.Test @@ -36,7 +34,7 @@ class XmlElementStorageTest { public Test fun testGetStateNotSucceeded() { val storage = MyXmlElementStorage(tag("root")) val state = storage.getState(this, "test", javaClass()) - assertThat(state, nullValue()) + assertThat(state).isNull() } public Test fun `set state overrides old state`() { @@ -45,9 +43,9 @@ class XmlElementStorageTest { val externalizationSession = storage.startExternalization()!! externalizationSession.setState(this, "test", newState) externalizationSession.createSaveSession()!!.save() - assertThat(storage.savedElement, notNullValue()) - assertThat(storage.savedElement!!.getChild("component").getChild("bar"), notNullValue()) - assertThat(storage.savedElement!!.getChild("component").getChild("foo"), nullValue()) + assertThat(storage.savedElement).isNotNull() + assertThat(storage.savedElement!!.getChild("component").getChild("bar")).isNotNull() + assertThat(storage.savedElement!!.getChild("component").getChild("foo")).isNull() } private class MyXmlElementStorage(private val myElement: Element) : XmlElementStorage("", "root", null, null, null) { diff --git a/platform/extensions/extensions.iml b/platform/extensions/extensions.iml index 34eec9193ea5..8395ac142875 100644 --- a/platform/extensions/extensions.iml +++ b/platform/extensions/extensions.iml @@ -14,6 +14,7 @@ + diff --git a/platform/lang-api/lang-api.iml b/platform/lang-api/lang-api.iml index b095734ee2d1..c6851ed56112 100644 --- a/platform/lang-api/lang-api.iml +++ b/platform/lang-api/lang-api.iml @@ -17,5 +17,4 @@ - - + \ No newline at end of file diff --git a/platform/platform-tests/testSrc/com/intellij/idea/LockSupportTest.java b/platform/platform-tests/testSrc/com/intellij/idea/LockSupportTest.java index 074a1db7348c..7895de3d6165 100644 --- a/platform/platform-tests/testSrc/com/intellij/idea/LockSupportTest.java +++ b/platform/platform-tests/testSrc/com/intellij/idea/LockSupportTest.java @@ -25,8 +25,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; +import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; public class LockSupportTest { @Test(timeout = 30000) diff --git a/platform/util/testSrc/com/intellij/openapi/util/io/FileUtilLightTest.java b/platform/util/testSrc/com/intellij/openapi/util/io/FileUtilLightTest.java index 0d82e64cd574..747c5c79a129 100644 --- a/platform/util/testSrc/com/intellij/openapi/util/io/FileUtilLightTest.java +++ b/platform/util/testSrc/com/intellij/openapi/util/io/FileUtilLightTest.java @@ -31,8 +31,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.sameInstance; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.*; public class FileUtilLightTest { @@ -203,16 +202,16 @@ public class FileUtilLightTest { @Test public void sanitizeFileName() { String newS = "tmp"; - assertThat(FileUtil.sanitizeFileName(newS), sameInstance(newS)); - assertThat(FileUtil.sanitizeFileName("_test"), sameInstance("_test")); + assertThat(FileUtil.sanitizeFileName(newS)).isSameAs(newS); + assertThat(FileUtil.sanitizeFileName("_test")).isSameAs("_test"); - assertThat(FileUtil.sanitizeFileName(" "), equalTo("_")); - assertThat(FileUtil.sanitizeFileName("\u2026"), equalTo("")); - assertThat(FileUtil.sanitizeFileName("q_test"), sameInstance("q_test")); - assertThat(FileUtil.sanitizeFileName("12_"), sameInstance("12_")); - assertThat(FileUtil.sanitizeFileName("12_ 123"), equalTo("12___123")); - assertThat(FileUtil.sanitizeFileName(" 12\u2026123"), equalTo("_12123")); + assertThat(FileUtil.sanitizeFileName(" ")).isEqualTo("_"); + assertThat(FileUtil.sanitizeFileName("\u2026")).isEmpty(); + assertThat(FileUtil.sanitizeFileName("q_test")).isSameAs("q_test"); + assertThat(FileUtil.sanitizeFileName("12_")).isSameAs("12_"); + assertThat(FileUtil.sanitizeFileName("12_ 123")).isEqualTo("12___123"); + assertThat(FileUtil.sanitizeFileName(" 12\u2026123")).isEqualTo("_12123"); - assertThat(FileUtil.sanitizeFileName("a+b+c"), equalTo("a_b_c")); + assertThat(FileUtil.sanitizeFileName("a+b+c")).isEqualTo("a_b_c"); } } diff --git a/platform/util/testSrc/com/intellij/util/io/UrlUtilTest.java b/platform/util/testSrc/com/intellij/util/io/UrlUtilTest.java index 207d52d6e109..89adedc50329 100644 --- a/platform/util/testSrc/com/intellij/util/io/UrlUtilTest.java +++ b/platform/util/testSrc/com/intellij/util/io/UrlUtilTest.java @@ -27,7 +27,7 @@ import com.intellij.openapi.vfs.CharsetToolkit; import org.jetbrains.annotations.Nullable; import org.junit.Test; -import static org.hamcrest.CoreMatchers.equalTo; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.*; public class UrlUtilTest { @@ -76,8 +76,8 @@ public class UrlUtilTest { @Test public void testDataUri() { byte[] test = "test".getBytes(CharsetToolkit.UTF8_CHARSET); - assertThat(URLUtil.getBytesFromDataUri("data:text/plain;charset=utf-8;base64,dGVzdA=="), equalTo(test)); + assertThat(URLUtil.getBytesFromDataUri("data:text/plain;charset=utf-8;base64,dGVzdA==")).isEqualTo(test); // https://youtrack.jetbrains.com/issue/WEB-14581#comment=27-1014790 - assertThat(URLUtil.getBytesFromDataUri("data:text/plain;charset:utf-8;base64,dGVzdA=="), equalTo(test)); + assertThat(URLUtil.getBytesFromDataUri("data:text/plain;charset:utf-8;base64,dGVzdA==")).isEqualTo(test); } } \ No newline at end of file diff --git a/plugins/java-decompiler/engine/java-decompiler-engine.iml b/plugins/java-decompiler/engine/java-decompiler-engine.iml index d56249d739ea..5880ebffc0b5 100644 --- a/plugins/java-decompiler/engine/java-decompiler-engine.iml +++ b/plugins/java-decompiler/engine/java-decompiler-engine.iml @@ -9,5 +9,6 @@ + \ No newline at end of file diff --git a/plugins/settings-repository/testSrc/BareGitTest.kt b/plugins/settings-repository/testSrc/BareGitTest.kt index 127634c5e68a..7df96855ffef 100644 --- a/plugins/settings-repository/testSrc/BareGitTest.kt +++ b/plugins/settings-repository/testSrc/BareGitTest.kt @@ -18,15 +18,13 @@ package org.jetbrains.settingsRepository.test import com.intellij.openapi.util.io.FileUtil import com.intellij.testFramework.TemporaryDirectory import gnu.trove.THashMap -import org.hamcrest.CoreMatchers.equalTo -import org.hamcrest.CoreMatchers.nullValue +import org.assertj.core.api.Assertions.assertThat import org.jetbrains.jgit.dirCache.AddFile import org.jetbrains.jgit.dirCache.edit import org.jetbrains.settingsRepository.git.cloneBare import org.jetbrains.settingsRepository.git.commit import org.jetbrains.settingsRepository.git.processChildren import org.jetbrains.settingsRepository.git.read -import org.junit.Assert.assertThat import org.junit.Rule import org.junit.Test import java.io.File @@ -37,7 +35,7 @@ class BareGitTest { public Test fun `remote doesn't have commits`() { val repository = cloneBare(tempDirManager.createRepository("remote").getWorkTree().getAbsolutePath(), tempDirManager.newDirectory("local")) - assertThat(repository.read("\$ROOT_CONFIG$/keymaps/Mac OS X from RubyMine.xml"), nullValue()) + assertThat(repository.read("\$ROOT_CONFIG$/keymaps/Mac OS X from RubyMine.xml")).isNull() } public Test fun bare() { @@ -50,7 +48,7 @@ class BareGitTest { remoteRepository.commit("") val repository = cloneBare(remoteRepository.getWorkTree().getAbsolutePath(), tempDirManager.newDirectory()) - assertThat(FileUtil.loadTextAndClose(repository.read(filePath)!!), equalTo(FileUtil.loadFile(file))) + assertThat(FileUtil.loadTextAndClose(repository.read(filePath)!!)).isEqualTo(FileUtil.loadFile(file)) } public Test fun processChildren() { @@ -71,7 +69,7 @@ class BareGitTest { true } - assertThat(data.size(), equalTo(1)) - assertThat(data.get("Mac OS X from RubyMine.xml"), equalTo(FileUtil.loadFile(file))) + assertThat(data).hasSize(1) + assertThat(data.get("Mac OS X from RubyMine.xml")).isEqualTo(FileUtil.loadFile(file)) } } \ No newline at end of file diff --git a/plugins/settings-repository/testSrc/CredentialsTest.kt b/plugins/settings-repository/testSrc/CredentialsTest.kt index a71a7515defa..7cd518b878ca 100644 --- a/plugins/settings-repository/testSrc/CredentialsTest.kt +++ b/plugins/settings-repository/testSrc/CredentialsTest.kt @@ -3,18 +3,14 @@ package org.jetbrains.settingsRepository.test import com.intellij.openapi.util.NotNullLazyValue import com.intellij.openapi.util.io.FileUtil import com.intellij.testFramework.UsefulTestCase +import org.assertj.core.api.Assertions.assertThat import org.eclipse.jgit.storage.file.FileRepositoryBuilder import org.eclipse.jgit.transport.CredentialItem import org.eclipse.jgit.transport.URIish -import org.hamcrest.CoreMatchers.equalTo -import org.hamcrest.CoreMatchers.not -import org.hamcrest.CoreMatchers.nullValue -import org.hamcrest.text.IsEmptyString.isEmptyString import org.jetbrains.keychain.CredentialsStore import org.jetbrains.keychain.FileCredentialsStore import org.jetbrains.settingsRepository.git.JGitCredentialsProvider import org.junit.After -import org.junit.Assert.assertThat import org.junit.Test import java.io.File @@ -40,12 +36,12 @@ class CredentialsTest { val username = CredentialItem.Username() val password = CredentialItem.Password() val uri = URIish("https://develar:bike@github.com/develar/settings-repository.git") - assertThat(createProvider(credentialsStore).get(uri, username, password), equalTo(true)) - assertThat(username.getValue(), equalTo("develar")) - assertThat(String(password.getValue()!!), equalTo("bike")) + assertThat(createProvider(credentialsStore).get(uri, username, password)).isTrue() + assertThat(username.getValue()).isEqualTo("develar") + assertThat(String(password.getValue()!!)).isEqualTo("bike") // ensure that credentials store was not used - assertThat(credentialsStore.get(uri.getHost()), nullValue()) - assertThat(storeFile?.exists(), equalTo(false)) + assertThat(credentialsStore.get(uri.getHost())).isNull() + assertThat(storeFile?.exists()).isFalse() } public Test fun gitCredentialHelper() { @@ -58,8 +54,8 @@ class CredentialsTest { val username = CredentialItem.Username() val password = CredentialItem.Password() val uri = URIish("https://develar@bitbucket.org/develar/test-ics.git") - assertThat(createProvider(credentialsStore).get(uri, username, password), equalTo(true)) - assertThat(username.getValue(), equalTo("develar")) - assertThat(String(password.getValue()!!), not(isEmptyString())) + assertThat(createProvider(credentialsStore).get(uri, username, password)).isTrue() + assertThat(username.getValue()).isEqualTo("develar") + assertThat(String(password.getValue()!!)).isNotEmpty() } } diff --git a/plugins/settings-repository/testSrc/GitTest.kt b/plugins/settings-repository/testSrc/GitTest.kt index aabd95dcaf87..cd677eba4b2b 100644 --- a/plugins/settings-repository/testSrc/GitTest.kt +++ b/plugins/settings-repository/testSrc/GitTest.kt @@ -281,6 +281,20 @@ class GitTest : TestCase() { compareFiles(fs()) } + Test fun `commit if unmerged`() { + createLocalRepository(null) + + sync(SyncType.MERGE) + + provider.delete("remote.xml", RoamingType.PER_USER) + repositoryManager.commit() + + sync(SyncType.MERGE) + restoreRemoteAfterPush() + + compareFiles(fs()) + } + // remote is uninitialized (empty - initial commit is not done) Test fun `merge with uninitialized upstream`() { doSyncWithUninitializedUpstream(SyncType.MERGE) diff --git a/plugins/settings-repository/testSrc/LoadTest.kt b/plugins/settings-repository/testSrc/LoadTest.kt index 505ca29e15d7..67dedd53c9d7 100644 --- a/plugins/settings-repository/testSrc/LoadTest.kt +++ b/plugins/settings-repository/testSrc/LoadTest.kt @@ -21,12 +21,11 @@ import com.intellij.configurationStore.TestSchemesProcessor import com.intellij.openapi.components.RoamingType import com.intellij.util.xmlb.serialize import com.intellij.util.xmlb.toByteArray +import org.assertj.core.api.Assertions.assertThat import org.eclipse.jgit.lib.Repository -import org.hamcrest.CoreMatchers.equalTo import org.jetbrains.settingsRepository.ReadonlySource import org.jetbrains.settingsRepository.git.cloneBare import org.jetbrains.settingsRepository.git.commit -import org.junit.Assert.assertThat import org.junit.Test import java.io.File @@ -42,7 +41,7 @@ class LoadTest : TestCase() { val schemesManager = createSchemeManager(dirPath) schemesManager.loadSchemes() - assertThat(schemesManager.getAllSchemes(), equalTo(listOf(localScheme))) + assertThat(schemesManager.getAllSchemes()).containsOnly(localScheme) } public Test fun `load scheme with the same names`() { @@ -53,7 +52,7 @@ class LoadTest : TestCase() { val schemesManager = createSchemeManager(dirPath) schemesManager.loadSchemes() - assertThat(schemesManager.getAllSchemes(), equalTo(listOf(localScheme))) + assertThat(schemesManager.getAllSchemes()).containsOnly(localScheme) } public Test fun `load scheme from repo and read-only repo`() { @@ -70,9 +69,9 @@ class LoadTest : TestCase() { remoteRepository.useAsReadOnlySource { val schemesManager = createSchemeManager(dirPath) schemesManager.loadSchemes() - assertThat(schemesManager.getAllSchemes(), equalTo(listOf(remoteScheme, localScheme))) - assertThat(schemesManager.isMetadataEditable(localScheme), equalTo(true)) - assertThat(schemesManager.isMetadataEditable(remoteScheme), equalTo(false)) + assertThat(schemesManager.getAllSchemes()).containsOnly(remoteScheme, localScheme) + assertThat(schemesManager.isMetadataEditable(localScheme)).isTrue() + assertThat(schemesManager.isMetadataEditable(remoteScheme)).isFalse() } } @@ -91,8 +90,8 @@ class LoadTest : TestCase() { remoteRepository.useAsReadOnlySource { val schemesManager = createSchemeManager(dirPath) schemesManager.loadSchemes() - assertThat(schemesManager.getAllSchemes(), equalTo(listOf(localScheme))) - assertThat(schemesManager.isMetadataEditable(localScheme), equalTo(false)) + assertThat(schemesManager.getAllSchemes()).containsOnly(localScheme) + assertThat(schemesManager.isMetadataEditable(localScheme)).isFalse() } } @@ -108,7 +107,7 @@ class LoadTest : TestCase() { fun Repository.createAndRegisterReadOnlySource(): ReadonlySource { val source = ReadonlySource(getWorkTree().getAbsolutePath()) - assertThat(cloneBare(source.url!!, File(icsManager.readOnlySourcesManager.rootDir, source.path!!)).getObjectDatabase().exists(), equalTo(true)) + assertThat(cloneBare(source.url!!, File(icsManager.readOnlySourcesManager.rootDir, source.path!!)).getObjectDatabase().exists()).isTrue() icsManager.readOnlySourcesManager.setSources(listOf(source)) return source } diff --git a/plugins/settings-repository/testSrc/RespositoryHelper.kt b/plugins/settings-repository/testSrc/RespositoryHelper.kt index 023ad01d2908..9b0831550dd0 100644 --- a/plugins/settings-repository/testSrc/RespositoryHelper.kt +++ b/plugins/settings-repository/testSrc/RespositoryHelper.kt @@ -16,12 +16,10 @@ package org.jetbrains.settingsRepository.test import com.intellij.mock.MockVirtualFileSystem -import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.vfs.VirtualFile import com.intellij.util.ArrayUtil +import org.assertj.core.api.Assertions.assertThat import org.eclipse.jgit.lib.Constants -import org.hamcrest.CoreMatchers.equalTo -import org.junit.Assert.assertThat import java.io.File import java.util.Arrays import java.util.Comparator @@ -52,7 +50,7 @@ private fun compareFiles(local: File, remote: File, expected: VirtualFile? = nul } } - assertThat(localFiles, equalTo(remoteFiles)) + assertThat(localFiles).isEqualTo(remoteFiles) val expectedFiles: Array? if (expected == null) { @@ -68,7 +66,7 @@ private fun compareFiles(local: File, remote: File, expected: VirtualFile? = nul }) for (i in 0..expectedFiles.size() - 1) { - assertThat(localFiles[i], equalTo(expectedFiles[i].getName())) + assertThat(localFiles[i]).isEqualTo(expectedFiles[i].getName()) } } @@ -81,11 +79,11 @@ private fun compareFiles(local: File, remote: File, expected: VirtualFile? = nul } else { expectedFile = expectedFiles[i] - assertThat(expectedFile.isDirectory(), equalTo(localFile.isDirectory())) + assertThat(expectedFile.isDirectory()).isEqualTo(localFile.isDirectory()) } if (localFile.isFile()) { - assertThat(FileUtil.loadFile(localFile), equalTo(FileUtil.loadFile(remoteFile))) + assertThat(localFile).hasSameContentAs(remoteFile) } else { compareFiles(localFile, remoteFile, expectedFile, *localExcludes) diff --git a/python/testSrc/python-community-tests.iml b/python/testSrc/python-community-tests.iml index 76f778bf6b5c..be7e234cfd0e 100644 --- a/python/testSrc/python-community-tests.iml +++ b/python/testSrc/python-community-tests.iml @@ -21,5 +21,6 @@ + \ No newline at end of file From 33749f8eb66b1610149886b37dbb7f3e2f628b7b Mon Sep 17 00:00:00 2001 From: "liana.bakradze" Date: Tue, 25 Aug 2015 11:19:52 +0300 Subject: [PATCH 008/246] fixed task text for local courses --- .../edu/learning/ui/StudyToolWindow.java | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java index 9e44f6458b36..a060a8d69062 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java @@ -20,6 +20,7 @@ import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.ActionToolbar; import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.fileEditor.FileEditorManager; @@ -27,11 +28,13 @@ import com.intellij.openapi.fileEditor.FileEditorManagerEvent; import com.intellij.openapi.fileEditor.FileEditorManagerListener; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.SimpleToolWindowPanel; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.BrowserHyperlinkListener; import com.intellij.ui.components.JBScrollPane; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UIUtil; +import com.jetbrains.edu.EduNames; import com.jetbrains.edu.courseFormat.Task; import com.jetbrains.edu.courseFormat.TaskFile; import com.jetbrains.edu.learning.StudyUtils; @@ -45,6 +48,7 @@ import javax.swing.border.EmptyBorder; import javax.swing.text.html.HTMLDocument; import javax.swing.text.html.HTMLEditorKit; import java.awt.*; +import java.io.IOException; public class StudyToolWindow extends SimpleToolWindowPanel implements DataProvider, Disposable { @@ -116,6 +120,7 @@ public class StudyToolWindow extends SimpleToolWindowPanel implements DataProvid } static class StudyFileEditorManagerListener implements FileEditorManagerListener { + private static final Logger LOG = Logger.getInstance(StudyFileEditorManagerListener.class); private Project myProject; private JTextPane myTaskTextPane; @@ -127,7 +132,7 @@ public class StudyToolWindow extends SimpleToolWindowPanel implements DataProvid @Override public void fileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile file) { Task task = getTask(file); - setTaskText(task); + setTaskText(task, file.getParent()); } @Override @@ -140,7 +145,7 @@ public class StudyToolWindow extends SimpleToolWindowPanel implements DataProvid VirtualFile file = event.getNewFile(); if (file != null) { Task task = getTask(file); - setTaskText(task); + setTaskText(task, file); } } @@ -155,12 +160,23 @@ public class StudyToolWindow extends SimpleToolWindowPanel implements DataProvid } } - private void setTaskText(@Nullable final Task task) { + private void setTaskText(@Nullable final Task task, @Nullable final VirtualFile taskDirectory) { if (task == null) { myTaskTextPane.setText(EMPTY_TASK_TEXT); return; } String text = task.getText(); + if (text == null && taskDirectory != null) { + VirtualFile taskTextFile = taskDirectory.findChild(EduNames.TASK_HTML); + if (taskTextFile != null) { + try { + text = FileUtil.loadTextAndClose(taskTextFile.getInputStream()); + } + catch (IOException e) { + LOG.info(e); + } + } + } myTaskTextPane.setText(text); } } From bb47a8b8173585db671fa12c4e217dd7550b1022 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Tue, 25 Aug 2015 11:42:09 +0300 Subject: [PATCH 009/246] fixed EDU-408 Error when trying to upload course to stepic with incorrect credentials --- .../com/jetbrains/edu/stepic/EduStepicConnector.java | 5 ++++- .../src/com/jetbrains/edu/stepic/LoginDialog.java | 10 ++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/python/educational/src/com/jetbrains/edu/stepic/EduStepicConnector.java b/python/educational/src/com/jetbrains/edu/stepic/EduStepicConnector.java index 46a02a0b3a94..54ca40cc5a5b 100644 --- a/python/educational/src/com/jetbrains/edu/stepic/EduStepicConnector.java +++ b/python/educational/src/com/jetbrains/edu/stepic/EduStepicConnector.java @@ -132,6 +132,7 @@ public class EduStepicConnector { } catch (UnsupportedEncodingException e) { LOG.error(e.getMessage()); + ourClient = null; return false; } @@ -144,11 +145,13 @@ public class EduStepicConnector { final StatusLine line = response.getStatusLine(); if (line.getStatusCode() != 302) { LOG.error("Failed to login " + EntityUtils.toString(response.getEntity())); + ourClient = null; return false; } } catch (IOException e) { - LOG.error(e.getMessage()); + LOG.warn(e.getMessage()); + ourClient = null; return false; } return true; diff --git a/python/educational/src/com/jetbrains/edu/stepic/LoginDialog.java b/python/educational/src/com/jetbrains/edu/stepic/LoginDialog.java index d71c6206bf86..0424f47af716 100644 --- a/python/educational/src/com/jetbrains/edu/stepic/LoginDialog.java +++ b/python/educational/src/com/jetbrains/edu/stepic/LoginDialog.java @@ -39,13 +39,15 @@ public class LoginDialog extends DialogWrapper { @Override protected void doOKAction() { AuthDataHolder authData = myLoginPanel.getAuthData(); - StudySettings.getInstance().setLogin(authData.email); - StudySettings.getInstance().setPassword(authData.password); final boolean success = EduStepicConnector.login(authData.email, authData.password); if (!success) { - setErrorText("Log in failed"); + setErrorText("Login failed"); + } + else { + StudySettings.getInstance().setLogin(authData.email); + StudySettings.getInstance().setPassword(authData.password); + super.doOKAction(); } - super.doOKAction(); } public void clearErrors() { From fe897f2ee2aef3cba4ad44076fd84b7843fee061 Mon Sep 17 00:00:00 2001 From: "Vladislav.Soroka" Date: Tue, 25 Aug 2015 12:10:06 +0300 Subject: [PATCH 010/246] IDEA-97324 Maven support cannot handle skinny wars for EAR deployments --- ...enManifestGenerationBuildTaskProvider.java | 47 ++++++++++++++----- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/compiler/MavenManifestGenerationBuildTaskProvider.java b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/compiler/MavenManifestGenerationBuildTaskProvider.java index f65ee59c26c2..19f1b81db9f3 100644 --- a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/compiler/MavenManifestGenerationBuildTaskProvider.java +++ b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/compiler/MavenManifestGenerationBuildTaskProvider.java @@ -26,28 +26,30 @@ import com.intellij.util.Processor; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jps.builders.BuildRootDescriptor; import org.jetbrains.jps.builders.artifacts.ArtifactBuildTaskProvider; import org.jetbrains.jps.builders.storage.BuildDataPaths; -import org.jetbrains.jps.cmdline.ProjectDescriptor; import org.jetbrains.jps.incremental.BuildTask; import org.jetbrains.jps.incremental.CompileContext; +import org.jetbrains.jps.incremental.FSOperations; import org.jetbrains.jps.incremental.ProjectBuildException; import org.jetbrains.jps.incremental.artifacts.impl.JpsArtifactUtil; +import org.jetbrains.jps.incremental.fs.CompilationRound; import org.jetbrains.jps.maven.model.JpsMavenExtensionService; import org.jetbrains.jps.maven.model.impl.MavenModuleResourceConfiguration; import org.jetbrains.jps.maven.model.impl.MavenProjectConfiguration; import org.jetbrains.jps.model.artifact.JpsArtifact; import org.jetbrains.jps.model.artifact.elements.JpsArtifactRootElement; +import org.jetbrains.jps.model.artifact.elements.JpsDirectoryPackagingElement; import org.jetbrains.jps.model.artifact.elements.JpsFileCopyPackagingElement; import org.jetbrains.jps.model.artifact.elements.JpsPackagingElement; +import org.jetbrains.jps.model.ex.JpsElementBase; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import java.util.Collection; import java.util.Collections; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.jar.Attributes; @@ -120,8 +122,9 @@ public class MavenManifestGenerationBuildTaskProvider extends ArtifactBuildTaskP @Override public boolean process(JpsPackagingElement element) { if (!(element instanceof JpsFileCopyPackagingElement)) return true; + final JpsFileCopyPackagingElement fileCopyPackagingElement = (JpsFileCopyPackagingElement)element; - final String filePath = ((JpsFileCopyPackagingElement)element).getFilePath(); + final String filePath = fileCopyPackagingElement.getFilePath(); final File skinnyManifest = new File(filePath); if (!"SKINNY_MANIFEST.MF".equals(skinnyManifest.getName())) return true; @@ -144,26 +147,44 @@ public class MavenManifestGenerationBuildTaskProvider extends ArtifactBuildTaskP final Attributes warManifestMainAttributes = warManifest.getMainAttributes(); warManifestMainAttributes.putValue("Class-Path", StringUtil.join(skinnyWarClasspath, " ")); + File skinnyManifestTargetFile = null; FileUtil.createParentDirs(skinnyManifest); FileOutputStream outputStream = new FileOutputStream(skinnyManifest); try { warManifest.write(outputStream); - final ProjectDescriptor projectDescriptor = context.getProjectDescriptor(); - final Collection descriptors = - projectDescriptor.getBuildRootIndex().findAllParentDescriptors(skinnyManifest, context); - for (BuildRootDescriptor descriptor : descriptors) { - try { - projectDescriptor.fsState.markDirty(context, skinnyManifest, descriptor, projectDescriptor.timestamps.getStorage()); - } - catch (IOException e) { - LOG.debug(e); + if (fileCopyPackagingElement instanceof JpsElementBase) { + final LinkedList pathParts = new LinkedList(); + pathParts.add(fileCopyPackagingElement.getRenamedOutputFileName()); + + JpsElementBase parent = ((JpsElementBase)fileCopyPackagingElement).getParent(); + while (parent != null) { + if (parent instanceof JpsDirectoryPackagingElement) { + pathParts.addFirst(((JpsDirectoryPackagingElement)parent).getDirectoryName()); + } + else if (parent instanceof JpsArtifact) { + final String outputPath = ((JpsArtifact)parent).getOutputPath(); + if (outputPath != null) { + pathParts.addFirst(outputPath); + skinnyManifestTargetFile = new File(StringUtil.join(pathParts, "/")); + break; + } + } + parent = parent.getParent(); } } } finally { StreamUtil.closeStream(outputStream); } + + if (skinnyManifestTargetFile != null) { + FileUtil.createParentDirs(skinnyManifestTargetFile); + FileUtil.copy(skinnyManifest, skinnyManifestTargetFile); + } + + FSOperations.markDirtyIfNotDeleted(context, CompilationRound.NEXT, skinnyManifest); + FSOperations.markDirtyIfNotDeleted(context, CompilationRound.NEXT, skinnyManifestTargetFile); } catch (IOException e) { LOG.debug(e); From f1590c61bccb27b566c6fc2fc850138095b7beb1 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Tue, 25 Aug 2015 12:14:49 +0300 Subject: [PATCH 011/246] IDEA-143508 Keymap abbreviations don't work in the Find Action popup --- .../gotoByName/GotoActionItemProvider.java | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionItemProvider.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionItemProvider.java index 6fbb00edc1f5..5090a0a51c27 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionItemProvider.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionItemProvider.java @@ -23,10 +23,7 @@ import com.intellij.ide.ui.search.ActionFromOptionDescriptorProvider; import com.intellij.ide.ui.search.OptionDescription; import com.intellij.ide.ui.search.SearchableOptionsRegistrar; import com.intellij.ide.ui.search.SearchableOptionsRegistrarImpl; -import com.intellij.openapi.actionSystem.ActionManager; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.impl.ActionManagerImpl; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; @@ -40,6 +37,7 @@ import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashSet; import gnu.trove.TObjectHashingStrategy; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -91,6 +89,7 @@ public class GotoActionItemProvider implements ChooseByNameItemProvider { public boolean filterElements(String pattern, boolean everywhere, Processor consumer) { DataContext dataContext = DataManager.getInstance().getDataContext(myModel.getContextComponent()); + if (!processAbbreviations(pattern, consumer, dataContext)) return false; if (!processIntentions(pattern, consumer, dataContext)) return false; if (!processActions(pattern, everywhere, consumer, dataContext)) return false; if (!processTopHits(pattern, consumer, dataContext)) return false; @@ -99,6 +98,28 @@ public class GotoActionItemProvider implements ChooseByNameItemProvider { return true; } + private boolean processAbbreviations(final String pattern, Processor consumer, DataContext context) { + List actions = AbbreviationManager.getInstance().findActions(pattern); + if (actions.isEmpty()) return true; + List wrappers = ContainerUtil.newArrayListWithCapacity(actions.size()); + for (String actionId : actions) { + AnAction action = myActionManager.getAction(actionId); + wrappers.add(new ActionWrapper(action, myModel.myActionGroups.get(action), MatchMode.NAME, context)); + } + return ContainerUtil.process(ContainerUtil.map(wrappers, new Function() { + @Override + public MatchedValue fun(@NotNull ActionWrapper w) { + return new MatchedValue(w, pattern) { + @Nullable + @Override + public String getValueText() { + return pattern; + } + }; + } + }), consumer); + } + private static boolean processTopHits(String pattern, Processor consumer, DataContext dataContext) { Project project = CommonDataKeys.PROJECT.getData(dataContext); final CollectConsumer collector = new CollectConsumer(); From ca61b21ae544e9b8e288af78f008c8657e1e8c48 Mon Sep 17 00:00:00 2001 From: Alexey Gopachenko Date: Tue, 25 Aug 2015 10:48:15 +0200 Subject: [PATCH 012/246] Collect*Uniques*Processor, Externalizer --- spellchecker/src/com/intellij/spellchecker/jetbrains.dic | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spellchecker/src/com/intellij/spellchecker/jetbrains.dic b/spellchecker/src/com/intellij/spellchecker/jetbrains.dic index d60d3b38ace4..e31914515118 100644 --- a/spellchecker/src/com/intellij/spellchecker/jetbrains.dic +++ b/spellchecker/src/com/intellij/spellchecker/jetbrains.dic @@ -154,6 +154,7 @@ eval evex exif expr +externalizer facebook facelet fallthrough @@ -627,6 +628,7 @@ undofile unescaped unhandled uninstall +uniques unmerged unpivot unprotect From 774cfb5755d3a3de49872aede5ea2c965a70d6ec Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 25 Aug 2015 12:42:49 +0300 Subject: [PATCH 013/246] delete temp files on exit by default --- .../util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java b/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java index a5bfbd98070a..457da71ca778 100644 --- a/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java +++ b/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java @@ -308,7 +308,7 @@ public class FileUtilRt { @NotNull public static File createTempFile(@NotNull @NonNls String prefix, @Nullable @NonNls String suffix) throws IOException { - return createTempFile(prefix, suffix, false); //false until TeamCity fixes its plugin + return createTempFile(prefix, suffix, true); // deleteOnExit by default } @NotNull From 4f4a7d7a71a2bea51ffba59e3a0a198c06694e0d Mon Sep 17 00:00:00 2001 From: Alexander Kass Date: Thu, 30 Jul 2015 13:25:53 +0300 Subject: [PATCH 014/246] BidirectionalMultiMap: support set types override --- .../util/containers/BidirectionalMultiMap.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/platform/util/src/com/intellij/util/containers/BidirectionalMultiMap.java b/platform/util/src/com/intellij/util/containers/BidirectionalMultiMap.java index 1405fb1ed232..c18304d76293 100644 --- a/platform/util/src/com/intellij/util/containers/BidirectionalMultiMap.java +++ b/platform/util/src/com/intellij/util/containers/BidirectionalMultiMap.java @@ -61,19 +61,29 @@ public class BidirectionalMultiMap { public boolean put(K key, V value) { Set ks = myValue2Keys.get(value); if (ks == null) { - ks = new HashSet(); + ks = createKeysSet(); myValue2Keys.put(value, ks); } ks.add(key); Set vs = myKey2Values.get(key); if (vs == null) { - vs = new HashSet(); + vs = createValuesSet(); myKey2Values.put(key, vs); } return vs.add(value); } + @NotNull + protected Set createValuesSet() { + return new HashSet(); + } + + @NotNull + protected Set createKeysSet() { + return new HashSet(); + } + public boolean removeKey(K key) { final Set vs = myKey2Values.get(key); if (vs == null) return false; From bf3bbf9746d2c28585bbe48fc02761193a5ab16a Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Aug 2015 09:49:45 +0200 Subject: [PATCH 015/246] IDEA-144278 IAE at com.intellij.psi.impl.search.PsiSearchHelperImpl.processElementsWithWord --- .../psi/impl/search/VariableInIncompleteCodeSearcher.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/VariableInIncompleteCodeSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/VariableInIncompleteCodeSearcher.java index c4aa59f47629..5d6a88887e43 100644 --- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/VariableInIncompleteCodeSearcher.java +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/VariableInIncompleteCodeSearcher.java @@ -16,6 +16,7 @@ package com.intellij.psi.impl.search; import com.intellij.openapi.application.QueryExecutorBase; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.search.*; import com.intellij.psi.search.searches.ReferencesSearch; @@ -36,7 +37,7 @@ public class VariableInIncompleteCodeSearcher extends QueryExecutorBase Date: Tue, 25 Aug 2015 13:08:25 +0200 Subject: [PATCH 016/246] shorten too long notification texts before showing a balloon (IDEA-144301) --- .../impl/ui/NotificationsUtil.java | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsUtil.java b/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsUtil.java index b94fb222503b..abb84610a119 100644 --- a/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsUtil.java +++ b/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsUtil.java @@ -17,7 +17,9 @@ package com.intellij.notification.impl.ui; import com.intellij.notification.Notification; import com.intellij.notification.NotificationListener; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.ui.MessageType; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.ColorUtil; import com.intellij.ui.JBColor; import com.intellij.xml.util.XmlStringUtil; @@ -33,29 +35,35 @@ import java.awt.*; * @author spleaner */ public class NotificationsUtil { - - private NotificationsUtil() { - } + private static final Logger LOG = Logger.getInstance("#com.intellij.notification.impl.ui.NotificationsUtil"); + private static final int TITLE_LIMIT = 1000; + private static final int CONTENT_LIMIT = 10000; public static String buildHtml(@NotNull final Notification notification, @Nullable String style) { - String result = ""; - if (style != null) { - result += "
"; + String title = notification.getTitle(); + String content = notification.getContent(); + if (title.length() > TITLE_LIMIT || content.length() > CONTENT_LIMIT) { + LOG.info("Too large notification " + notification + " of " + notification.getClass() + + "\nListener=" + notification.getListener() + + "\nTitle=" + title + + "\nContent=" + content); + title = StringUtil.trimLog(title, TITLE_LIMIT); + content = StringUtil.trimLog(content, CONTENT_LIMIT); } - result += "" + notification.getTitle() + "" + - "

" + notification.getContent() + "

"; - if (style != null) { - result += "
"; - } - return XmlStringUtil.wrapInHtml(result); + return buildHtml(title, content, style, "#" + ColorUtil.toHex(getMessageType(notification).getTitleForeground())); } public static String buildHtml(@NotNull final String title, @NotNull final String content, @Nullable String style) { + return buildHtml(title, content, style, null); + } + + @NotNull + private static String buildHtml(@NotNull String title, @NotNull String content, @Nullable String style, @Nullable String color) { String result = ""; if (style != null) { result += "
"; } - result += "" + title + "

" + content + "

"; + result += "" : " color=\"" + color + "\">") + title + "

" + content + "

"; if (style != null) { result += "
"; } @@ -81,12 +89,7 @@ public class NotificationsUtil { public static Icon getIcon(@NotNull final Notification notification) { Icon icon = notification.getIcon(); - - if (icon == null) { - icon = getMessageType(notification).getDefaultIcon(); - } - - return icon; + return icon != null ? icon : getMessageType(notification).getDefaultIcon(); } public static MessageType getMessageType(@NotNull Notification notification) { From c12f1a627b1bac3666faaa368bcf3fc8bb3367c3 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 25 Aug 2015 13:45:42 +0200 Subject: [PATCH 017/246] IDEA-143759 Repository contains unmerged paths. Merge not work for me --- .../src/BaseRepositoryManager.kt | 51 ++++---- plugins/settings-repository/src/IcsManager.kt | 4 +- .../src/git/JGitMergeProvider.kt | 48 +++++--- plugins/settings-repository/src/git/pull.kt | 114 +++++++++++------- plugins/settings-repository/src/git/reset.kt | 5 +- plugins/settings-repository/src/sync.kt | 10 +- .../settings-repository/testSrc/GitTest.kt | 63 ++++++++-- 7 files changed, 194 insertions(+), 101 deletions(-) diff --git a/plugins/settings-repository/src/BaseRepositoryManager.kt b/plugins/settings-repository/src/BaseRepositoryManager.kt index 04e185a32ad8..1112919d9139 100644 --- a/plugins/settings-repository/src/BaseRepositoryManager.kt +++ b/plugins/settings-repository/src/BaseRepositoryManager.kt @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2015 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 org.jetbrains.settingsRepository import com.intellij.openapi.application.ApplicationManager @@ -6,18 +21,15 @@ import com.intellij.openapi.fileTypes.StdFileTypes import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.vcs.merge.MergeDialogCustomizer import com.intellij.openapi.vcs.merge.MergeProvider2 -import com.intellij.openapi.vcs.merge.MergeSession import com.intellij.openapi.vcs.merge.MultipleFileMergeDialog import com.intellij.openapi.vfs.CharsetToolkit import com.intellij.openapi.vfs.VirtualFile import com.intellij.testFramework.LightVirtualFile import com.intellij.util.PathUtilRt -import org.jetbrains.annotations.TestOnly import java.io.File import java.io.FileInputStream import java.io.InputStream import java.io.OutputStream -import java.util.Arrays import java.util.concurrent.locks.ReentrantReadWriteLock import kotlin.concurrent.read import kotlin.concurrent.write @@ -158,38 +170,25 @@ fun File.removeWithParentsIfEmpty(root: File, isFile: Boolean = true) { } } } -// kotlin bug, cannot be val (.NoSuchMethodError: org.jetbrains.settingsRepository.SettingsRepositoryPackage.getMARKER_ACCEPT_MY()[B) -TestOnly object AM { - val MARKER_ACCEPT_MY: ByteArray = "__accept my__".toByteArray() - val MARKER_ACCEPT_THEIRS: ByteArray = "__accept theirs__".toByteArray() -} + +var conflictResolver: ((files: List, mergeProvider: MergeProvider2) -> Unit)? = null fun resolveConflicts(files: List, mergeProvider: MergeProvider2): List { if (ApplicationManager.getApplication()!!.isUnitTestMode()) { - val mergeSession = mergeProvider.createMergeSession(files) - for (file in files) { - val mergeData = mergeProvider.loadRevisions(file) - if (Arrays.equals(mergeData.CURRENT, AM.MARKER_ACCEPT_MY) || Arrays.equals(mergeData.LAST, AM.MARKER_ACCEPT_THEIRS)) { - mergeSession.conflictResolvedForFile(file, MergeSession.Resolution.AcceptedYours) - } - else if (Arrays.equals(mergeData.CURRENT, AM.MARKER_ACCEPT_THEIRS) || Arrays.equals(mergeData.LAST, AM.MARKER_ACCEPT_MY)) { - mergeSession.conflictResolvedForFile(file, MergeSession.Resolution.AcceptedTheirs) - } - else if (Arrays.equals(mergeData.LAST, AM.MARKER_ACCEPT_MY)) { - file.setBinaryContent(mergeData.LAST!!) - mergeProvider.conflictResolvedForFile(file) - } - else { - throw UnsupportedOperationException() - } + if (conflictResolver == null) { + throw CannotResolveConflictInTestMode() + } + else { + conflictResolver!!(files, mergeProvider) } - return files } var processedFiles: List? = null invokeAndWaitIfNeed { - val fileMergeDialog = MultipleFileMergeDialog(null, files, mergeProvider, MergeDialogCustomizer()) + val fileMergeDialog = MultipleFileMergeDialog(null, files, mergeProvider, object : MergeDialogCustomizer() { + override fun getMultipleFileDialogTitle() = "Settings Repository: Files Merged with Conflicts" + }) fileMergeDialog.show() processedFiles = fileMergeDialog.getProcessedFiles() } diff --git a/plugins/settings-repository/src/IcsManager.kt b/plugins/settings-repository/src/IcsManager.kt index c99af441899e..27ff98ad2fb9 100644 --- a/plugins/settings-repository/src/IcsManager.kt +++ b/plugins/settings-repository/src/IcsManager.kt @@ -289,6 +289,4 @@ class IcsApplicationLoadListener : ApplicationLoadListener { icsManager.beforeApplicationLoaded(application) } -} - -class NoRemoteRepositoryException(cause: Throwable) : RuntimeException(cause.getMessage(), cause) \ No newline at end of file +} \ No newline at end of file diff --git a/plugins/settings-repository/src/git/JGitMergeProvider.kt b/plugins/settings-repository/src/git/JGitMergeProvider.kt index e240fb435441..7a96d319e90e 100644 --- a/plugins/settings-repository/src/git/JGitMergeProvider.kt +++ b/plugins/settings-repository/src/git/JGitMergeProvider.kt @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2015 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 org.jetbrains.settingsRepository.git import com.intellij.openapi.fileEditor.FileDocumentManager @@ -6,9 +21,8 @@ import com.intellij.openapi.vcs.merge.MergeProvider2 import com.intellij.openapi.vcs.merge.MergeSession import com.intellij.openapi.vfs.CharsetToolkit import com.intellij.openapi.vfs.VirtualFile +import com.intellij.util.ArrayUtil import com.intellij.util.ui.ColumnInfo -import org.eclipse.jgit.diff.RawText -import org.eclipse.jgit.lib.ObjectId import org.eclipse.jgit.lib.Repository import org.jetbrains.jgit.dirCache.deletePath import org.jetbrains.jgit.dirCache.writePath @@ -16,7 +30,7 @@ import org.jetbrains.settingsRepository.RepositoryVirtualFile import java.nio.CharBuffer import java.util.ArrayList -private fun conflictsToVirtualFiles(map: Map>): MutableList { +private fun conflictsToVirtualFiles(map: Map): MutableList { val result = ArrayList(map.size()) for (path in map.keySet()) { result.add(RepositoryVirtualFile(path)) @@ -24,7 +38,12 @@ private fun conflictsToVirtualFiles(map: Map>) : MergeProvider2 { +/** + * If content null: + * Ours or Theirs - deleted. + * Base - missed (no base). + */ +class JGitMergeProvider(private val repository: Repository, private val conflicts: Map, private val pathToContent: Map.(path: String, index: Int) -> ByteArray?) : MergeProvider2 { override fun createMergeSession(files: List) = JGitMergeSession() override fun conflictResolvedForFile(file: VirtualFile) { @@ -42,22 +61,23 @@ class JGitMergeProvider(private val repository: Repository, private val myCommit } } - // cannot be private due to Kotlin bug - fun addFile(bytes: ByteArray, file: VirtualFile, size: Int = bytes.size()) { + private fun addFile(bytes: ByteArray, file: VirtualFile, size: Int = bytes.size()) { repository.writePath(file.getPath(), bytes, size) } override fun isBinary(file: VirtualFile) = file.getFileType().isBinary() override fun loadRevisions(file: VirtualFile): MergeData { - val sequences = conflicts[file.getPath()]!!.getSequences() + val path = file.getPath() val mergeData = MergeData() - mergeData.ORIGINAL = (sequences[0] as RawText).getContent() - mergeData.CURRENT = (sequences[1] as RawText).getContent() - mergeData.LAST = (sequences[2] as RawText).getContent() + mergeData.ORIGINAL = getContentOrEmpty(path, 0) + mergeData.CURRENT = getContentOrEmpty(path, 1) + mergeData.LAST = getContentOrEmpty(path, 2) return mergeData } + private fun getContentOrEmpty(path: String, index: Int) = conflicts.pathToContent(path, index) ?: ArrayUtil.EMPTY_BYTE_ARRAY + private inner class JGitMergeSession : MergeSession { override fun getMergeInfoColumns(): Array> { return arrayOf(StatusColumn(false), StatusColumn(true)) @@ -71,19 +91,19 @@ class JGitMergeProvider(private val repository: Repository, private val myCommit } else { val content = getContent(file, resolution == MergeSession.Resolution.AcceptedTheirs) - if (content == RawText.EMPTY_TEXT) { + if (content == null) { repository.deletePath(file.getPath()) } else { - addFile(content.getContent(), file) + addFile(content, file) } } } - private fun getContent(file: VirtualFile, isTheirs: Boolean) = conflicts[file.getPath()]!!.getSequences()[if (isTheirs) 2 else 1] as RawText + private fun getContent(file: VirtualFile, isTheirs: Boolean) = conflicts.pathToContent(file.getPath(), if (isTheirs) 2 else 1) inner class StatusColumn(private val isTheirs: Boolean) : ColumnInfo(if (isTheirs) "Theirs" else "Yours") { - override fun valueOf(file: VirtualFile?) = if (getContent(file!!, isTheirs) == RawText.EMPTY_TEXT) "Deleted" else "Modified" + override fun valueOf(file: VirtualFile?) = if (getContent(file!!, isTheirs) == null) "Deleted" else "Modified" override fun getMaxStringValue() = "Modified" diff --git a/plugins/settings-repository/src/git/pull.kt b/plugins/settings-repository/src/git/pull.kt index 38ca8ced5923..b5a286166783 100644 --- a/plugins/settings-repository/src/git/pull.kt +++ b/plugins/settings-repository/src/git/pull.kt @@ -17,6 +17,8 @@ package org.jetbrains.settingsRepository.git import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.vfs.VirtualFile +import com.intellij.util.SmartList +import com.intellij.util.containers.hash.LinkedHashMap import org.eclipse.jgit.api.MergeCommand.FastForwardMode import org.eclipse.jgit.api.MergeResult import org.eclipse.jgit.api.MergeResult.MergeStatus @@ -24,6 +26,8 @@ import org.eclipse.jgit.api.errors.CheckoutConflictException import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException import org.eclipse.jgit.api.errors.JGitInternalException import org.eclipse.jgit.api.errors.NoHeadException +import org.eclipse.jgit.diff.RawText +import org.eclipse.jgit.diff.Sequence import org.eclipse.jgit.dircache.DirCacheCheckout import org.eclipse.jgit.internal.JGitText import org.eclipse.jgit.lib.* @@ -38,7 +42,6 @@ import org.eclipse.jgit.treewalk.FileTreeIterator import org.jetbrains.settingsRepository.* import java.io.IOException import java.text.MessageFormat -import java.util.ArrayList open class Pull(val manager: GitRepositoryManager, val indicator: ProgressIndicator?, val commitMessageFormatter: CommitMessageFormatter = IdeaCommitMessageFormatter()) { val repository = manager.repository @@ -53,13 +56,30 @@ open class Pull(val manager: GitRepositoryManager, val indicator: ProgressIndica LOG.debug("Pull") val repository = manager.repository - val repositoryState = repository.getRepositoryState() + var repositoryState = repository.getRepositoryState() + if (repositoryState == RepositoryState.MERGING) { + val conflicts = LinkedHashMap>() + val dirCache = repository.readDirCache() + val reader = repository.newObjectReader() + reader.use { + for (i in 0..(dirCache.getEntryCount() - 1)) { + val entry = dirCache.getEntry(i) + if (!entry.isMerged()) { + conflicts.getOrPut(entry.getPathString(), { arrayOfNulls(3) })[entry.getStage() - 1] = reader.open(entry.getObjectId(), Constants.OBJ_BLOB).getCachedBytes() + } + } + } + + resolveConflicts(JGitMergeProvider(repository, conflicts, { path, index -> get(path)!!.get(index) }), conflictsToVirtualFiles(conflicts), repository) + // compute new state + repositoryState = repository.getRepositoryState() + } + if (repositoryState != RepositoryState.SAFE) { LOG.warn(MessageFormat.format(JGitText.get().cannotPullOnARepoWithState, repositoryState.name())) } - val refToMerge = prefetchedRefToMerge ?: fetch() ?: return null - + var refToMerge = prefetchedRefToMerge ?: fetch() ?: return null val mergeResult = merge(refToMerge, mergeStrategy, commitMessage = commitMessage) val mergeStatus = mergeResult.mergeStatus if (LOG.isDebugEnabled()) { @@ -67,31 +87,7 @@ open class Pull(val manager: GitRepositoryManager, val indicator: ProgressIndica } if (mergeStatus == MergeStatus.CONFLICTING) { - val mergedCommits = mergeResult.mergedCommits - assert(mergedCommits.size() == 2) - val conflicts = mergeResult.conflicts!! - var unresolvedFiles = conflictsToVirtualFiles(conflicts) - val mergeProvider = JGitMergeProvider(repository, mergedCommits[0]!!, mergedCommits[1]!!, conflicts) - val resolvedFiles: List - val mergedFiles = ArrayList() - while (true) { - resolvedFiles = resolveConflicts(unresolvedFiles, mergeProvider) - - for (file in resolvedFiles) { - mergedFiles.add(file.getPath()) - } - - if (resolvedFiles.size() == unresolvedFiles.size()) { - break - } - else { - unresolvedFiles.removeAll(mergedFiles) - } - } - - repository.commit() - - return mergeResult.result.toMutable().addChanged(mergedFiles) + return resolveConflicts(mergeResult, repository) } else if (!mergeStatus.isSuccessful()) { throw IllegalStateException(mergeResult.toString()) @@ -104,9 +100,7 @@ open class Pull(val manager: GitRepositoryManager, val indicator: ProgressIndica fun fetch(prevRefUpdateResult: RefUpdate.Result? = null): Ref? { indicator?.checkCanceled() - val repository = manager.repository - - val fetchResult = repository.fetch(remoteConfig, manager.credentialsProvider, indicator.asProgressMonitor()) ?: return null + val fetchResult = manager.repository.fetch(remoteConfig, manager.credentialsProvider, indicator.asProgressMonitor()) ?: return null if (LOG.isDebugEnabled()) { printMessages(fetchResult) @@ -129,10 +123,10 @@ open class Pull(val manager: GitRepositoryManager, val indicator: ProgressIndica // we can have more than one fetch ref spec, but currently we don't worry about it if (refUpdateResult == RefUpdate.Result.LOCK_FAILURE || refUpdateResult == RefUpdate.Result.IO_FAILURE) { if (prevRefUpdateResult == refUpdateResult) { - throw IOException("Ref update result " + refUpdateResult.name() + ", we have already tried to fetch again, but no luck") + throw IOException("Ref update result ${refUpdateResult.name()}, we have already tried to fetch again, but no luck") } - LOG.warn("Ref update result " + refUpdateResult.name() + ", trying again after 500 ms") + LOG.warn("Ref update result ${refUpdateResult.name()}, trying again after 500 ms") Thread.sleep(500) return fetch(refUpdateResult) } @@ -165,17 +159,13 @@ open class Pull(val manager: GitRepositoryManager, val indicator: ProgressIndica val head = repository.getRef(Constants.HEAD) ?: throw NoHeadException(JGitText.get().commitOnRepoWithoutHEADCurrentlyNotSupported) + // handle annotated tags + val ref = repository.peel(unpeeledRef) + val objectId = ref.getPeeledObjectId() ?: ref.getObjectId() // Check for FAST_FORWARD, ALREADY_UP_TO_DATE val revWalk = RevWalk(repository) var dirCacheCheckout: DirCacheCheckout? = null try { - // handle annotated tags - val ref = repository.peel(unpeeledRef) - var objectId = ref.getPeeledObjectId() - if (objectId == null) { - objectId = ref.getObjectId() - } - val srcCommit = revWalk.lookupCommit(objectId) val headId = head.getObjectId() if (headId == null) { @@ -235,11 +225,11 @@ open class Pull(val manager: GitRepositoryManager, val indicator: ProgressIndica else { mergeMessage = commitMessageFormatter.mergeMessage(listOf(ref), head) repository.writeMergeCommitMsg(mergeMessage) - repository.writeMergeHeads(arrayListOf(ref.getObjectId())) + repository.writeMergeHeads(listOf(ref.getObjectId())) } val merger = mergeStrategy.newMerger(repository) val noProblems: Boolean - var lowLevelResults: Map>? = null + var lowLevelResults: Map>? = null var failingPaths: Map? = null var unmergedPaths: List? = null if (merger is ResolveMerger) { @@ -297,7 +287,7 @@ open class Pull(val manager: GitRepositoryManager, val indicator: ProgressIndica } } catch (e: org.eclipse.jgit.errors.CheckoutConflictException) { - throw CheckoutConflictException(if (dirCacheCheckout == null) listOf() else dirCacheCheckout.getConflicts(), e) + throw CheckoutConflictException(dirCacheCheckout?.getConflicts() ?: listOf(), e) } finally { revWalk.close() @@ -305,7 +295,7 @@ open class Pull(val manager: GitRepositoryManager, val indicator: ProgressIndica } } -class MergeResultEx(val newHead: ObjectId?, val mergeStatus: MergeStatus, val mergedCommits: Array, val result: ImmutableUpdateResult, val conflicts: Map>? = null) +class MergeResultEx(val newHead: ObjectId?, val mergeStatus: MergeStatus, val mergedCommits: Array, val result: ImmutableUpdateResult, val conflicts: Map>? = null) private fun updateHead(refLogMessage: StringBuilder, newHeadId: ObjectId, oldHeadID: ObjectId, repository: Repository) { val refUpdate = repository.updateRef(Constants.HEAD) @@ -320,3 +310,37 @@ private fun updateHead(refLogMessage: StringBuilder, newHeadId: ObjectId, oldHea } } +private fun resolveConflicts(mergeResult: MergeResultEx, repository: Repository): MutableUpdateResult { + assert(mergeResult.mergedCommits.size() == 2) + val conflicts = mergeResult.conflicts!! + val mergeProvider = JGitMergeProvider(repository, conflicts, { path, index -> + val rawText = get(path)!!.getSequences().get(index) as RawText + // RawText.EMPTY_TEXT if content is null - deleted + if (rawText == RawText.EMPTY_TEXT) null else rawText.getContent() + }) + val mergedFiles = resolveConflicts(mergeProvider, conflictsToVirtualFiles(conflicts), repository) + return mergeResult.result.toMutable().addChanged(mergedFiles) +} + +private fun resolveConflicts(mergeProvider: JGitMergeProvider, unresolvedFiles: MutableList, repository: Repository): List { + val resolvedFiles: List + val mergedFiles = SmartList() + while (true) { + resolvedFiles = resolveConflicts(unresolvedFiles, mergeProvider) + + for (file in resolvedFiles) { + mergedFiles.add(file.getPath()) + } + + if (resolvedFiles.size() == unresolvedFiles.size()) { + break + } + else { + unresolvedFiles.removeAll(mergedFiles) + } + } + + repository.commit() + + return mergedFiles +} diff --git a/plugins/settings-repository/src/git/reset.kt b/plugins/settings-repository/src/git/reset.kt index 2127ace092d2..7ed2d50e3647 100644 --- a/plugins/settings-repository/src/git/reset.kt +++ b/plugins/settings-repository/src/git/reset.kt @@ -24,8 +24,9 @@ import org.jetbrains.settingsRepository.UpdateResult class Reset(manager: GitRepositoryManager, indicator: ProgressIndicator) : Pull(manager, indicator) { fun reset(toTheirs: Boolean, localRepositoryInitializer: (() -> Unit)? = null): UpdateResult { + val message = if (toTheirs) "Overwrite local to ${manager.getUpstream()}" else "Overwrite remote ${manager.getUpstream()} to local" if (LOG.isDebugEnabled()) { - LOG.debug("Reset to ${if (toTheirs) "theirs" else "my"}") + LOG.debug(message) } val resetResult = repository.resetHard() @@ -33,7 +34,7 @@ class Reset(manager: GitRepositoryManager, indicator: ProgressIndicator) : Pull( indicator?.checkCanceled() - val commitMessage = commitMessageFormatter.message(if (toTheirs) "Overwrite local to ${manager.getUpstream()}" else "Overwrite remote ${manager.getUpstream()} to local") + val commitMessage = commitMessageFormatter.message(message) // grab added/deleted/renamed/modified files val mergeStrategy = if (toTheirs) MergeStrategy.THEIRS else MergeStrategy.OURS val firstMergeResult = pull(mergeStrategy, commitMessage) diff --git a/plugins/settings-repository/src/sync.kt b/plugins/settings-repository/src/sync.kt index 1e90e7bbe139..d677b477240e 100644 --- a/plugins/settings-repository/src/sync.kt +++ b/plugins/settings-repository/src/sync.kt @@ -59,7 +59,7 @@ class SyncManager(private val icsManager: IcsManager, private val autoSyncManage // well, we cannot commit? No problem, upcoming action must do something smart and solve the situation } catch (e: ProcessCanceledException) { - LOG.debug("Canceled") + LOG.warn("Canceled") return } catch (e: Throwable) { @@ -104,7 +104,7 @@ class SyncManager(private val icsManager: IcsManager, private val autoSyncManage return } catch (e: Throwable) { - if (e !is AuthenticationException && e !is NoRemoteRepositoryException) { + if (e !is AuthenticationException && e !is NoRemoteRepositoryException && e !is CannotResolveConflictInTestMode) { LOG.error(e) } exception = e @@ -188,4 +188,8 @@ enum class SyncType { MERGE, OVERWRITE_LOCAL, OVERWRITE_REMOTE -} \ No newline at end of file +} + +class NoRemoteRepositoryException(cause: Throwable) : RuntimeException(cause.getMessage(), cause) + +class CannotResolveConflictInTestMode() : RuntimeException() \ No newline at end of file diff --git a/plugins/settings-repository/testSrc/GitTest.kt b/plugins/settings-repository/testSrc/GitTest.kt index cd677eba4b2b..b9f307f7bfd3 100644 --- a/plugins/settings-repository/testSrc/GitTest.kt +++ b/plugins/settings-repository/testSrc/GitTest.kt @@ -17,9 +17,12 @@ package org.jetbrains.settingsRepository.test import com.intellij.mock.MockVirtualFileSystem import com.intellij.openapi.components.RoamingType +import com.intellij.openapi.components.impl.stores.StreamProvider import com.intellij.openapi.util.io.FileUtil +import com.intellij.openapi.vcs.merge.MergeSession import com.intellij.openapi.vfs.CharsetToolkit import com.intellij.openapi.vfs.VirtualFile +import com.intellij.testFramework.path import com.intellij.util.PathUtilRt import org.assertj.core.api.Assertions.assertThat import org.eclipse.jgit.api.Git @@ -28,16 +31,24 @@ import org.jetbrains.jgit.dirCache.AddFile import org.jetbrains.jgit.dirCache.deletePath import org.jetbrains.jgit.dirCache.edit import org.jetbrains.jgit.dirCache.writePath -import org.jetbrains.settingsRepository.AM +import org.jetbrains.settingsRepository.CannotResolveConflictInTestMode import org.jetbrains.settingsRepository.SyncType +import org.jetbrains.settingsRepository.conflictResolver import org.jetbrains.settingsRepository.git.GitRepositoryManager import org.jetbrains.settingsRepository.git.commit import org.jetbrains.settingsRepository.git.computeIndexDiff import org.jetbrains.settingsRepository.git.resetHard import org.junit.Test import java.io.File +import java.util.Arrays import kotlin.properties.Delegates +// kotlin bug, cannot be val (.NoSuchMethodError: org.jetbrains.settingsRepository.SettingsRepositoryPackage.getMARKER_ACCEPT_MY()[B) +object AM { + val MARKER_ACCEPT_MY: ByteArray = "__accept my__".toByteArray() + val MARKER_ACCEPT_THEIRS: ByteArray = "__accept theirs__".toByteArray() +} + class GitTest : TestCase() { private val repositoryManager: GitRepositoryManager get() = icsManager.repositoryManager as GitRepositoryManager @@ -49,6 +60,28 @@ class GitTest : TestCase() { tempDirManager.createRepository("upstream") } + init { + conflictResolver = { files, mergeProvider -> + val mergeSession = mergeProvider.createMergeSession(files) + for (file in files) { + val mergeData = mergeProvider.loadRevisions(file) + if (Arrays.equals(mergeData.CURRENT, AM.MARKER_ACCEPT_MY) || Arrays.equals(mergeData.LAST, AM.MARKER_ACCEPT_THEIRS)) { + mergeSession.conflictResolvedForFile(file, MergeSession.Resolution.AcceptedYours) + } + else if (Arrays.equals(mergeData.CURRENT, AM.MARKER_ACCEPT_THEIRS) || Arrays.equals(mergeData.LAST, AM.MARKER_ACCEPT_MY)) { + mergeSession.conflictResolvedForFile(file, MergeSession.Resolution.AcceptedTheirs) + } + else if (Arrays.equals(mergeData.LAST, AM.MARKER_ACCEPT_MY)) { + file.setBinaryContent(mergeData.LAST!!) + mergeProvider.conflictResolvedForFile(file) + } + else { + throw CannotResolveConflictInTestMode() + } + } + } + } + private fun addAndCommit(path: String): FileInfo { val data = FileUtil.loadFileBytes(File(testDataPath, PathUtilRt.getFileName(path))) provider.save(path, data) @@ -284,15 +317,24 @@ class GitTest : TestCase() { Test fun `commit if unmerged`() { createLocalRepository(null) + provider.saveContent("remote.xml", "") + + try { + sync(SyncType.MERGE) + } + catch (e: CannotResolveConflictInTestMode) { + } + + // repository in unmerged state + conflictResolver = {files, mergeProvider -> + assertThat(files).hasSize(1) + assertThat(files.first().path).isEqualTo("remote.xml") + val mergeSession = mergeProvider.createMergeSession(files) + mergeSession.conflictResolvedForFile(files.first(), MergeSession.Resolution.AcceptedTheirs) + } sync(SyncType.MERGE) - provider.delete("remote.xml", RoamingType.PER_USER) - repositoryManager.commit() - - sync(SyncType.MERGE) - restoreRemoteAfterPush() - - compareFiles(fs()) + compareFiles(fs("remote.xml")) } // remote is uninitialized (empty - initial commit is not done) @@ -364,4 +406,9 @@ class GitTest : TestCase() { private fun sync(syncType: SyncType) { icsManager.sync(syncType, fixtureManager.projectFixture.getProject()) } +} + +fun StreamProvider.saveContent(fileSpec: String, content: String) { + val data = content.toByteArray() + saveContent(fileSpec, data, data.size(), RoamingType.PER_USER) } \ No newline at end of file From 07e19a683bd570d38a58f0083d90064d9dc2c9aa Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 25 Aug 2015 13:51:40 +0200 Subject: [PATCH 018/246] fix NPE if MultipleFileMergeDialog was created without project (as ICS does) --- .../src/com/intellij/diff/merge/TextMergeTool.java | 7 ++++++- .../src/com/intellij/openapi/command/undo/UndoManager.java | 5 +++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/platform/diff-impl/src/com/intellij/diff/merge/TextMergeTool.java b/platform/diff-impl/src/com/intellij/diff/merge/TextMergeTool.java index a0c1ca24d1b3..26e58ddabf0e 100644 --- a/platform/diff-impl/src/com/intellij/diff/merge/TextMergeTool.java +++ b/platform/diff-impl/src/com/intellij/diff/merge/TextMergeTool.java @@ -701,13 +701,18 @@ public class TextMergeTool implements MergeTool { } private void registerUndoRedo(final boolean undo) { + Project project = getProject(); + if (project == null) { + return; + } + List affectedChanges = getAffectedChanges(); final List states = new ArrayList(affectedChanges.size()); for (TextMergeChange change : affectedChanges) { states.add(change.storeState()); } - UndoManager.getInstance(getProject()).undoableActionPerformed(new BasicUndoableAction(myDocument) { + UndoManager.getInstance(project).undoableActionPerformed(new BasicUndoableAction(myDocument) { @Override public void undo() throws UnexpectedUndoException { if (undo) restoreStates(states); diff --git a/platform/platform-api/src/com/intellij/openapi/command/undo/UndoManager.java b/platform/platform-api/src/com/intellij/openapi/command/undo/UndoManager.java index bcbe7afb9d6e..b6f60a55f968 100644 --- a/platform/platform-api/src/com/intellij/openapi/command/undo/UndoManager.java +++ b/platform/platform-api/src/com/intellij/openapi/command/undo/UndoManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,12 +21,13 @@ import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public abstract class UndoManager { public static final Key ORIGINAL_DOCUMENT = new Key("ORIGINAL_DOCUMENT"); - public static UndoManager getInstance(Project project) { + public static UndoManager getInstance(@NotNull Project project) { return project.getComponent(UndoManager.class); } From 5b6c41cdef413bd5c5df388895ec642c05ea4435 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Tue, 25 Aug 2015 15:02:52 +0300 Subject: [PATCH 019/246] merge: fix NPE if UndoManager not found --- .../intellij/diff/merge/TextMergeTool.java | 42 ++++++++----------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/platform/diff-impl/src/com/intellij/diff/merge/TextMergeTool.java b/platform/diff-impl/src/com/intellij/diff/merge/TextMergeTool.java index 26e58ddabf0e..a82a03b741c4 100644 --- a/platform/diff-impl/src/com/intellij/diff/merge/TextMergeTool.java +++ b/platform/diff-impl/src/com/intellij/diff/merge/TextMergeTool.java @@ -200,6 +200,7 @@ public class TextMergeTool implements MergeTool { public class MyThreesideViewer extends ThreesideTextDiffViewerEx { @NotNull private final ModifierProvider myModifierProvider; + @Nullable private final UndoManager myUndoManager; // all changes - both applied and unapplied ones @NotNull private final List myAllMergeChanges = new ArrayList(); @@ -217,14 +218,17 @@ public class TextMergeTool implements MergeTool { super(context, request); myModifierProvider = new ModifierProvider(); + myUndoManager = getProject() != null ? UndoManager.getInstance(getProject()) : UndoManager.getGlobalInstance(); DiffUtil.registerAction(new ApplySelectedChangesAction(Side.LEFT, true), myPanel); DiffUtil.registerAction(new ApplySelectedChangesAction(Side.RIGHT, true), myPanel); DiffUtil.registerAction(new IgnoreSelectedChangesAction(Side.LEFT, true), myPanel); DiffUtil.registerAction(new IgnoreSelectedChangesAction(Side.RIGHT, true), myPanel); - new UndoRedoAction(true).register(); - new UndoRedoAction(false).register(); + if (myUndoManager != null) { + new UndoRedoAction(true).register(); + new UndoRedoAction(false).register(); + } } @Override @@ -333,10 +337,9 @@ public class TextMergeTool implements MergeTool { @Override public void run() { outputDocument.setText(baseDocument.getCharsSequence()); - UndoManager undoManager = getProject() != null ? UndoManager.getInstance(getProject()) : UndoManager.getGlobalInstance(); - if (undoManager != null) { + if (myUndoManager != null) { DocumentReference ref = DocumentReferenceManager.getInstance().create(outputDocument); - undoManager.nonundoableActionPerformed(ref, false); + myUndoManager.nonundoableActionPerformed(ref, false); } } }); @@ -513,10 +516,10 @@ public class TextMergeTool implements MergeTool { } } - if (!corruptedStates.isEmpty()) { + if (!corruptedStates.isEmpty() && myUndoManager != null) { // document undo is registered inside onDocumentChange, so our undo() will be called after its undo(). // thus thus we can avoid checks for isUndoInProgress() (to avoid modification of the same TextMergeChange by this listener) - UndoManager.getInstance(getProject()).undoableActionPerformed(new BasicUndoableAction(getEditor(ThreeSide.BASE).getDocument()) { + myUndoManager.undoableActionPerformed(new BasicUndoableAction(getEditor(ThreeSide.BASE).getDocument()) { @Override public void undo() throws UnexpectedUndoException { enterBulkChangeUpdateBlock(); @@ -701,10 +704,7 @@ public class TextMergeTool implements MergeTool { } private void registerUndoRedo(final boolean undo) { - Project project = getProject(); - if (project == null) { - return; - } + if (myUndoManager == null) return; List affectedChanges = getAffectedChanges(); final List states = new ArrayList(affectedChanges.size()); @@ -712,7 +712,7 @@ public class TextMergeTool implements MergeTool { states.add(change.storeState()); } - UndoManager.getInstance(project).undoableActionPerformed(new BasicUndoableAction(myDocument) { + myUndoManager.undoableActionPerformed(new BasicUndoableAction(myDocument) { @Override public void undo() throws UnexpectedUndoException { if (undo) restoreStates(states); @@ -1185,22 +1185,20 @@ public class TextMergeTool implements MergeTool { @Override public void update(AnActionEvent e) { - UndoManager undoManager = getUndoManager(); + assert myUndoManager != null; TextEditor textEditor = getTextEditor(); - - e.getPresentation().setEnabled(myUndo ? undoManager.isUndoAvailable(textEditor) : undoManager.isRedoAvailable(textEditor)); + e.getPresentation().setEnabled(myUndo ? myUndoManager.isUndoAvailable(textEditor) : myUndoManager.isRedoAvailable(textEditor)); } @Override public void actionPerformed(AnActionEvent e) { - UndoManager undoManager = getUndoManager(); + assert myUndoManager != null; TextEditor textEditor = getTextEditor(); - if (myUndo) { - undoManager.undo(textEditor); + myUndoManager.undo(textEditor); } else { - undoManager.redo(textEditor); + myUndoManager.redo(textEditor); } } @@ -1209,12 +1207,6 @@ public class TextMergeTool implements MergeTool { EditorEx editor = getEditor(ThreeSide.BASE); return TextEditorProvider.getInstance().getTextEditor(editor); } - - @NotNull - private UndoManager getUndoManager() { - Project project = getProject(); - return project != null ? UndoManager.getInstance(project) : UndoManager.getGlobalInstance(); - } } private class MyDividerPaintable implements DiffDividerDrawUtil.DividerPaintable { From 188f1411e121e8ee8975b760fa64ae9648c86f12 Mon Sep 17 00:00:00 2001 From: "Vladimir.Orlov" Date: Tue, 25 Aug 2015 15:37:18 +0300 Subject: [PATCH 020/246] IDEA-144319 When starting Idea from terminal error "Cannot find VM options file" appears but Idea starts successfully --- bin/scripts/unix/idea.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/bin/scripts/unix/idea.sh b/bin/scripts/unix/idea.sh index 03d086d3b5f0..f20ed48714d5 100755 --- a/bin/scripts/unix/idea.sh +++ b/bin/scripts/unix/idea.sh @@ -136,7 +136,10 @@ if [ -n "$@@product_uc@@_PROPERTIES" ]; then IDE_PROPERTIES_PROPERTY="-Didea.properties.file=$@@product_uc@@_PROPERTIES" fi -vm_options_file="$OS_SPECIFIC_BIN_DIR/@@vm_options@@$BITS.vmoptions" +vm_options_file="$IDE_BIN_HOME/@@vm_options@@$BITS.vmoptions" +if [ ! -r "$vm_options_file" ]; then + vm_options_file="$OS_SPECIFIC_BIN_DIR/@@vm_options@@$BITS.vmoptions" +fi user_vm_options_file="$HOME/.@@system_selector@@/@@vm_options@@$BITS.vmoptions" if [ -r "$user_vm_options_file" ]; then vm_options_file="$user_vm_options_file" @@ -184,6 +187,5 @@ LD_LIBRARY_PATH="$IDE_BIN_HOME:$LD_LIBRARY_PATH" "$JDK/jre/bin/java" \ com.intellij.idea.Main \ "$@" EC=$? -exit $EC -# test $EC -ne 88 && exit $EC -# exec "$0" "$@" +test $EC -ne 88 && exit $EC +exec "$0" "$@" From ad74cfcfd9e823f5c8c28bc75a6ab965ac60523c Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Tue, 25 Aug 2015 15:47:22 +0300 Subject: [PATCH 021/246] EA-72099 - IOOBE: LineSet.findLineIndex --- .../src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java index 82f9dd86e810..142feafa4a34 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java @@ -658,7 +658,6 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedInternalDo myApplianceManager.reset(); myStorage.removeAll(); myDeferredFoldRegions.clear(); - myEditor.getScrollingModel().scrollToCaret(ScrollType.CENTER); myApplianceManager.recalculateIfNecessary(); } From 2fdabde0ec4b82326ea803389714657086e6c3d1 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Tue, 25 Aug 2015 15:48:55 +0300 Subject: [PATCH 022/246] Collection -> List --- .../testFramework/fixtures/CodeInsightTestFixture.java | 4 ++-- .../fixtures/impl/CodeInsightTestFixtureImpl.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java index 6e16f4efbd2c..ad282d14ab26 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java @@ -472,9 +472,9 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { Document getDocument(@NotNull PsiFile file); @NotNull - Collection findAllGutters(@NotNull @TestDataFile String filePath); + List findAllGutters(@NotNull @TestDataFile String filePath); - Collection findAllGutters(); + List findAllGutters(); void type(final char c); diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java index 3702fdb42cf1..0f7f174aa90e 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java @@ -1136,14 +1136,14 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig @Override @NotNull - public Collection findAllGutters(@NotNull final String filePath) { + public List findAllGutters(@NotNull final String filePath) { configureByFilesInner(filePath); return findAllGutters(); } @Override @NotNull - public Collection findAllGutters() { + public List findAllGutters() { final Project project = getProject(); final SortedMap> result = new TreeMap>(); From 05a593783928847d8f7286e6f1c965af04eb0a75 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Tue, 25 Aug 2015 15:52:36 +0300 Subject: [PATCH 023/246] EA-72098 - NPE: EnumeratorStringDescriptor.getHashCode --- .../src/com/intellij/execution/TestStateStorage.java | 2 +- .../testframework/sm/runner/ui/SMTestRunnerResultsForm.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/TestStateStorage.java b/platform/lang-impl/src/com/intellij/execution/TestStateStorage.java index 9ad8808130c3..ac42d6c0f5bd 100644 --- a/platform/lang-impl/src/com/intellij/execution/TestStateStorage.java +++ b/platform/lang-impl/src/com/intellij/execution/TestStateStorage.java @@ -94,7 +94,7 @@ public class TestStateStorage extends AbstractProjectComponent{ } } - public void writeState(String testUrl, Record record) { + public void writeState(@NotNull String testUrl, Record record) { if (myMap == null) return; try { myMap.put(testUrl, record); diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java index 32da6e01e10a..f79abadbd551 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java @@ -828,8 +828,8 @@ public class SMTestRunnerResultsForm extends TestResultsPanel TestStateStorage storage = TestStateStorage.getInstance(getProject()); List tests = myRoot.getAllTests(); for (SMTestProxy proxy : tests) { - if (proxy.isLeaf()) { - String url = proxy.getLocationUrl(); + String url = proxy.getLocationUrl(); + if (proxy.isLeaf() && url != null) { storage.writeState(url, new TestStateStorage.Record(proxy.getMagnitude(), new Date())); } } From 979f80095fc0e2c6dfbaf223bac113dc6ce394e1 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Tue, 25 Aug 2015 15:14:28 +0200 Subject: [PATCH 024/246] open goto file popup if nothing found in Recent Files --- .../com/intellij/ide/actions/Switcher.java | 52 ++++++++++++++++--- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java b/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java index 11a560a7ef6f..28cd53649030 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java @@ -16,9 +16,11 @@ package com.intellij.ide.actions; import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.ide.DataManager; import com.intellij.ide.IdeEventQueue; import com.intellij.ide.ui.UISettings; import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.impl.PresentationFactory; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.markup.EffectType; import com.intellij.openapi.editor.markup.TextAttributes; @@ -89,7 +91,7 @@ public class Switcher extends AnAction implements DumbAware { public void run() { synchronized (Switcher.class) { if (SWITCHER != null) { - SWITCHER.navigate(false); + SWITCHER.navigate(null); } } } @@ -226,7 +228,7 @@ public class Switcher extends AnAction implements DumbAware { jList.setSelectedIndex(jList.getAnchorSelectionIndex()); } if (jList.getSelectedIndex() != -1) { - navigate(false); + navigate(e); } } return true; @@ -646,7 +648,7 @@ public class Switcher extends AnAction implements DumbAware { boolean ctrl = e.getKeyCode() == CTRL_KEY; boolean enter = e.getKeyCode() == VK_ENTER; if (ctrl && isAutoHide() || enter) { - navigate(e.isShiftDown() && enter); + navigate(e); } else if (e.getKeyCode() == VK_LEFT) { goLeft(); @@ -850,10 +852,15 @@ public class Switcher extends AnAction implements DumbAware { return files.hasFocus() ? files : toolWindows.hasFocus() ? toolWindows : preferable; } - void navigate(final boolean openInNewWindow) { + void navigate(final InputEvent e) { + final boolean openInNewWindow = e != null && e.isShiftDown() && e instanceof KeyEvent && ((KeyEvent)e).getKeyCode() == VK_ENTER; final Object[] values = getSelectedList().getSelectedValues(); + final String searchQuery = mySpeedSearch != null ? mySpeedSearch.getEnteredPrefix() : null; myPopup.cancel(null); - if (values.length > 0 && values[0] instanceof ToolWindow) { + if (values.length == 0) { + tryToOpenFileSearch(e, searchQuery); + } + else if (values[0] instanceof ToolWindow) { final ToolWindow toolWindow = (ToolWindow)values[0]; IdeFocusManager.getInstance(project).doWhenFocusSettlesDown(new Runnable() { @Override @@ -892,6 +899,39 @@ public class Switcher extends AnAction implements DumbAware { } } + private void tryToOpenFileSearch(final InputEvent e, final String fileName) { + AnAction gotoFile = ActionManager.getInstance().getAction("GotoFile"); + if (gotoFile != null && !StringUtil.isEmpty(fileName)) { + myPopup.cancel(); + final AnAction action = gotoFile; + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + + DataManager.getInstance().getDataContextFromFocus().doWhenDone(new Consumer() { + @Override + public void consume(@NotNull final DataContext context) { + final DataContext dataContext = new DataContext() { + @Nullable + @Override + public Object getData(@NonNls String dataId) { + if (PlatformDataKeys.PREDEFINED_TEXT.is(dataId)) { + return fileName; + } + return context.getData(dataId); + } + }; + final AnActionEvent event = + new AnActionEvent(e, dataContext, ActionPlaces.EDITOR_POPUP, new PresentationFactory().getPresentation(action), + ActionManager.getInstance(), 0); + action.actionPerformed(event); + } + }); + } + }); + } + } + @Nullable private static EditorWindow findAppropriateWindow(@NotNull FileInfo info) { if (info.second == null) return null; @@ -966,7 +1006,7 @@ public class Switcher extends AnAction implements DumbAware { protected void processKeyEvent(@NotNull final KeyEvent e) { final int keyCode = e.getKeyCode(); if (keyCode == VK_ENTER) { - SWITCHER.navigate(e.isShiftDown()); + SWITCHER.navigate(e); e.consume(); return; } From a1eb18141045015da597edcb9ca3b4a46dc7b577 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yann=20C=C3=A9bron?= Date: Tue, 25 Aug 2015 15:14:36 +0200 Subject: [PATCH 025/246] PlatformActions.xml: remove "configurable" attribute from s --- platform/platform-resources/src/idea/PlatformActions.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index 975e05f4ca51..a37ba12507c0 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -363,7 +363,7 @@ - + @@ -474,7 +474,7 @@ - + @@ -499,7 +499,7 @@ - + From 2a6f4dfeb8541fa0b790d35512affdff8e5a5067 Mon Sep 17 00:00:00 2001 From: Alexander Zolotov Date: Fri, 21 Aug 2015 20:00:46 +0300 Subject: [PATCH 026/246] String -> CharSequence --- .../intellij/openapi/vcs/IssueNavigationConfiguration.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/IssueNavigationConfiguration.java b/platform/vcs-api/src/com/intellij/openapi/vcs/IssueNavigationConfiguration.java index e1c74749d2c3..483f4e7dc1bc 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/IssueNavigationConfiguration.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/IssueNavigationConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -92,7 +92,7 @@ public class IssueNavigationConfiguration implements PersistentStateComponent findIssueLinks(String text) { + public List findIssueLinks(CharSequence text) { final List result = new ArrayList(); for(IssueNavigationLink link: myLinks) { Pattern issuePattern = link.getIssuePattern(); From 37244426e0b95819f8aabb12837f6242976b8ca4 Mon Sep 17 00:00:00 2001 From: Alexander Zolotov Date: Fri, 21 Aug 2015 20:09:27 +0300 Subject: [PATCH 027/246] Move url pattern to URLUtil and reuse it for issue navigation --- .../intellij/execution/filters/UrlFilter.java | 8 +-- .../psi/execution/filters/UrlFilterTest.java | 65 ------------------- .../ArbitraryPlaceUrlReferenceProvider.java | 9 +-- .../intellij/ide/actions/CopyUrlAction.java | 4 +- .../src/com/intellij/util/io/URLUtil.java | 7 +- .../com/intellij/util/io/UrlUtilTest.java | 44 +++++++++++++ .../vcs/IssueNavigationConfiguration.java | 7 +- 7 files changed, 56 insertions(+), 88 deletions(-) delete mode 100644 platform/lang-api/testSources/com/intellij/psi/execution/filters/UrlFilterTest.java diff --git a/platform/lang-api/src/com/intellij/execution/filters/UrlFilter.java b/platform/lang-api/src/com/intellij/execution/filters/UrlFilter.java index f8a524b435b6..df1ab08d4351 100644 --- a/platform/lang-api/src/com/intellij/execution/filters/UrlFilter.java +++ b/platform/lang-api/src/com/intellij/execution/filters/UrlFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -17,25 +17,23 @@ package com.intellij.execution.filters; import com.intellij.openapi.project.Project; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.io.URLUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * @author yole */ public class UrlFilter implements Filter { - public static final Pattern URL_PATTERN = Pattern.compile("\\b(mailto:|(news|(ht|f)tp(s?))://|((? items = null; while (m.find()) { diff --git a/platform/lang-api/testSources/com/intellij/psi/execution/filters/UrlFilterTest.java b/platform/lang-api/testSources/com/intellij/psi/execution/filters/UrlFilterTest.java deleted file mode 100644 index c778c7441266..000000000000 --- a/platform/lang-api/testSources/com/intellij/psi/execution/filters/UrlFilterTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2000-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.psi.execution.filters; - -import com.intellij.execution.filters.UrlFilter; -import junit.framework.TestCase; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.regex.Matcher; - -public class UrlFilterTest extends TestCase { - - private static void doUrlTest(@NotNull final String line, @Nullable final String expectedUrl) { - final Matcher matcher = UrlFilter.URL_PATTERN.matcher(line); - if (expectedUrl == null) { - if (matcher.find()) { - fail("No URL expected in [" + line + "], detected: " + matcher.group()); - } - return; - } - - assertTrue("Expected URL (" + expectedUrl + ") is not detected in [" + line + "]", matcher.find()); - assertEquals("Text: [" + line + "]", expectedUrl, matcher.group()); - } - - public void testUrlParsing() throws Exception { - doUrlTest("not detecting jetbrains.com", null); - doUrlTest("mailto:admin@jetbrains.com;", "mailto:admin@jetbrains.com"); - doUrlTest("news://jetbrains.com is good", "news://jetbrains.com"); - doUrlTest("see http://www.jetbrains.com", "http://www.jetbrains.com"); - doUrlTest("https://www.jetbrains.com;", "https://www.jetbrains.com"); - doUrlTest("(ftp://jetbrains.com)", "ftp://jetbrains.com"); - doUrlTest("[ftps://jetbrains.com]", "ftps://jetbrains.com"); - doUrlTest("Is it good site:http://jetbrains.com?", "http://jetbrains.com"); - doUrlTest("And http://jetbrains.com?a=@#/%?=~_|!:,.;&b=20,", "http://jetbrains.com?a=@#/%?=~_|!:,.;&b=20"); - doUrlTest("site:www.jetbrains.com.", "www.jetbrains.com"); - doUrlTest("site (www.jetbrains.com)", "www.jetbrains.com"); - doUrlTest("site [www.jetbrains.com]", "www.jetbrains.com"); - doUrlTest("site ", "www.jetbrains.com"); - doUrlTest("site {www.jetbrains.com}", "www.jetbrains.com"); - doUrlTest("site 'www.jetbrains.com'", "www.jetbrains.com"); - doUrlTest("site \"www.jetbrains.com\"", "www.jetbrains.com"); - doUrlTest("site=www.jetbrains.com!", "www.jetbrains.com"); - doUrlTest("site *www.jetbrains.com*", "www.jetbrains.com"); - doUrlTest("site `www.jetbrains.com`", "www.jetbrains.com"); - doUrlTest("not a site _www.jetbrains.com", null); - doUrlTest("not a site 1www.jetbrains.com", null); - doUrlTest("not a site wwww.jetbrains.com", null); - doUrlTest("not a site xxx.www.jetbrains.com", null); - } -} diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/ArbitraryPlaceUrlReferenceProvider.java b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/ArbitraryPlaceUrlReferenceProvider.java index 6450b9f9ac53..e07020452adb 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/ArbitraryPlaceUrlReferenceProvider.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/ArbitraryPlaceUrlReferenceProvider.java @@ -15,7 +15,6 @@ */ package com.intellij.psi.impl.source.resolve.reference; -import com.intellij.execution.filters.UrlFilter; import com.intellij.openapi.paths.GlobalPathReferenceProvider; import com.intellij.openapi.paths.PathReferenceManager; import com.intellij.openapi.util.TextRange; @@ -28,18 +27,14 @@ import com.intellij.psi.util.CachedValueProvider; import com.intellij.psi.util.CachedValuesManager; import com.intellij.util.ProcessingContext; import com.intellij.util.SmartList; +import com.intellij.util.io.URLUtil; import org.jetbrains.annotations.NotNull; import java.util.List; import java.util.concurrent.atomic.AtomicReference; import java.util.regex.Matcher; -/** -* Created by Maxim.Mossienko on 12/19/2014. -*/ public class ArbitraryPlaceUrlReferenceProvider extends PsiReferenceProvider { - public static final ArbitraryPlaceUrlReferenceProvider INSTANCE = new ArbitraryPlaceUrlReferenceProvider(); - private static final UserDataCache, PsiElement, Object> ourRefsCache = new UserDataCache, PsiElement, Object>("psielement.url.refs") { private final AtomicReference myReferenceProvider = new AtomicReference(); @@ -48,7 +43,7 @@ public class ArbitraryPlaceUrlReferenceProvider extends PsiReferenceProvider { return CachedValuesManager .getManager(element.getProject()).createCachedValue(new CachedValueProvider() { public Result compute() { - Matcher matcher = UrlFilter.URL_PATTERN.matcher(element.getText()); + Matcher matcher = URLUtil.URL_PATTERN.matcher(element.getText()); List refs = null; GlobalPathReferenceProvider provider = myReferenceProvider.get(); diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CopyUrlAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CopyUrlAction.java index f98fe24f9d09..f069e85df09c 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/CopyUrlAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/CopyUrlAction.java @@ -15,13 +15,13 @@ */ package com.intellij.ide.actions; -import com.intellij.execution.filters.UrlFilter; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.ide.CopyPasteManager; import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.util.io.URLUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -61,7 +61,7 @@ public class CopyUrlAction extends DumbAwareAction { CharSequence chars = editor.getDocument().getCharsSequence(); while (offset > 0 && seemsUrlPart(chars.charAt(offset - 1))) offset--; - Matcher matcher = UrlFilter.URL_PATTERN.matcher(chars.subSequence(offset, chars.length())); + Matcher matcher = URLUtil.URL_PATTERN.matcher(chars.subSequence(offset, chars.length())); if (matcher.lookingAt()) { return matcher.group(); } diff --git a/platform/util/src/com/intellij/util/io/URLUtil.java b/platform/util/src/com/intellij/util/io/URLUtil.java index 11eba77fbb6d..b0ceb83602b4 100644 --- a/platform/util/src/com/intellij/util/io/URLUtil.java +++ b/platform/util/src/com/intellij/util/io/URLUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -35,8 +35,6 @@ import java.util.regex.Pattern; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; -import static com.intellij.openapi.util.text.StringUtil.stripQuotesAroundValue; - public class URLUtil { public static final String SCHEME_SEPARATOR = "://"; public static final String FILE_PROTOCOL = "file"; @@ -45,6 +43,7 @@ public class URLUtil { public static final String JAR_SEPARATOR = "!/"; public static final Pattern DATA_URI_PATTERN = Pattern.compile("data:([^,;]+/[^,;]+)(;charset(?:=|:)[^,;]+)?(;base64)?,(.+)"); + public static final Pattern URL_PATTERN = Pattern.compile("\\b(mailto:|(news|(ht|f)tp(s?))://|((?", "www.jetbrains.com"); + doUrlTest("site {www.jetbrains.com}", "www.jetbrains.com"); + doUrlTest("site 'www.jetbrains.com'", "www.jetbrains.com"); + doUrlTest("site \"www.jetbrains.com\"", "www.jetbrains.com"); + doUrlTest("site=www.jetbrains.com!", "www.jetbrains.com"); + doUrlTest("site *www.jetbrains.com*", "www.jetbrains.com"); + doUrlTest("site `www.jetbrains.com`", "www.jetbrains.com"); + doUrlTest("not a site _www.jetbrains.com", null); + doUrlTest("not a site 1www.jetbrains.com", null); + doUrlTest("not a site wwww.jetbrains.com", null); + doUrlTest("not a site xxx.www.jetbrains.com", null); + } } \ No newline at end of file diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/IssueNavigationConfiguration.java b/platform/vcs-api/src/com/intellij/openapi/vcs/IssueNavigationConfiguration.java index 483f4e7dc1bc..8161750c99f7 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/IssueNavigationConfiguration.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/IssueNavigationConfiguration.java @@ -20,8 +20,8 @@ import com.intellij.lifecycle.PeriodicalTasksCloser; import com.intellij.openapi.components.*; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; +import com.intellij.util.io.URLUtil; import com.intellij.util.xmlb.XmlSerializerUtil; -import org.jetbrains.annotations.NonNls; import java.util.ArrayList; import java.util.Collections; @@ -41,9 +41,6 @@ import java.util.regex.Pattern; } ) public class IssueNavigationConfiguration implements PersistentStateComponent { - @NonNls private static final Pattern ourHtmlPattern = - Pattern.compile("(http:|https:)\\/\\/([^\\s()](?!&(gt|lt|nbsp)+;))+[^\\p{Pe}\\p{Pc}\\p{Pd}\\p{Ps}\\p{Po}\\s]/?"); - public static IssueNavigationConfiguration getInstance(Project project) { return PeriodicalTasksCloser.getInstance().safeGetService(project, IssueNavigationConfiguration.class); } @@ -102,7 +99,7 @@ public class IssueNavigationConfiguration implements PersistentStateComponent Date: Fri, 21 Aug 2015 21:27:40 +0300 Subject: [PATCH 028/246] Introduce extendable comment reference provider type --- ...utor.java => CommentsReferenceContributor.java} | 14 ++++++++++++-- .../src/META-INF/LangExtensions.xml | 4 +++- .../impl/providers/JavaReferenceContributor.java | 5 +++-- .../intellij/xml/util/XmlReferenceContributor.java | 2 +- 4 files changed, 19 insertions(+), 6 deletions(-) rename platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/{ArbitraryPlaceUrlReferenceContributor.java => CommentsReferenceContributor.java} (59%) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/ArbitraryPlaceUrlReferenceContributor.java b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/CommentsReferenceContributor.java similarity index 59% rename from platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/ArbitraryPlaceUrlReferenceContributor.java rename to platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/CommentsReferenceContributor.java index cf036f80d0da..06c3a22d3e7d 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/ArbitraryPlaceUrlReferenceContributor.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/CommentsReferenceContributor.java @@ -19,11 +19,21 @@ import com.intellij.patterns.PlatformPatterns; import com.intellij.psi.PsiComment; import com.intellij.psi.PsiReferenceContributor; import com.intellij.psi.PsiReferenceRegistrar; +import com.intellij.psi.ReferenceProviderType; import org.jetbrains.annotations.NotNull; -public class ArbitraryPlaceUrlReferenceContributor extends PsiReferenceContributor { +public class CommentsReferenceContributor extends PsiReferenceContributor { + /** + * Use this provider type if your element is not PsiComment but you want to fill it + * with the same references as PsiCommit (e.g. it's used for PsiDocToken). + * + * Also you can register your own reference provider as 'comment reference provider' and it will be + * applied to all PsiComment and other elements that uses this provider type for retrieving references. + */ + public static final ReferenceProviderType COMMENTS_REFERENCE_PROVIDER_TYPE = new ReferenceProviderType("commentsReferenceProvider"); + @Override public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) { - registrar.registerReferenceProvider(PlatformPatterns.psiElement(PsiComment.class), ArbitraryPlaceUrlReferenceProvider.INSTANCE); + registrar.registerReferenceProvider(PlatformPatterns.psiElement(PsiComment.class), COMMENTS_REFERENCE_PROVIDER_TYPE.getProvider()); } } diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index a96bbb730bdb..d882f9231da4 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -767,7 +767,9 @@ - + + Date: Mon, 24 Aug 2015 15:26:11 +0300 Subject: [PATCH 029/246] Allow to specify custom url for WebReference --- .../paths/GlobalPathReferenceProvider.java | 6 +++--- .../intellij/openapi/paths/WebReference.java | 17 +++++++++++++++-- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/paths/GlobalPathReferenceProvider.java b/platform/lang-impl/src/com/intellij/openapi/paths/GlobalPathReferenceProvider.java index 63841da51015..ba38d3ec31a7 100644 --- a/platform/lang-impl/src/com/intellij/openapi/paths/GlobalPathReferenceProvider.java +++ b/platform/lang-impl/src/com/intellij/openapi/paths/GlobalPathReferenceProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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,9 +19,9 @@ package com.intellij.openapi.paths; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.util.io.URLUtil; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.NonNls; import java.util.List; @@ -61,7 +61,7 @@ public class GlobalPathReferenceProvider implements PathReferenceProvider { String url, TextRange rangeInElement, @NotNull List references) { if (isWebReferenceUrl(url)) { - references.add(new WebReference(psiElement, rangeInElement)); + references.add(new WebReference(psiElement, rangeInElement, url)); return true; } else if (url.contains("://") || url.startsWith("//") || startsWithAllowedPrefix(url)) { diff --git a/platform/lang-impl/src/com/intellij/openapi/paths/WebReference.java b/platform/lang-impl/src/com/intellij/openapi/paths/WebReference.java index 77b076938efc..49033af5564a 100644 --- a/platform/lang-impl/src/com/intellij/openapi/paths/WebReference.java +++ b/platform/lang-impl/src/com/intellij/openapi/paths/WebReference.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,17 +21,30 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReferenceBase; import com.intellij.psi.impl.FakePsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author Eugene.Kudelevsky */ public class WebReference extends PsiReferenceBase { + @Nullable private final String myUrl; + public WebReference(@NotNull PsiElement element) { + this(element, (String)null); + } + + public WebReference(@NotNull PsiElement element, @Nullable String url) { super(element, true); + myUrl = url; } public WebReference(@NotNull PsiElement element, @NotNull TextRange textRange) { + this(element, textRange, null); + } + + public WebReference(@NotNull PsiElement element, TextRange textRange, @Nullable String url) { super(element, textRange, true); + myUrl = url; } @Override @@ -40,7 +53,7 @@ public class WebReference extends PsiReferenceBase { } protected String getUrl() { - return getValue(); + return myUrl != null ? myUrl : getValue(); } @NotNull From b0b31e7d50f1aa46b4e020fec8a8400bec289ff2 Mon Sep 17 00:00:00 2001 From: Alexander Zolotov Date: Mon, 24 Aug 2015 16:51:16 +0300 Subject: [PATCH 030/246] IDEA-62743 Render issue links in Java comments --- .../javaDoc/IssueLinksInJavaDoc.java | 6 +++ .../daemon/JavadocHighlightingTest.java | 41 ++++++++++++++----- .../intellij/openapi/paths/WebReference.java | 2 +- .../ArbitraryPlaceUrlReferenceProvider.java | 38 ++++++++--------- .../vcs/IssueNavigationConfiguration.java | 4 +- 5 files changed, 56 insertions(+), 35 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/IssueLinksInJavaDoc.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/IssueLinksInJavaDoc.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/IssueLinksInJavaDoc.java new file mode 100644 index 000000000000..bf4cbf7f23d4 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/IssueLinksInJavaDoc.java @@ -0,0 +1,6 @@ +/** + * Fixes ABC-1123 and ABC-2. See details at BBB-22 + */ +class IssueLinksInJavaDoc { + // Fixes ABC-22 and ABC-11. See details at BBB-33 +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/JavadocHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/JavadocHighlightingTest.java index 8249afe26f8b..a68a02d51633 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/JavadocHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/JavadocHighlightingTest.java @@ -20,6 +20,8 @@ import com.intellij.codeInspection.javaDoc.JavaDocLocalInspection; import com.intellij.codeInspection.javaDoc.JavaDocReferenceInspection; import com.intellij.openapi.paths.WebReference; import com.intellij.openapi.roots.LanguageLevelProjectExtension; +import com.intellij.openapi.vcs.IssueNavigationConfiguration; +import com.intellij.openapi.vcs.IssueNavigationLink; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiRecursiveElementWalkingVisitor; @@ -96,9 +98,36 @@ public class JavadocHighlightingTest extends LightDaemonAnalyzerTestCase { public void testMissingReturnDescription() { doTest(); } public void testDoubleParenthesesInCode() { doTest(); } + public void testIssueLinksInJavaDoc() { + IssueNavigationConfiguration navigationConfiguration = IssueNavigationConfiguration.getInstance(getProject()); + List oldLinks = navigationConfiguration.getLinks(); + try { + IssueNavigationLink link = new IssueNavigationLink("ABC-\\d+", "http://example.com/$0"); + navigationConfiguration.setLinks(ContainerUtil.newArrayList(link)); + configureByFile(BASE_PATH + "/" + getTestName(false) + ".java"); + List expected = ContainerUtil.newArrayList("http://example.com/ABC-1123", "http://example.com/ABC-2", + "http://example.com/ABC-22", "http://example.com/ABC-11"); + List actual = collectWebReferences().stream().map(WebReference::getUrl).collect(Collectors.toList()); + assertEquals(expected, actual); + } + finally { + navigationConfiguration.setLinks(oldLinks); + } + } + public void testLinksInJavaDoc() { configureByFile(BASE_PATH + "/" + getTestName(false) + ".java"); + @SuppressWarnings("SpellCheckingInspection") Set expected = ContainerUtil.newHashSet( + "http://www.unicode.org/unicode/standard/standard.html", + "http://docs.oracle.com/javase/7/docs/technotes/guides/lang/cl-mt.html", + "https://youtrack.jetbrains.com/issue/IDEA-131621", + "mailto:webmaster@jetbrains.com"); + Set actual = collectWebReferences().stream().map(PsiReferenceBase::getCanonicalText).collect(Collectors.toSet()); + assertEquals(expected, actual); + } + @NotNull + public static List collectWebReferences() { final List refs = new ArrayList<>(); myFile.accept(new PsiRecursiveElementWalkingVisitor() { @Override @@ -109,18 +138,8 @@ public class JavadocHighlightingTest extends LightDaemonAnalyzerTestCase { super.visitElement(element); } }); - assertTrue(refs.stream().allMatch(PsiReferenceBase::isSoft)); - - assertTrue(refs.stream().allMatch(ref -> ref.resolve() != null)); - - @SuppressWarnings("SpellCheckingInspection") Set expected = ContainerUtil.newHashSet( - "http://www.unicode.org/unicode/standard/standard.html", - "http://docs.oracle.com/javase/7/docs/technotes/guides/lang/cl-mt.html", - "https://youtrack.jetbrains.com/issue/IDEA-131621", - "mailto:webmaster@jetbrains.com"); - Set actual = refs.stream().map(PsiReferenceBase::getCanonicalText).collect(Collectors.toSet()); - assertEquals(expected, actual); + return refs; } private void doTestWithLangLevel(LanguageLevel level) { diff --git a/platform/lang-impl/src/com/intellij/openapi/paths/WebReference.java b/platform/lang-impl/src/com/intellij/openapi/paths/WebReference.java index 49033af5564a..56f4b5aae40e 100644 --- a/platform/lang-impl/src/com/intellij/openapi/paths/WebReference.java +++ b/platform/lang-impl/src/com/intellij/openapi/paths/WebReference.java @@ -52,7 +52,7 @@ public class WebReference extends PsiReferenceBase { return new MyFakePsiElement(); } - protected String getUrl() { + public String getUrl() { return myUrl != null ? myUrl : getValue(); } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/ArbitraryPlaceUrlReferenceProvider.java b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/ArbitraryPlaceUrlReferenceProvider.java index e07020452adb..efa996099eac 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/ArbitraryPlaceUrlReferenceProvider.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/ArbitraryPlaceUrlReferenceProvider.java @@ -17,8 +17,8 @@ package com.intellij.psi.impl.source.resolve.reference; import com.intellij.openapi.paths.GlobalPathReferenceProvider; import com.intellij.openapi.paths.PathReferenceManager; -import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.UserDataCache; +import com.intellij.openapi.vcs.IssueNavigationConfiguration; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; import com.intellij.psi.PsiReferenceProvider; @@ -27,46 +27,40 @@ import com.intellij.psi.util.CachedValueProvider; import com.intellij.psi.util.CachedValuesManager; import com.intellij.util.ProcessingContext; import com.intellij.util.SmartList; -import com.intellij.util.io.URLUtil; import org.jetbrains.annotations.NotNull; import java.util.List; import java.util.concurrent.atomic.AtomicReference; -import java.util.regex.Matcher; public class ArbitraryPlaceUrlReferenceProvider extends PsiReferenceProvider { private static final UserDataCache, PsiElement, Object> ourRefsCache = new UserDataCache, PsiElement, Object>("psielement.url.refs") { - private final AtomicReference myReferenceProvider = new AtomicReference(); + private final AtomicReference myReferenceProvider = new AtomicReference(); - @Override - protected CachedValue compute(final PsiElement element, Object p) { - return CachedValuesManager - .getManager(element.getProject()).createCachedValue(new CachedValueProvider() { + @Override + protected CachedValue compute(final PsiElement element, Object p) { + return CachedValuesManager.getManager(element.getProject()).createCachedValue(new CachedValueProvider() { public Result compute() { - Matcher matcher = URLUtil.URL_PATTERN.matcher(element.getText()); - + IssueNavigationConfiguration navigationConfiguration = IssueNavigationConfiguration.getInstance(element.getProject()); + if (navigationConfiguration == null) { + return Result.create(PsiReference.EMPTY_ARRAY, element); + } + List refs = null; GlobalPathReferenceProvider provider = myReferenceProvider.get(); - - while (matcher.find()) { - final int start = matcher.start(); - final int end = matcher.end(); + for (IssueNavigationConfiguration.LinkMatch link : navigationConfiguration.findIssueLinks(element.getText())) { if (refs == null) refs = new SmartList(); if (provider == null) { provider = (GlobalPathReferenceProvider)PathReferenceManager.getInstance().getGlobalWebPathReferenceProvider(); myReferenceProvider.lazySet(provider); } - - provider.createUrlReference(element, matcher.group(0), new TextRange(start, end), refs); + provider.createUrlReference(element, link.getTargetUrl(), link.getRange(), refs); } - - return new Result(refs != null ? refs.toArray(new PsiReference[refs.size()]) : PsiReference.EMPTY_ARRAY, - element); + PsiReference[] references = refs != null ? refs.toArray(new PsiReference[refs.size()]) : PsiReference.EMPTY_ARRAY; + return new Result(references, element, navigationConfiguration); } }, false); - - } - }; + } + }; @NotNull @Override diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/IssueNavigationConfiguration.java b/platform/vcs-api/src/com/intellij/openapi/vcs/IssueNavigationConfiguration.java index 8161750c99f7..fb4dea016a9a 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/IssueNavigationConfiguration.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/IssueNavigationConfiguration.java @@ -19,6 +19,7 @@ package com.intellij.openapi.vcs; import com.intellij.lifecycle.PeriodicalTasksCloser; import com.intellij.openapi.components.*; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.SimpleModificationTracker; import com.intellij.openapi.util.TextRange; import com.intellij.util.io.URLUtil; import com.intellij.util.xmlb.XmlSerializerUtil; @@ -40,7 +41,7 @@ import java.util.regex.Pattern; @Storage(file = StoragePathMacros.PROJECT_CONFIG_DIR + "/vcs.xml", scheme = StorageScheme.DIRECTORY_BASED) } ) -public class IssueNavigationConfiguration implements PersistentStateComponent { +public class IssueNavigationConfiguration extends SimpleModificationTracker implements PersistentStateComponent { public static IssueNavigationConfiguration getInstance(Project project) { return PeriodicalTasksCloser.getInstance().safeGetService(project, IssueNavigationConfiguration.class); } @@ -53,6 +54,7 @@ public class IssueNavigationConfiguration implements PersistentStateComponent links) { myLinks = new ArrayList(links); + incModificationCount(); } public IssueNavigationConfiguration getState() { From 525be2693bb8bfbe6f4f391c9cb712671686d553 Mon Sep 17 00:00:00 2001 From: Alexander Zolotov Date: Tue, 25 Aug 2015 16:11:58 +0300 Subject: [PATCH 031/246] Fix leaks in ExternalSystemAutoImporter dispose alarms and connection on project close --- .../autoimport/ExternalSystemAutoImporter.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/autoimport/ExternalSystemAutoImporter.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/autoimport/ExternalSystemAutoImporter.java index 0b9bd9995028..008f66403e7d 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/autoimport/ExternalSystemAutoImporter.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/autoimport/ExternalSystemAutoImporter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -54,7 +54,10 @@ import com.intellij.util.messages.MessageBus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; @@ -69,11 +72,11 @@ public class ExternalSystemAutoImporter implements BulkFileListener, DocumentLis @NotNull private final ConcurrentMap> myFilesToRefresh = ContainerUtil.newConcurrentMap(); - @NotNull private final Alarm myVfsAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); + @NotNull private final Alarm myVfsAlarm; @NotNull private final ReadWriteLock myVfsLock = new ReentrantReadWriteLock(); @NotNull private final Set myDocumentsToSave = ContainerUtilRt.newHashSet(); - @NotNull private final Alarm myDocumentAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); + @NotNull private final Alarm myDocumentAlarm; @NotNull private final ReadWriteLock myDocumentLock = new ReentrantReadWriteLock(); @NotNull private final Runnable myFilesRequest = new Runnable() { @@ -124,6 +127,8 @@ public class ExternalSystemAutoImporter implements BulkFileListener, DocumentLis myProject = project; myProjectDataManager = projectDataManager; myAutoImportAware = autoImportAware; + myVfsAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD, project); + myDocumentAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD, project); } @SuppressWarnings("unchecked") @@ -150,7 +155,7 @@ public class ExternalSystemAutoImporter implements BulkFileListener, DocumentLis entries ); final MessageBus messageBus = project.getMessageBus(); - messageBus.connect().subscribe(VirtualFileManager.VFS_CHANGES, autoImporter); + messageBus.connect(project).subscribe(VirtualFileManager.VFS_CHANGES, autoImporter); EditorFactory.getInstance().getEventMulticaster().addDocumentListener(autoImporter, project); } From 2e12c76270612f8f055384db0e23f3829ed4fb48 Mon Sep 17 00:00:00 2001 From: Alexander Zolotov Date: Tue, 25 Aug 2015 16:14:01 +0300 Subject: [PATCH 032/246] Optimize imports --- platform/util/testSrc/com/intellij/util/io/UrlUtilTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/platform/util/testSrc/com/intellij/util/io/UrlUtilTest.java b/platform/util/testSrc/com/intellij/util/io/UrlUtilTest.java index bf52b65ed434..1c83f14684ed 100644 --- a/platform/util/testSrc/com/intellij/util/io/UrlUtilTest.java +++ b/platform/util/testSrc/com/intellij/util/io/UrlUtilTest.java @@ -28,10 +28,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.junit.Test; -import static org.assertj.core.api.Assertions.assertThat; import java.util.regex.Matcher; -import static org.hamcrest.CoreMatchers.equalTo; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.*; public class UrlUtilTest { From 739766431c62c0008b30c6a82f22e88058871825 Mon Sep 17 00:00:00 2001 From: Alexander Zolotov Date: Tue, 25 Aug 2015 16:42:51 +0300 Subject: [PATCH 033/246] Unregister facet listeners on project disposing --- .../ui/FacetDependentToolWindowManager.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/facet/impl/ui/FacetDependentToolWindowManager.java b/platform/lang-impl/src/com/intellij/facet/impl/ui/FacetDependentToolWindowManager.java index 176ce6af5929..d87bc6e93066 100644 --- a/platform/lang-impl/src/com/intellij/facet/impl/ui/FacetDependentToolWindowManager.java +++ b/platform/lang-impl/src/com/intellij/facet/impl/ui/FacetDependentToolWindowManager.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2015 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.facet.impl.ui; import com.intellij.facet.*; @@ -57,7 +72,7 @@ public class FacetDependentToolWindowManager extends AbstractProjectComponent { } } } - }); + }, myProject); FacetDependentToolWindow[] extensions = Extensions.getExtensions(FacetDependentToolWindow.EXTENSION_POINT_NAME); loop: for (FacetDependentToolWindow extension : extensions) { From 468391cb0a96463839f9e7453cdf42498735c5fd Mon Sep 17 00:00:00 2001 From: Andrey Vokin Date: Tue, 25 Aug 2015 17:01:25 +0300 Subject: [PATCH 034/246] Slim and Jade. When parsing ruby code start marker goes to the root element. --- .../MasqueradingPsiBuilderAdapter.java | 43 +++++++++++++------ 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/xml/xml-psi-impl/src/com/intellij/embedding/MasqueradingPsiBuilderAdapter.java b/xml/xml-psi-impl/src/com/intellij/embedding/MasqueradingPsiBuilderAdapter.java index 7cdb16b51ffc..044ff757a5f0 100644 --- a/xml/xml-psi-impl/src/com/intellij/embedding/MasqueradingPsiBuilderAdapter.java +++ b/xml/xml-psi-impl/src/com/intellij/embedding/MasqueradingPsiBuilderAdapter.java @@ -24,7 +24,6 @@ import com.intellij.lang.impl.PsiBuilderAdapter; import com.intellij.lang.impl.PsiBuilderImpl; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; -import com.intellij.psi.TokenType; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -225,20 +224,22 @@ public class MasqueradingPsiBuilderAdapter extends PsiBuilderAdapter { @NotNull @Override public Marker mark() { - Marker originalPositionMarker = super.mark(); + Marker originalPositionMarker = null; // In the case of the topmost node all should be inserted if (myLexPosition != 0) { + originalPositionMarker = super.mark(); synchronizePositions(true); } final Marker mark = super.mark(); + if (myLexPosition == 0) { + if (myDelegate.getTokenType() == TemplateMasqueradingLexer.MINUS_TYPE) { + myDelegate.advanceLexer(); + } + } return new MyMarker(mark, originalPositionMarker, myLexPosition); } - private boolean allIsEmpty() { - return myShrunkSequence.isEmpty() && getDelegate().getOriginalText().length() != 0; - } - private void skipWhitespace() { while (myLexPosition < myShrunkSequence.size() && isWhiteSpaceOnPos(myLexPosition)) { myLexPosition++; @@ -344,43 +345,59 @@ public class MasqueradingPsiBuilderAdapter extends PsiBuilderAdapter { @Override public void rollbackTo() { - myOriginalPositionMarker.rollbackTo(); + if (myOriginalPositionMarker != null) { + myOriginalPositionMarker.rollbackTo(); + } else { + super.rollbackTo(); + } myLexPosition = myBuilderPosition; } @Override public void doneBefore(@NotNull IElementType type, @NotNull Marker before) { - myOriginalPositionMarker.drop(); + if (myOriginalPositionMarker != null) { + myOriginalPositionMarker.drop(); + } super.doneBefore(type, getDelegateOrThis(before)); } @Override public void doneBefore(@NotNull IElementType type, @NotNull Marker before, String errorMessage) { - myOriginalPositionMarker.drop(); + if (myOriginalPositionMarker != null) { + myOriginalPositionMarker.drop(); + } super.doneBefore(type, getDelegateOrThis(before), errorMessage); } @Override public void drop() { - myOriginalPositionMarker.drop(); + if (myOriginalPositionMarker != null) { + myOriginalPositionMarker.drop(); + } super.drop(); } @Override public void done(@NotNull IElementType type) { - myOriginalPositionMarker.drop(); + if (myOriginalPositionMarker != null) { + myOriginalPositionMarker.drop(); + } super.done(type); } @Override public void collapse(@NotNull IElementType type) { - myOriginalPositionMarker.drop(); + if (myOriginalPositionMarker != null) { + myOriginalPositionMarker.drop(); + } super.collapse(type); } @Override public void error(String message) { - myOriginalPositionMarker.drop(); + if (myOriginalPositionMarker != null) { + myOriginalPositionMarker.drop(); + } super.error(message); } From 5f596d7209f3ef9c56cda1c31f3a3bed73eb078d Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Thu, 2 Jul 2015 11:20:42 +0300 Subject: [PATCH 035/246] IDEA-139962 log: filter action should be dumb-aware (cherry picked from commit ccc3fdd1ddcb32876ac5321a657ade3c450e1aee) --- .../vcs/log/ui/filter/StructureFilterPopupComponent.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java index e6aeb338394c..252bf4a23394 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java @@ -16,6 +16,7 @@ package com.intellij.vcs.log.ui.filter; import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; @@ -221,7 +222,7 @@ class StructureFilterPopupComponent extends FilterPopupComponent Date: Mon, 6 Jul 2015 10:52:08 +0300 Subject: [PATCH 036/246] IDEA-134049 do not close action popup menu on click on toggle action * allow to toggle actions with space (cherry picked from commit 7f2fc156b51283d70d0bb5bfd237c639f7548554) --- .../intellij/ui/popup/PopupFactoryImpl.java | 77 +++++++++++++++++-- .../filter/StructureFilterPopupComponent.java | 2 + 2 files changed, 73 insertions(+), 6 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java b/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java index 6ad38f60e760..ea0796235585 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java @@ -50,7 +50,10 @@ import com.intellij.ui.components.panels.NonOpaquePanel; import com.intellij.ui.popup.list.ListPopupImpl; import com.intellij.ui.popup.mock.MockConfirmation; import com.intellij.ui.popup.tree.TreePopupImpl; +import com.intellij.util.Function; +import com.intellij.util.ObjectUtils; import com.intellij.util.PlatformIcons; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.containers.WeakHashMap; import com.intellij.util.ui.EmptyIcon; @@ -65,6 +68,9 @@ import javax.swing.event.HyperlinkListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -218,6 +224,13 @@ public class PopupFactoryImpl extends JBPopupFactory { myDisposeCallback = disposeCallback; myComponent = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext); + registerAction("handleActionToggle1", KeyEvent.VK_SPACE, 0, new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + handleToggleAction(); + } + }); + addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { @@ -270,6 +283,52 @@ public class PopupFactoryImpl extends JBPopupFactory { ActionMenu.showDescriptionInStatusBar(true, myComponent, null); super.dispose(); } + + @Override + public void handleSelect(boolean handleFinalChoices, InputEvent e) { + final Object selectedValue = getList().getSelectedValue(); + final ActionPopupStep actionPopupStep = ObjectUtils.tryCast(getListStep(), ActionPopupStep.class); + + if (actionPopupStep != null) { + ToggleAction toggleAction = getToggleAction(selectedValue, actionPopupStep); + if (toggleAction != null) { + actionPopupStep.performAction(toggleAction, e != null ? e.getModifiers() : 0); + getList().repaint(); + return; + } + } + + super.handleSelect(handleFinalChoices, e); + } + + protected void handleToggleAction() { + final Object[] selectedValues = getList().getSelectedValues(); + + ListPopupStep listStep = getListStep(); + final ActionPopupStep actionPopupStep = ObjectUtils.tryCast(listStep, ActionPopupStep.class); + if (actionPopupStep == null) return; + + List filtered = ContainerUtil.mapNotNull(selectedValues, new Function() { + @Override + public ToggleAction fun(Object o) { + return getToggleAction(o, actionPopupStep); + } + }); + + for (ToggleAction action : filtered) { + actionPopupStep.performAction(action, 0); + } + + getList().repaint(); + } + + @Nullable + private static ToggleAction getToggleAction(@Nullable Object value, @NotNull ActionPopupStep actionPopupStep) { + ActionItem item = value instanceof ActionItem ? (ActionItem)value : null; + if (item == null) return null; + if (!actionPopupStep.isSelectable(item)) return null; + return item.getAction() instanceof ToggleAction ? (ToggleAction)item.getAction() : null; + } } @NotNull @@ -740,18 +799,24 @@ public class PopupFactoryImpl extends JBPopupFactory { myFinalRunnable = new Runnable() { @Override public void run() { - final AnActionEvent event = new AnActionEvent(null, dataContext, ActionPlaces.UNKNOWN, action.getTemplatePresentation().clone(), - ActionManager.getInstance(), eventModifiers); - event.setInjectedContext(action.isInInjectedContext()); - if (ActionUtil.lastUpdateAndCheckDumb(action, event, false)) { - action.actionPerformed(event); - } + performAction(action, eventModifiers); } }; return FINAL_CHOICE; } } + public void performAction(@NotNull AnAction action, int modifiers) { + final DataManager mgr = DataManager.getInstance(); + final DataContext dataContext = myContext != null ? mgr.getDataContext(myContext) : mgr.getDataContext(); + final AnActionEvent event = new AnActionEvent(null, dataContext, ActionPlaces.UNKNOWN, action.getTemplatePresentation().clone(), + ActionManager.getInstance(), modifiers); + event.setInjectedContext(action.isInInjectedContext()); + if (ActionUtil.lastUpdateAndCheckDumb(action, event, false)) { + action.actionPerformed(event); + } + } + @Override public Runnable getFinalRunnable() { return myFinalRunnable; diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java index 252bf4a23394..e90fdb873cc8 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java @@ -246,6 +246,8 @@ class StructureFilterPopupComponent extends FilterPopupComponent Date: Mon, 6 Jul 2015 11:12:27 +0300 Subject: [PATCH 037/246] IDEA-134049 log: ctrl+click to select a single root (cherry picked from commit 3b405063e7aa52fa15320c61387014246d4eccff) --- .../src/com/intellij/ui/popup/list/ListPopupImpl.java | 5 +++++ .../vcs/log/ui/filter/StructureFilterPopupComponent.java | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java b/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java index 55dd37d3089f..1613fe696896 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java @@ -521,6 +521,11 @@ public class ListPopupImpl extends WizardPopup implements ListPopup { @Override protected void processMouseEvent(MouseEvent e) { + if (!isMultiSelectionEnabled() && + (e.getModifiers() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) != 0) { + // do not toggle selection with ctrl+click event in single-selection mode + e.consume(); + } if (UIUtil.isActionClick(e, MouseEvent.MOUSE_PRESSED) && isOnNextStepButton(e)) { e.consume(); } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java index e90fdb873cc8..e66766a788bc 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java @@ -40,6 +40,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; +import java.awt.event.InputEvent; import java.util.*; import java.util.List; @@ -244,7 +245,12 @@ class StructureFilterPopupComponent extends FilterPopupComponent Date: Mon, 6 Jul 2015 11:26:10 +0300 Subject: [PATCH 038/246] IDEA-134049 log: update Icons in all actions do not wait for the newt update() to change state of 'checkbox' (cherry picked from commit 1c5a8f20dfa29136b07789445d0876dfac1ed81f) --- .../intellij/ui/popup/PopupFactoryImpl.java | 46 ++++++++++++------- .../filter/StructureFilterPopupComponent.java | 11 +++-- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java b/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java index ea0796235585..a10187dd5d4f 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java @@ -206,6 +206,7 @@ public class PopupFactoryImpl extends JBPopupFactory { private final Runnable myDisposeCallback; private final Component myComponent; + private final String myActionPlace; public ActionGroupPopup(final String title, @NotNull ActionGroup actionGroup, @@ -223,6 +224,7 @@ public class PopupFactoryImpl extends JBPopupFactory { maxRowCount); myDisposeCallback = disposeCallback; myComponent = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext); + myActionPlace = actionPlace == null ? ActionPlaces.UNKNOWN : actionPlace; registerAction("handleActionToggle1", KeyEvent.VK_SPACE, 0, new AbstractAction() { @Override @@ -237,20 +239,26 @@ public class PopupFactoryImpl extends JBPopupFactory { final JList list = (JList)e.getSource(); final ActionItem actionItem = (ActionItem)list.getSelectedValue(); if (actionItem == null) return; - AnAction action = actionItem.getAction(); - Presentation presentation = new Presentation(); - presentation.setDescription(action.getTemplatePresentation().getDescription()); - final String actualActionPlace = actionPlace == null ? ActionPlaces.UNKNOWN : actionPlace; - final AnActionEvent actionEvent = - new AnActionEvent(null, DataManager.getInstance().getDataContext(myComponent), actualActionPlace, presentation, - ActionManager.getInstance(), 0); - actionEvent.setInjectedContext(action.isInInjectedContext()); - ActionUtil.performDumbAwareUpdate(action, actionEvent, false); + Presentation presentation = updateActionItem(actionItem); ActionMenu.showDescriptionInStatusBar(true, myComponent, presentation.getDescription()); } }); } + @NotNull + private Presentation updateActionItem(@NotNull ActionItem actionItem) { + AnAction action = actionItem.getAction(); + Presentation presentation = new Presentation(); + presentation.setDescription(action.getTemplatePresentation().getDescription()); + + final AnActionEvent actionEvent = + new AnActionEvent(null, DataManager.getInstance().getDataContext(myComponent), myActionPlace, presentation, + ActionManager.getInstance(), 0); + actionEvent.setInjectedContext(action.isInInjectedContext()); + ActionUtil.performDumbAwareUpdate(action, actionEvent, false); + return presentation; + } + private static ListPopupStep createStep(String title, @NotNull ActionGroup actionGroup, @NotNull DataContext dataContext, @@ -293,6 +301,9 @@ public class PopupFactoryImpl extends JBPopupFactory { ToggleAction toggleAction = getToggleAction(selectedValue, actionPopupStep); if (toggleAction != null) { actionPopupStep.performAction(toggleAction, e != null ? e.getModifiers() : 0); + for (ActionItem item : actionPopupStep.myItems) { + updateActionItem(item); + } getList().repaint(); return; } @@ -319,6 +330,10 @@ public class PopupFactoryImpl extends JBPopupFactory { actionPopupStep.performAction(action, 0); } + for (ActionItem item : actionPopupStep.myItems) { + updateActionItem(item); + } + getList().repaint(); } @@ -468,7 +483,7 @@ public class PopupFactoryImpl extends JBPopupFactory { @NotNull @Override public ListPopup createWizardStep(@NotNull PopupStep step) { - return new ListPopupImpl((ListPopupStep) step); + return new ListPopupImpl((ListPopupStep)step); } @NotNull @@ -501,7 +516,7 @@ public class PopupFactoryImpl extends JBPopupFactory { return new ComponentPopupBuilderImpl(content, prefferableFocusComponent); } - + @NotNull @Override public RelativePoint guessBestPopupLocation(@NotNull DataContext dataContext) { @@ -581,7 +596,8 @@ public class PopupFactoryImpl extends JBPopupFactory { if (bestRow != -1) { Rectangle rowBounds = tree.getRowBounds(bestRow); - tree.scrollRectToVisible(new Rectangle(rowBounds.x, rowBounds.y, Math.min(visibleRect.width, rowBounds.width), rowBounds.height)); + tree.scrollRectToVisible( + new Rectangle(rowBounds.x, rowBounds.y, Math.min(visibleRect.width, rowBounds.width), rowBounds.height)); popupMenuPoint = new Point(rowBounds.x + 2, rowBounds.y + rowBounds.height - 1); } } @@ -677,7 +693,7 @@ public class PopupFactoryImpl extends JBPopupFactory { public Icon getIcon() { return myIcon; - } + } public boolean isPrependWithSeparator() { return myPrependWithSeparator; @@ -1095,9 +1111,7 @@ public class PopupFactoryImpl extends JBPopupFactory { .setDialogMode(true) .setTitle(title) .setAnimationCycle(200) - .setFillColor(bg) - .setBorderColor(border) - .setHideOnClickOutside(false) + .setFillColor(bg).setBorderColor(border).setHideOnClickOutside(false) .setHideOnKeyOutside(false) .setHideOnAction(false) .setCloseButtonEnabled(true) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java index e66766a788bc..5c1370f4e3e1 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java @@ -252,17 +252,18 @@ class StructureFilterPopupComponent extends FilterPopupComponent Date: Sun, 19 Jul 2015 20:34:09 +0300 Subject: [PATCH 039/246] marker interface for actions that prevent popup from closing on click on them (cherry picked from commit a7647c77df6a39a040896a61fe542263ad883282) --- .../ui/popup/KeepingPopupOpenAction.java | 22 +++++++++++++++++++ .../intellij/ui/popup/PopupFactoryImpl.java | 12 +++++----- .../filter/StructureFilterPopupComponent.java | 3 ++- 3 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 platform/platform-impl/src/com/intellij/ui/popup/KeepingPopupOpenAction.java diff --git a/platform/platform-impl/src/com/intellij/ui/popup/KeepingPopupOpenAction.java b/platform/platform-impl/src/com/intellij/ui/popup/KeepingPopupOpenAction.java new file mode 100644 index 000000000000..e8748921e7d8 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ui/popup/KeepingPopupOpenAction.java @@ -0,0 +1,22 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ui.popup; + +/** + * Marker interface for actions that prevent popup from closing when user clicks on them. + * */ +public interface KeepingPopupOpenAction { +} diff --git a/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java b/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java index a10187dd5d4f..ee30c2b8288c 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java @@ -298,9 +298,9 @@ public class PopupFactoryImpl extends JBPopupFactory { final ActionPopupStep actionPopupStep = ObjectUtils.tryCast(getListStep(), ActionPopupStep.class); if (actionPopupStep != null) { - ToggleAction toggleAction = getToggleAction(selectedValue, actionPopupStep); - if (toggleAction != null) { - actionPopupStep.performAction(toggleAction, e != null ? e.getModifiers() : 0); + KeepingPopupOpenAction dontClosePopupAction = getActionByClass(selectedValue, actionPopupStep, KeepingPopupOpenAction.class); + if (dontClosePopupAction != null) { + actionPopupStep.performAction((AnAction)dontClosePopupAction, e != null ? e.getModifiers() : 0); for (ActionItem item : actionPopupStep.myItems) { updateActionItem(item); } @@ -322,7 +322,7 @@ public class PopupFactoryImpl extends JBPopupFactory { List filtered = ContainerUtil.mapNotNull(selectedValues, new Function() { @Override public ToggleAction fun(Object o) { - return getToggleAction(o, actionPopupStep); + return getActionByClass(o, actionPopupStep, ToggleAction.class); } }); @@ -338,11 +338,11 @@ public class PopupFactoryImpl extends JBPopupFactory { } @Nullable - private static ToggleAction getToggleAction(@Nullable Object value, @NotNull ActionPopupStep actionPopupStep) { + private static T getActionByClass(@Nullable Object value, @NotNull ActionPopupStep actionPopupStep, @NotNull Class actionClass) { ActionItem item = value instanceof ActionItem ? (ActionItem)value : null; if (item == null) return null; if (!actionPopupStep.isSelectable(item)) return null; - return item.getAction() instanceof ToggleAction ? (ToggleAction)item.getAction() : null; + return actionClass.isInstance(item.getAction()) ? actionClass.cast(item.getAction()) : null; } } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java index 5c1370f4e3e1..13b03e28410e 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java @@ -19,6 +19,7 @@ import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; +import com.intellij.ui.popup.KeepingPopupOpenAction; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.SizedIcon; @@ -223,7 +224,7 @@ class StructureFilterPopupComponent extends FilterPopupComponent Date: Sun, 19 Jul 2015 23:00:20 +0300 Subject: [PATCH 040/246] allow action popup to show tooltip; show tooltip for select root actions in structure popup in log (cherry picked from commit 2ffef237d585ee3748aa963bd7e28bb50778379a) --- .../openapi/ui/popup/ListPopupStepEx.java | 4 +++ .../intellij/ui/GroupedElementsRenderer.java | 2 +- .../intellij/ui/popup/PopupFactoryImpl.java | 26 ++++++++++++++++--- .../popup/list/PopupListElementRenderer.java | 10 +++++++ .../filter/StructureFilterPopupComponent.java | 1 + 5 files changed, 39 insertions(+), 4 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/ui/popup/ListPopupStepEx.java b/platform/platform-api/src/com/intellij/openapi/ui/popup/ListPopupStepEx.java index f3ea978b87e5..75dd6e84fbe4 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/popup/ListPopupStepEx.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/popup/ListPopupStepEx.java @@ -1,9 +1,13 @@ package com.intellij.openapi.ui.popup; import org.intellij.lang.annotations.MagicConstant; +import org.jetbrains.annotations.Nullable; import java.awt.event.InputEvent; public interface ListPopupStepEx extends ListPopupStep { PopupStep onChosen(T selectedValue, boolean finalChoice, @MagicConstant(flagsFromClass = InputEvent.class) int eventModifiers); + + @Nullable + String getTooltipTextFor(T value); } \ No newline at end of file diff --git a/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java b/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java index a7bdb9f1bb62..9f828799422e 100644 --- a/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java +++ b/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java @@ -58,7 +58,7 @@ public abstract class GroupedElementsRenderer { mySeparatorComponent.setMinimumWidth(preferredForcedWidth); myTextLabel.setText(text); - myTextLabel.setToolTipText(tooltip); + myRendererComponent.setToolTipText(tooltip); myTextLabel.setIcon(icon); myTextLabel.setDisabledIcon(disabledIcon); diff --git a/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java b/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java index ee30c2b8288c..2f3bdd8eba96 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java @@ -671,14 +671,22 @@ public class PopupFactoryImpl extends JBPopupFactory { private final Icon myIcon; private final boolean myPrependWithSeparator; private final String mySeparatorText; + private final String myDescription; - private ActionItem(@NotNull AnAction action, @NotNull String text, boolean enabled, Icon icon, final boolean prependWithSeparator, String separatorText) { + private ActionItem(@NotNull AnAction action, + @NotNull String text, + @Nullable String description, + boolean enabled, + Icon icon, + final boolean prependWithSeparator, + String separatorText) { myAction = action; myText = text; myIsEnabled = enabled; myIcon = icon; myPrependWithSeparator = prependWithSeparator; mySeparatorText = separatorText; + myDescription = description; } @NotNull @@ -704,6 +712,10 @@ public class PopupFactoryImpl extends JBPopupFactory { } public boolean isEnabled() { return myIsEnabled; } + + public String getDescription() { + return myDescription; + } } private static class ActionPopupStep implements ListPopupStepEx, MnemonicNavigationFilter, SpeedSearchFilter { @@ -779,6 +791,12 @@ public class PopupFactoryImpl extends JBPopupFactory { return value.getText(); } + @Nullable + @Override + public String getTooltipTextFor(ActionItem value) { + return value.getDescription(); + } + @Override public ListSeparator getSeparatorAbove(final ActionItem value) { return value.isPrependWithSeparator() ? new ListSeparator(value.getSeparatorText()) : null; @@ -942,7 +960,7 @@ public class PopupFactoryImpl extends JBPopupFactory { appendActionsFromGroup(actionGroup); if (myListModel.isEmpty()) { - myListModel.add(new ActionItem(Utils.EMPTY_MENU_FILLER, Utils.NOTHING_HERE, false, null, false, null)); + myListModel.add(new ActionItem(Utils.EMPTY_MENU_FILLER, Utils.NOTHING_HERE, null, false, null, false, null)); } } @@ -1051,7 +1069,9 @@ public class PopupFactoryImpl extends JBPopupFactory { } boolean prependSeparator = (!myListModel.isEmpty() || mySeparatorText != null) && myPrependWithSeparator; assert text != null : action + " has no presentation"; - myListModel.add(new ActionItem(action, text, presentation.isEnabled(), icon, prependSeparator, mySeparatorText)); + myListModel.add( + new ActionItem(action, text, (String)presentation.getClientProperty(JComponent.TOOL_TIP_TEXT_KEY), presentation.isEnabled(), icon, + prependSeparator, mySeparatorText)); myPrependWithSeparator = false; mySeparatorText = null; } diff --git a/platform/platform-impl/src/com/intellij/ui/popup/list/PopupListElementRenderer.java b/platform/platform-impl/src/com/intellij/ui/popup/list/PopupListElementRenderer.java index 0431d39c1ff0..aa973cd8ee88 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/list/PopupListElementRenderer.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/list/PopupListElementRenderer.java @@ -18,9 +18,11 @@ package com.intellij.ui.popup.list; import com.intellij.icons.AllIcons; import com.intellij.openapi.ui.popup.ListItemDescriptorAdapter; import com.intellij.openapi.ui.popup.ListPopupStep; +import com.intellij.openapi.ui.popup.ListPopupStepEx; import com.intellij.openapi.ui.popup.util.BaseListPopupStep; import com.intellij.ui.ColorUtil; import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; @@ -49,6 +51,14 @@ public class PopupListElementRenderer extends GroupedItemsListRenderer { public String getCaptionAboveOf(Object value) { return aPopup.getListModel().getCaptionAboveOf(value); } + + @Nullable + @Override + public String getTooltipFor(Object value) { + ListPopupStep listStep = aPopup.getListStep(); + if (!(listStep instanceof ListPopupStepEx)) return null; + return ((ListPopupStepEx)listStep).getTooltipTextFor(value); + } }); myPopup = aPopup; } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java index 13b03e28410e..df20ae5d642d 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java @@ -261,6 +261,7 @@ class StructureFilterPopupComponent extends FilterPopupComponent Date: Tue, 25 Aug 2015 13:46:41 +0200 Subject: [PATCH 041/246] more diagnostics for VfsData.initFile exceptions (IDEA-141920) --- .../src/com/intellij/openapi/vfs/newvfs/impl/VfsData.java | 8 +++++++- .../openapi/vfs/newvfs/persistent/PersistentFSImpl.java | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VfsData.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VfsData.java index 3655a3f6b108..4685cabd0054 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VfsData.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VfsData.java @@ -151,7 +151,13 @@ public class VfsData { Object existingData = segment.myObjectArray.get(offset); if (existingData != null) { - throw new AssertionError("File already created: " + existingData + "; parentId=" + FSRecords.getParent(id)); + int parent = FSRecords.getParent(id); + String msg = "File already created: " + existingData + "; parentId=" + parent; + if (parent > 0) { + msg += "; parent.name=" + FSRecords.getName(parent); + msg += "; parent.children=" + Arrays.toString(FSRecords.listAll(id)); + } + throw new AssertionError(msg); } segment.myObjectArray.set(offset, data); } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java index 17feca44f204..da3d889bf7b0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java @@ -915,7 +915,7 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone throw new RuntimeException("Duplicate FS roots: " + rootUrl + " and " + entry.getKey() + ", id=" + rootId + ", valid=" + existingRoot.isValid(), e); } } - throw new RuntimeException("No root duplication", e); + throw new RuntimeException("No root duplication, roots" + Arrays.toString(FSRecords.listAll(1)), e); } incStructuralModificationCount(); mark = writeAttributesToRecord(rootId, 0, newRoot, fs, attributes); From 189ade356afe9db912cf630b9f01ffef182d4def Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Aug 2015 14:07:29 +0200 Subject: [PATCH 042/246] remove unused LookupValueWithTail --- .../codeInsight/lookup/LookupItemUtil.java | 6 ----- .../completion/CompletionData.java | 3 --- .../lookup/LookupValueFactory.java | 19 -------------- .../lookup/LookupValueWithTail.java | 25 ------------------- 4 files changed, 53 deletions(-) delete mode 100644 platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupValueWithTail.java diff --git a/java/java-impl/src/com/intellij/codeInsight/lookup/LookupItemUtil.java b/java/java-impl/src/com/intellij/codeInsight/lookup/LookupItemUtil.java index 6d24dbdc8135..269e5652f981 100644 --- a/java/java-impl/src/com/intellij/codeInsight/lookup/LookupItemUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/lookup/LookupItemUtil.java @@ -40,9 +40,6 @@ import java.util.Collection; public class LookupItemUtil{ private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.lookup.LookupItemUtil"); - private LookupItemUtil() { - } - @Nullable public static LookupElement addLookupItem(Collection set, @NotNull Object object) { return addLookupItem(set, object, new CamelHumpMatcher("")); @@ -124,9 +121,6 @@ public class LookupItemUtil{ if (s == null) { LOG.error("Null string for object: " + object + " of class " + (object != null ? object.getClass() : null)); } - if (object instanceof LookupValueWithTail) { - item.setAttribute(LookupItem.TAIL_TEXT_ATTR, " " + ((LookupValueWithTail)object).getTailText()); - } item.setLookupString(s); item.setTailType(tailType); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionData.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionData.java index 9708c7b52168..2f3fe2bf6250 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionData.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionData.java @@ -260,9 +260,6 @@ public class CompletionData { if (object instanceof LookupValueWithUIHint && ((LookupValueWithUIHint) object).isBold()) { item.setBold(); } - if (object instanceof LookupValueWithTail) { - item.setAttribute(LookupItem.TAIL_TEXT_ATTR, " " + ((LookupValueWithTail)object).getTailText()); - } item.setAttribute(CompletionUtil.TAIL_TYPE_ATTR, tailType); return item; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupValueFactory.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupValueFactory.java index f0ebb111e48b..e90c888ad20b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupValueFactory.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupValueFactory.java @@ -43,10 +43,6 @@ public class LookupValueFactory { return new LookupValueWithIconAndHint(name, icon, hint); } - public static Object createLookupValueWithHintAndTail(@NotNull String name, @Nullable Icon icon, String hint, final String tail) { - return new LookupValueWithHintAndTail(name, icon, hint, tail); - } - public static class LookupValueWithIcon implements PresentableLookupValue, Iconable { private final String myName; private final Icon myIcon; @@ -100,19 +96,4 @@ public class LookupValueFactory { return false; } } - - public static class LookupValueWithHintAndTail extends LookupValueWithIconAndHint implements LookupValueWithTail { - private final String myTail; - - protected LookupValueWithHintAndTail(final String name, final Icon icon, final String hint, String tail) { - super(name, icon, hint); - myTail = tail; - } - - @Override - public String getTailText() { - return myTail; - } - } - } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupValueWithTail.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupValueWithTail.java deleted file mode 100644 index 835cead200a6..000000000000 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupValueWithTail.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.intellij.codeInsight.lookup; - -/** - * @author Dmitry Avdeev - * @deprecated use LookupElementBuilder - */ -public interface LookupValueWithTail { - String getTailText(); -} From c959e478a048b5eb9c22f14fb79a43ef7128a9d4 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Aug 2015 15:41:06 +0200 Subject: [PATCH 043/246] remove LookupItem method that nobody (not even external plugins) uses --- .../lookup/MutableLookupElement.java | 15 -------------- .../codeInsight/lookup/LookupItem.java | 20 ------------------- 2 files changed, 35 deletions(-) diff --git a/platform/lang-api/src/com/intellij/codeInsight/lookup/MutableLookupElement.java b/platform/lang-api/src/com/intellij/codeInsight/lookup/MutableLookupElement.java index 537e36414990..e3357ae729d3 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/lookup/MutableLookupElement.java +++ b/platform/lang-api/src/com/intellij/codeInsight/lookup/MutableLookupElement.java @@ -43,24 +43,9 @@ public abstract class MutableLookupElement extends LookupElement{ @NotNull public abstract MutableLookupElement setPresentableText(@NotNull String displayText); - @NotNull - public abstract MutableLookupElement setTypeText(final String text); - - @NotNull - public abstract MutableLookupElement setTailText(final String text, final boolean grayed); - @NotNull public abstract MutableLookupElement setTailType(@NotNull TailType type); - /** - * Use {@link com.intellij.codeInsight.completion.CompletionResultSet#caseInsensitive()} instead - * @param caseSensitive - * @return - */ - @Deprecated - @NotNull - public abstract MutableLookupElement setCaseSensitive(boolean caseSensitive); - public abstract MutableLookupElement addLookupStrings(@NonNls String... additionalLookupStrings); public abstract MutableLookupElement setInsertHandler(InsertHandler insertHandler); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java index cfd9b11ee3c4..8d4d296afdaa 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java @@ -282,11 +282,6 @@ public class LookupItem extends MutableLookupElement implements Comparable return this; } - public LookupItem setDeprecated(boolean deprecated) { - setAttribute(DEPRECATED_ATTR, deprecated ? "" : null); - return this; - } - @Override public LookupItem setAutoCompletionPolicy(final AutoCompletionPolicy policy) { myAutoCompletionPolicy = policy; @@ -328,28 +323,13 @@ public class LookupItem extends MutableLookupElement implements Comparable return myPresentable; } - @Override @NotNull - public LookupItem setTypeText(final String text) { - setAttribute(TYPE_TEXT_ATTR, text); - return this; - } - - @NotNull - @Override public MutableLookupElement setTailText(final String text, final boolean grayed) { setAttribute(TAIL_TEXT_ATTR, text); setAttribute(TAIL_TEXT_SMALL_ATTR, Boolean.TRUE); return this; } - @Override - @NotNull - public LookupItem setCaseSensitive(final boolean caseSensitive) { - setAttribute(CASE_INSENSITIVE, !caseSensitive); - return this; - } - @Override public LookupItem addLookupStrings(@NonNls final String... additionalLookupStrings) { ContainerUtil.addAll(myAllLookupStrings, additionalLookupStrings); From 84218d4ec2e4262a1ba8d9c88c342b2ada7196a3 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Aug 2015 16:23:06 +0200 Subject: [PATCH 044/246] remove unused LookupItem.DEPRECATED --- .../codeInsight/lookup/DefaultLookupItemRenderer.java | 5 ----- .../src/com/intellij/codeInsight/lookup/LookupItem.java | 1 - 2 files changed, 6 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/DefaultLookupItemRenderer.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/DefaultLookupItemRenderer.java index 62758a71f36e..6b9a8b2617fa 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/DefaultLookupItemRenderer.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/DefaultLookupItemRenderer.java @@ -38,7 +38,6 @@ public class DefaultLookupItemRenderer extends LookupElementRenderer presentation.setIcon(getRawIcon(item, presentation.isReal())); presentation.setItemText(getName(item)); - presentation.setStrikeout(isToStrikeout(item)); presentation.setItemTextBold(item.getAttribute(LookupItem.HIGHLIGHTED_ATTR) != null); presentation.setTailText(getText2(item), item.getAttribute(LookupItem.TAIL_TEXT_SMALL_ATTR) != null); presentation.setTypeText(getText3(item), null); @@ -99,10 +98,6 @@ public class DefaultLookupItemRenderer extends LookupElementRenderer return (String)item.getAttribute(LookupItem.TAIL_TEXT_ATTR); } - private static boolean isToStrikeout(LookupItem item) { - return item.getAttribute(LookupItem.DEPRECATED_ATTR) != null; - } - private static String getName(final LookupItem item){ final String presentableText = item.getPresentableText(); if (presentableText != null) return presentableText; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java index 8d4d296afdaa..9b846da394f5 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java @@ -54,7 +54,6 @@ public class LookupItem extends MutableLookupElement implements Comparable public static final Object FORCE_QUALIFY = Key.create("FORCE_QUALIFY"); public static final Object SUBSTITUTOR = Key.create("SUBSTITUTOR"); public static final Object TYPE = Key.create("TYPE"); - public static final Key DEPRECATED_ATTR = Key.create("DEPRECATED"); public static final Object CASE_INSENSITIVE = Key.create("CASE_INSENSITIVE"); From 1e7009197f8bb44be7a1ec789091ebc2f976a03f Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 25 Aug 2015 15:35:17 +0200 Subject: [PATCH 045/246] IDEA-143759 Repository contains unmerged paths. Merge not work for me --- .../src/RepositoryManager.kt | 12 +-- .../src/git/GitRepositoryManager.kt | 34 +++++++- plugins/settings-repository/src/git/pull.kt | 77 ++++++++++--------- plugins/settings-repository/src/sync.kt | 2 +- 4 files changed, 78 insertions(+), 47 deletions(-) diff --git a/plugins/settings-repository/src/RepositoryManager.kt b/plugins/settings-repository/src/RepositoryManager.kt index 4260dc5af3ad..1644e60a372b 100644 --- a/plugins/settings-repository/src/RepositoryManager.kt +++ b/plugins/settings-repository/src/RepositoryManager.kt @@ -50,9 +50,11 @@ public interface RepositoryManager { public fun processChildren(path: String, filter: (name: String) -> Boolean, processor: (name: String, inputStream: InputStream) -> Boolean) /** - * Not all implementations support progress indicator (will not be updated on progress) + * Not all implementations support progress indicator (will not be updated on progress). + * + * syncType will be passed if called before sync. */ - public fun commit(indicator: ProgressIndicator? = null): Boolean + public fun commit(indicator: ProgressIndicator? = null, syncType: SyncType? = null): Boolean public fun getAheadCommitsCount(): Int @@ -80,12 +82,6 @@ public interface RepositoryManager { } } -fun RepositoryManager.commitIfCan(indicator: ProgressIndicator? = null) { - if (canCommit()) { - commit(indicator) - } -} - public interface UpdateResult { val changed: Collection val deleted: Collection diff --git a/plugins/settings-repository/src/git/GitRepositoryManager.kt b/plugins/settings-repository/src/git/GitRepositoryManager.kt index 615fea45b624..d1463bdb7b71 100644 --- a/plugins/settings-repository/src/git/GitRepositoryManager.kt +++ b/plugins/settings-repository/src/git/GitRepositoryManager.kt @@ -24,10 +24,12 @@ import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.text.StringUtil import com.intellij.util.SmartList import org.eclipse.jgit.api.AddCommand +import org.eclipse.jgit.api.errors.UnmergedPathsException import org.eclipse.jgit.errors.TransportException import org.eclipse.jgit.lib.ConfigConstants import org.eclipse.jgit.lib.Constants import org.eclipse.jgit.lib.Repository +import org.eclipse.jgit.lib.RepositoryState import org.eclipse.jgit.storage.file.FileRepositoryBuilder import org.eclipse.jgit.transport.* import org.jetbrains.jgit.dirCache.AddLoadedFile @@ -110,7 +112,37 @@ class GitRepositoryManager(private val credentialsStore: NotNullLazyValue>() - val dirCache = repository.readDirCache() - val reader = repository.newObjectReader() - reader.use { - for (i in 0..(dirCache.getEntryCount() - 1)) { - val entry = dirCache.getEntry(i) - if (!entry.isMerged()) { - conflicts.getOrPut(entry.getPathString(), { arrayOfNulls(3) })[entry.getStage() - 1] = reader.open(entry.getObjectId(), Constants.OBJ_BLOB).getCachedBytes() - } - } - } - - resolveConflicts(JGitMergeProvider(repository, conflicts, { path, index -> get(path)!!.get(index) }), conflictsToVirtualFiles(conflicts), repository) - // compute new state - repositoryState = repository.getRepositoryState() - } - - if (repositoryState != RepositoryState.SAFE) { - LOG.warn(MessageFormat.format(JGitText.get().cannotPullOnARepoWithState, repositoryState.name())) + val state = manager.repository.fixAndGetState() + if (!state.canCheckout()) { + LOG.error("Cannot pull, repository in state ${state.getDescription()}") + return null } var refToMerge = prefetchedRefToMerge ?: fetch() ?: return null @@ -87,7 +69,7 @@ open class Pull(val manager: GitRepositoryManager, val indicator: ProgressIndica } if (mergeStatus == MergeStatus.CONFLICTING) { - return resolveConflicts(mergeResult, repository) + return resolveConflicts(mergeResult, manager.repository) } else if (!mergeStatus.isSuccessful()) { throw IllegalStateException(mergeResult.toString()) @@ -180,7 +162,7 @@ open class Pull(val manager: GitRepositoryManager, val indicator: ProgressIndica if (refUpdate.update() != RefUpdate.Result.NEW) { throw NoHeadException(JGitText.get().commitOnRepoWithoutHEADCurrentlyNotSupported) } - return MergeResultEx(srcCommit, MergeStatus.FAST_FORWARD, arrayOf(null, srcCommit), ImmutableUpdateResult(dirCacheCheckout.getUpdated().keySet(), dirCacheCheckout.getRemoved())) + return MergeResultEx(MergeStatus.FAST_FORWARD, arrayOf(null, srcCommit), ImmutableUpdateResult(dirCacheCheckout.getUpdated().keySet(), dirCacheCheckout.getRemoved())) } val refLogMessage = StringBuilder("merge ") @@ -188,7 +170,7 @@ open class Pull(val manager: GitRepositoryManager, val indicator: ProgressIndica val headCommit = revWalk.lookupCommit(headId) if (!forceMerge && revWalk.isMergedInto(srcCommit, headCommit)) { - return MergeResultEx(headCommit, MergeStatus.ALREADY_UP_TO_DATE, arrayOf(headCommit, srcCommit), EMPTY_UPDATE_RESULT) + return MergeResultEx(MergeStatus.ALREADY_UP_TO_DATE, arrayOf(headCommit, srcCommit), EMPTY_UPDATE_RESULT) //return MergeResult(headCommit, srcCommit, array(headCommit, srcCommit), MergeStatus.ALREADY_UP_TO_DATE, mergeStrategy, null) } else if (!forceMerge && fastForwardMode != FastForwardMode.NO_FF && revWalk.isMergedInto(headCommit, srcCommit)) { @@ -197,24 +179,21 @@ open class Pull(val manager: GitRepositoryManager, val indicator: ProgressIndica dirCacheCheckout = DirCacheCheckout(repository, headCommit.getTree(), repository.lockDirCache(), srcCommit.getTree()) dirCacheCheckout.setFailOnConflict(true) dirCacheCheckout.checkout() - val newHead: ObjectId val mergeStatus: MergeStatus if (squash) { - newHead = headId mergeStatus = MergeStatus.FAST_FORWARD_SQUASHED val squashedCommits = RevWalkUtils.find(revWalk, srcCommit, headCommit) repository.writeSquashCommitMsg(SquashMessageFormatter().format(squashedCommits, head)) } else { updateHead(refLogMessage, srcCommit, headId, repository) - newHead = srcCommit mergeStatus = MergeStatus.FAST_FORWARD } - return MergeResultEx(newHead, mergeStatus, arrayOf(headCommit, srcCommit), ImmutableUpdateResult(dirCacheCheckout.getUpdated().keySet(), dirCacheCheckout.getRemoved())) + return MergeResultEx(mergeStatus, arrayOf(headCommit, srcCommit), ImmutableUpdateResult(dirCacheCheckout.getUpdated().keySet(), dirCacheCheckout.getRemoved())) } else { if (fastForwardMode == FastForwardMode.FF_ONLY) { - return MergeResultEx(headCommit, MergeStatus.ABORTED, arrayOf(headCommit, srcCommit), EMPTY_UPDATE_RESULT) + return MergeResultEx(MergeStatus.ABORTED, arrayOf(headCommit, srcCommit), EMPTY_UPDATE_RESULT) } val mergeMessage: String @@ -257,7 +236,6 @@ open class Pull(val manager: GitRepositoryManager, val indicator: ProgressIndica result = ImmutableUpdateResult(dirCacheCheckout.getUpdated().keySet(), dirCacheCheckout.getRemoved()) } - var newHeadId: ObjectId? = null var mergeStatus: MergeResult.MergeStatus? = null if (!commit && squash) { mergeStatus = MergeResult.MergeStatus.MERGED_SQUASHED_NOT_COMMITTED @@ -266,23 +244,22 @@ open class Pull(val manager: GitRepositoryManager, val indicator: ProgressIndica mergeStatus = MergeResult.MergeStatus.MERGED_NOT_COMMITTED } if (commit && !squash) { - newHeadId = repository.commit(commitMessage, refLogMessage.toString()).getId() + repository.commit(commitMessage, refLogMessage.toString()).getId() mergeStatus = MergeResult.MergeStatus.MERGED } if (commit && squash) { - newHeadId = headCommit.getId() mergeStatus = MergeResult.MergeStatus.MERGED_SQUASHED } - return MergeResultEx(newHeadId, mergeStatus!!, arrayOf(headCommit.getId(), srcCommit.getId()), result!!) + return MergeResultEx(mergeStatus!!, arrayOf(headCommit.getId(), srcCommit.getId()), result!!) } else if (failingPaths == null) { repository.writeMergeCommitMsg(MergeMessageFormatter().formatWithConflicts(mergeMessage, unmergedPaths)) - return MergeResultEx(null, MergeResult.MergeStatus.CONFLICTING, arrayOf(headCommit.getId(), srcCommit.getId()), result!!, lowLevelResults) + return MergeResultEx(MergeResult.MergeStatus.CONFLICTING, arrayOf(headCommit.getId(), srcCommit.getId()), result!!, lowLevelResults) } else { repository.writeMergeCommitMsg(null) repository.writeMergeHeads(null) - return MergeResultEx(null, MergeResult.MergeStatus.FAILED, arrayOf(headCommit.getId(), srcCommit.getId()), result!!, lowLevelResults) + return MergeResultEx(MergeResult.MergeStatus.FAILED, arrayOf(headCommit.getId(), srcCommit.getId()), result!!, lowLevelResults) } } } @@ -295,7 +272,7 @@ open class Pull(val manager: GitRepositoryManager, val indicator: ProgressIndica } } -class MergeResultEx(val newHead: ObjectId?, val mergeStatus: MergeStatus, val mergedCommits: Array, val result: ImmutableUpdateResult, val conflicts: Map>? = null) +class MergeResultEx(val mergeStatus: MergeStatus, val mergedCommits: Array, val result: ImmutableUpdateResult, val conflicts: Map>? = null) private fun updateHead(refLogMessage: StringBuilder, newHeadId: ObjectId, oldHeadID: ObjectId, repository: Repository) { val refUpdate = repository.updateRef(Constants.HEAD) @@ -340,7 +317,33 @@ private fun resolveConflicts(mergeProvider: JGitMergeProvider, unresolv } } + // merge commit template will be used, so, we don't have to specify commit message explicitly repository.commit() return mergedFiles } + +private fun Repository.fixAndGetState(): RepositoryState { + var state = getRepositoryState() + if (state == RepositoryState.MERGING) { + resolveUnmergedConflicts(this) + // compute new state + state = getRepositoryState() + } + return state +} + +private fun resolveUnmergedConflicts(repository: Repository) { + val conflicts = LinkedHashMap>() + repository.newObjectReader().use { reader -> + val dirCache = repository.readDirCache() + for (i in 0..(dirCache.getEntryCount() - 1)) { + val entry = dirCache.getEntry(i) + if (!entry.isMerged()) { + conflicts.getOrPut(entry.getPathString(), { arrayOfNulls(3) })[entry.getStage() - 1] = reader.open(entry.getObjectId(), Constants.OBJ_BLOB).getCachedBytes() + } + } + } + + resolveConflicts(JGitMergeProvider(repository, conflicts, { path, index -> get(path)!!.get(index) }), conflictsToVirtualFiles(conflicts), repository) +} \ No newline at end of file diff --git a/plugins/settings-repository/src/sync.kt b/plugins/settings-repository/src/sync.kt index d677b477240e..b85604a5915c 100644 --- a/plugins/settings-repository/src/sync.kt +++ b/plugins/settings-repository/src/sync.kt @@ -55,7 +55,7 @@ class SyncManager(private val icsManager: IcsManager, private val autoSyncManage if (localRepositoryInitializer == null) { try { // we commit before even if sync "RESET_TO_THEIRS" — preserve history and ability to undo - repositoryManager.commitIfCan(indicator) + repositoryManager.commit(indicator, syncType) // well, we cannot commit? No problem, upcoming action must do something smart and solve the situation } catch (e: ProcessCanceledException) { From f31284fab003d64381db96ad7cd2213b31a6c53e Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 25 Aug 2015 16:12:36 +0200 Subject: [PATCH 046/246] since-build --- plugins/settings-repository/resources/META-INF/plugin.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/settings-repository/resources/META-INF/plugin.xml b/plugins/settings-repository/resources/META-INF/plugin.xml index 40934755386f..a118c1a82c85 100644 --- a/plugins/settings-repository/resources/META-INF/plugin.xml +++ b/plugins/settings-repository/resources/META-INF/plugin.xml @@ -6,7 +6,7 @@

Synchronization is performed automatically after successful completion of "Update Project" or "Push" actions. Also you can do sync using VCS -> Sync Settings.

See project page for more info.

]]> 999.999 - + JetBrains From f59bfa02db51e3a9a83139cebaa3e9b8d697c196 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 25 Aug 2015 16:17:34 +0200 Subject: [PATCH 047/246] ICS: saveContent -> write --- .../src/SchemeManagerImpl.kt | 2 +- .../src/XmlElementStorage.kt | 2 +- .../testSrc/ApplicationStoreTest.kt | 2 +- .../testSrc/MockStreamProvider.kt | 2 +- .../components/impl/stores/StreamProvider.kt | 2 +- plugins/settings-repository/src/IcsManager.kt | 2 +- .../settings-repository/testSrc/GitTest.kt | 24 +++++++------------ .../settings-repository/testSrc/LoadTest.kt | 10 ++++---- .../settings-repository/testSrc/TestCase.kt | 9 +++++-- 9 files changed, 27 insertions(+), 28 deletions(-) diff --git a/platform/configuration-store-impl/src/SchemeManagerImpl.kt b/platform/configuration-store-impl/src/SchemeManagerImpl.kt index de2a05a77ba2..48d0ca305a14 100644 --- a/platform/configuration-store-impl/src/SchemeManagerImpl.kt +++ b/platform/configuration-store-impl/src/SchemeManagerImpl.kt @@ -583,7 +583,7 @@ public class SchemeManagerImpl(private val if (renamed) { externalInfo!!.scheduleDelete() } - provider!!.saveContent(providerPath, byteOut.getInternalBuffer(), byteOut.size(), roamingType) + provider!!.write(providerPath, byteOut.getInternalBuffer(), byteOut.size(), roamingType) } if (externalInfo == null) { diff --git a/platform/configuration-store-impl/src/XmlElementStorage.kt b/platform/configuration-store-impl/src/XmlElementStorage.kt index 1fd9fcf666cc..5b0ee7f5e55a 100644 --- a/platform/configuration-store-impl/src/XmlElementStorage.kt +++ b/platform/configuration-store-impl/src/XmlElementStorage.kt @@ -139,7 +139,7 @@ abstract class XmlElementStorage protected constructor(protected val fileSpec: S else { // we should use standard line-separator (\n) - stream provider can share file content on any OS val content = StorageUtil.writeToBytes(element, "\n") - provider.saveContent(storage.fileSpec, content.getInternalBuffer(), content.size(), storage.roamingType) + provider.write(storage.fileSpec, content.getInternalBuffer(), content.size(), storage.roamingType) } } else { diff --git a/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt b/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt index b2f391c9404a..a489077d5961 100644 --- a/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt +++ b/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt @@ -111,7 +111,7 @@ class ApplicationStoreTest { private class MyStreamProvider : StreamProvider { public val data: MutableMap> = THashMap() - override fun saveContent(fileSpec: String, content: ByteArray, size: Int, roamingType: RoamingType) { + override fun write(fileSpec: String, content: ByteArray, size: Int, roamingType: RoamingType) { getMap(roamingType).put(fileSpec, String(content, 0, size, CharsetToolkit.UTF8_CHARSET)) } diff --git a/platform/configuration-store-impl/testSrc/MockStreamProvider.kt b/platform/configuration-store-impl/testSrc/MockStreamProvider.kt index d383107dd0fc..cd9442a1c766 100644 --- a/platform/configuration-store-impl/testSrc/MockStreamProvider.kt +++ b/platform/configuration-store-impl/testSrc/MockStreamProvider.kt @@ -9,7 +9,7 @@ import java.io.FileInputStream import java.io.InputStream class MockStreamProvider(private val myBaseDir: File) : StreamProvider { - override fun saveContent(fileSpec: String, content: ByteArray, size: Int, roamingType: RoamingType) { + override fun write(fileSpec: String, content: ByteArray, size: Int, roamingType: RoamingType) { FileUtil.writeToFile(File(myBaseDir, fileSpec), content, 0, size) } diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.kt b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.kt index 6767af9599cb..d3c25919c3b4 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.kt +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.kt @@ -30,7 +30,7 @@ public interface StreamProvider { * @param content bytes of content, size of array is not actual size of data, you must use `size` * @param size actual size of data */ - public fun saveContent(fileSpec: String, content: ByteArray, size: Int, roamingType: RoamingType) + public fun write(fileSpec: String, content: ByteArray, size: Int, roamingType: RoamingType) public fun loadContent(fileSpec: String, roamingType: RoamingType): InputStream? diff --git a/plugins/settings-repository/src/IcsManager.kt b/plugins/settings-repository/src/IcsManager.kt index 27ff98ad2fb9..a7b504ccef36 100644 --- a/plugins/settings-repository/src/IcsManager.kt +++ b/plugins/settings-repository/src/IcsManager.kt @@ -211,7 +211,7 @@ class IcsManager(dir: File) { repositoryManager.processChildren(fullPath, filter, { name, input -> processor(name, input, false) }) } - override fun saveContent(fileSpec: String, content: ByteArray, size: Int, roamingType: RoamingType) { + override fun write(fileSpec: String, content: ByteArray, size: Int, roamingType: RoamingType) { if (syncManager.writeAndDeleteProhibited) { throw IllegalStateException("Save is prohibited now") } diff --git a/plugins/settings-repository/testSrc/GitTest.kt b/plugins/settings-repository/testSrc/GitTest.kt index b9f307f7bfd3..588fa1fd5d08 100644 --- a/plugins/settings-repository/testSrc/GitTest.kt +++ b/plugins/settings-repository/testSrc/GitTest.kt @@ -17,7 +17,6 @@ package org.jetbrains.settingsRepository.test import com.intellij.mock.MockVirtualFileSystem import com.intellij.openapi.components.RoamingType -import com.intellij.openapi.components.impl.stores.StreamProvider import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.vcs.merge.MergeSession import com.intellij.openapi.vfs.CharsetToolkit @@ -84,7 +83,7 @@ class GitTest : TestCase() { private fun addAndCommit(path: String): FileInfo { val data = FileUtil.loadFileBytes(File(testDataPath, PathUtilRt.getFileName(path))) - provider.save(path, data) + provider.write(path, data) repositoryManager.commit() return FileInfo(path, data) } @@ -92,7 +91,7 @@ class GitTest : TestCase() { Test fun add() { val data = FileUtil.loadFileBytes(File(testDataPath, "remote.xml")) val addedFile = "remote.xml" - provider.save(addedFile, data) + provider.write(addedFile, data) val diff = repository.computeIndexDiff() assertThat(diff.diff()).isTrue() @@ -109,8 +108,8 @@ class GitTest : TestCase() { val data2 = FileUtil.loadFileBytes(File(testDataPath, "local.xml")) val addedFile = "remote.xml" val addedFile2 = "local.xml" - provider.save(addedFile, data) - provider.save(addedFile2, data2) + provider.write(addedFile, data) + provider.write(addedFile2, data2) val diff = repository.computeIndexDiff() assertThat(diff.diff()).isTrue() @@ -127,7 +126,7 @@ class GitTest : TestCase() { fun delete(data: ByteArray, directory: Boolean) { val dir = "dir" val fullFileSpec = "$dir/$addedFile" - provider.save(fullFileSpec, data) + provider.write(fullFileSpec, data) provider.delete(if (directory) dir else fullFileSpec, RoamingType.PER_USER) val diff = repository.computeIndexDiff() @@ -272,7 +271,7 @@ class GitTest : TestCase() { createLocalRepository(null) val data = AM.MARKER_ACCEPT_MY - provider.save("remote.xml", data) + provider.write("remote.xml", data) sync(SyncType.MERGE) @@ -286,7 +285,7 @@ class GitTest : TestCase() { sync(SyncType.MERGE) val data = AM.MARKER_ACCEPT_THEIRS - provider.save("remote.xml", data) + provider.write("remote.xml", data) repositoryManager.commit() remoteRepository.deletePath("remote.xml") @@ -317,7 +316,7 @@ class GitTest : TestCase() { Test fun `commit if unmerged`() { createLocalRepository(null) - provider.saveContent("remote.xml", "") + provider.write("remote.xml", "") try { sync(SyncType.MERGE) @@ -379,7 +378,7 @@ class GitTest : TestCase() { val path = "local.xml" val data = FileUtil.loadFileBytes(File(testDataPath, PathUtilRt.getFileName(path))) - provider.save(path, data) + provider.write(path, data) sync(syncType) @@ -406,9 +405,4 @@ class GitTest : TestCase() { private fun sync(syncType: SyncType) { icsManager.sync(syncType, fixtureManager.projectFixture.getProject()) } -} - -fun StreamProvider.saveContent(fileSpec: String, content: String) { - val data = content.toByteArray() - saveContent(fileSpec, data, data.size(), RoamingType.PER_USER) } \ No newline at end of file diff --git a/plugins/settings-repository/testSrc/LoadTest.kt b/plugins/settings-repository/testSrc/LoadTest.kt index 67dedd53c9d7..5fc5fc29092a 100644 --- a/plugins/settings-repository/testSrc/LoadTest.kt +++ b/plugins/settings-repository/testSrc/LoadTest.kt @@ -37,7 +37,7 @@ class LoadTest : TestCase() { public Test fun `load scheme`() { val localScheme = TestScheme("local") val data = localScheme.serialize().toByteArray() - provider.save("$dirPath/local.xml", data) + provider.write("$dirPath/local.xml", data) val schemesManager = createSchemeManager(dirPath) schemesManager.loadSchemes() @@ -47,8 +47,8 @@ class LoadTest : TestCase() { public Test fun `load scheme with the same names`() { val localScheme = TestScheme("local") val data = localScheme.serialize().toByteArray() - provider.save("$dirPath/local.xml", data) - provider.save("$dirPath/local2.xml", data) + provider.write("$dirPath/local.xml", data) + provider.write("$dirPath/local2.xml", data) val schemesManager = createSchemeManager(dirPath) schemesManager.loadSchemes() @@ -58,7 +58,7 @@ class LoadTest : TestCase() { public Test fun `load scheme from repo and read-only repo`() { val localScheme = TestScheme("local") - provider.save("$dirPath/local.xml", localScheme.serialize().toByteArray()) + provider.write("$dirPath/local.xml", localScheme.serialize().toByteArray()) val remoteScheme = TestScheme("remote") val remoteRepository = tempDirManager.createRepository() @@ -79,7 +79,7 @@ class LoadTest : TestCase() { val schemeName = "Emacs" val localScheme = TestScheme(schemeName, "local") - provider.save("$dirPath/$schemeName.xml", localScheme.serialize().toByteArray()) + provider.write("$dirPath/$schemeName.xml", localScheme.serialize().toByteArray()) val remoteScheme = TestScheme(schemeName, "remote") val remoteRepository = tempDirManager.createRepository("remote") diff --git a/plugins/settings-repository/testSrc/TestCase.kt b/plugins/settings-repository/testSrc/TestCase.kt index 115ec54891b7..47ca047e0544 100644 --- a/plugins/settings-repository/testSrc/TestCase.kt +++ b/plugins/settings-repository/testSrc/TestCase.kt @@ -33,8 +33,13 @@ import kotlin.properties.Delegates val testDataPath: String = "${PlatformTestUtil.getCommunityPath()}/plugins/settings-repository/testData" -fun StreamProvider.save(path: String, data: ByteArray) { - saveContent(path, data, data.size(), RoamingType.PER_USER) +fun StreamProvider.write(path: String, data: ByteArray) { + write(path, data, data.size(), RoamingType.PER_USER) +} + +fun StreamProvider.write(fileSpec: String, content: String) { + val data = content.toByteArray() + write(fileSpec, data, data.size(), RoamingType.PER_USER) } fun Repository.add(data: ByteArray, path: String): Repository { From ecd7f4217f64293afc29075b934d9994dfc3fbef Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 25 Aug 2015 16:24:43 +0200 Subject: [PATCH 048/246] ICS: loadContent -> read, remove unused listSubFiles --- .../src/XmlElementStorage.kt | 2 +- .../testSrc/ApplicationStoreTest.kt | 5 +++- .../testSrc/MockStreamProvider.kt | 20 ++++++++++++-- .../components/impl/stores/StreamProvider.kt | 27 ++----------------- .../src/BaseRepositoryManager.kt | 8 ------ plugins/settings-repository/src/IcsManager.kt | 4 +-- .../src/RepositoryManager.kt | 2 -- 7 files changed, 26 insertions(+), 42 deletions(-) diff --git a/platform/configuration-store-impl/src/XmlElementStorage.kt b/platform/configuration-store-impl/src/XmlElementStorage.kt index 5b0ee7f5e55a..245e47d6f06c 100644 --- a/platform/configuration-store-impl/src/XmlElementStorage.kt +++ b/platform/configuration-store-impl/src/XmlElementStorage.kt @@ -63,7 +63,7 @@ abstract class XmlElementStorage protected constructor(protected val fileSpec: S protected open fun dataLoadedFromProvider(element: Element?) { } - private fun loadDataFromProvider() = JDOMUtil.load(provider!!.loadContent(fileSpec, roamingType)) + private fun loadDataFromProvider() = JDOMUtil.load(provider!!.read(fileSpec, roamingType)) private fun loadState(element: Element): StateMap { beforeElementLoaded(element) diff --git a/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt b/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt index a489077d5961..5827dc8c2d33 100644 --- a/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt +++ b/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt @@ -109,6 +109,9 @@ class ApplicationStoreTest { private fun writeConfig(fileName: String, Language("XML") data: String) = testAppConfig.writeChild(fileName, data) private class MyStreamProvider : StreamProvider { + override fun processChildren(path: String, roamingType: RoamingType, filter: (String) -> Boolean, processor: (String, InputStream, Boolean) -> Boolean) { + } + public val data: MutableMap> = THashMap() override fun write(fileSpec: String, content: ByteArray, size: Int, roamingType: RoamingType) { @@ -124,7 +127,7 @@ class ApplicationStoreTest { return map } - override fun loadContent(fileSpec: String, roamingType: RoamingType): InputStream? { + override fun read(fileSpec: String, roamingType: RoamingType): InputStream? { val data = getMap(roamingType).get(fileSpec) ?: return null return ByteArrayInputStream(data.toByteArray()) } diff --git a/platform/configuration-store-impl/testSrc/MockStreamProvider.kt b/platform/configuration-store-impl/testSrc/MockStreamProvider.kt index cd9442a1c766..49064a738e3d 100644 --- a/platform/configuration-store-impl/testSrc/MockStreamProvider.kt +++ b/platform/configuration-store-impl/testSrc/MockStreamProvider.kt @@ -13,13 +13,13 @@ class MockStreamProvider(private val myBaseDir: File) : StreamProvider { FileUtil.writeToFile(File(myBaseDir, fileSpec), content, 0, size) } - override fun loadContent(fileSpec: String, roamingType: RoamingType): InputStream? { + override fun read(fileSpec: String, roamingType: RoamingType): InputStream? { val file = File(myBaseDir, fileSpec) //noinspection IOResourceOpenedButNotSafelyClosed return if (file.exists()) FileInputStream(file) else null } - override fun listSubFiles(fileSpec: String, roamingType: RoamingType): Collection { + private fun listSubFiles(fileSpec: String, roamingType: RoamingType): Collection { if (roamingType !== RoamingType.PER_USER) { return emptyList() } @@ -32,6 +32,22 @@ class MockStreamProvider(private val myBaseDir: File) : StreamProvider { return names } + /** + * You must close passed input stream. + */ + override fun processChildren(path: String, roamingType: RoamingType, filter: (name: String) -> Boolean, processor: (name: String, input: InputStream, readOnly: Boolean) -> Boolean) { + for (name in listSubFiles(path, roamingType)) { + if (!filter(name)) { + continue + } + + val input = read("$path/$name", roamingType) + if (input != null && !processor(name, input, false)) { + break + } + } + } + override fun delete(fileSpec: String, roamingType: RoamingType) { FileUtil.delete(File(myBaseDir, fileSpec)) } diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.kt b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.kt index d3c25919c3b4..ff2a1206c20f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.kt +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.kt @@ -16,7 +16,6 @@ package com.intellij.openapi.components.impl.stores import com.intellij.openapi.components.RoamingType -import java.io.IOException import java.io.InputStream public interface StreamProvider { @@ -32,34 +31,12 @@ public interface StreamProvider { */ public fun write(fileSpec: String, content: ByteArray, size: Int, roamingType: RoamingType) - public fun loadContent(fileSpec: String, roamingType: RoamingType): InputStream? - - public open fun listSubFiles(fileSpec: String, roamingType: RoamingType): Collection = emptyList() + public fun read(fileSpec: String, roamingType: RoamingType): InputStream? /** * You must close passed input stream. */ - public open fun processChildren(path: String, roamingType: RoamingType, filter: (name: String) -> Boolean, processor: (name: String, input: InputStream, readOnly: Boolean) -> Boolean) { - for (name in listSubFiles(path, roamingType)) { - if (!filter(name)) { - continue - } - - val input: InputStream? - try { - input = loadContent("$path/$name", roamingType) - } - catch (e: IOException) { - StorageUtil.LOG.error(e) - continue - } - - - if (input != null && !processor(name, input, false)) { - break - } - } - } + public fun processChildren(path: String, roamingType: RoamingType, filter: (name: String) -> Boolean, processor: (name: String, input: InputStream, readOnly: Boolean) -> Boolean) /** * Delete file or directory diff --git a/plugins/settings-repository/src/BaseRepositoryManager.kt b/plugins/settings-repository/src/BaseRepositoryManager.kt index 1112919d9139..c1549164563e 100644 --- a/plugins/settings-repository/src/BaseRepositoryManager.kt +++ b/plugins/settings-repository/src/BaseRepositoryManager.kt @@ -37,14 +37,6 @@ import kotlin.concurrent.write public abstract class BaseRepositoryManager(protected val dir: File) : RepositoryManager { protected val lock: ReentrantReadWriteLock = ReentrantReadWriteLock() - override fun listSubFileNames(path: String): Collection { - val files = File(dir, path).list() - if (files == null || files.size() == 0) { - return listOf() - } - return listOf(*files) - } - override fun processChildren(path: String, filter: (name: String) -> Boolean, processor: (name: String, inputStream: InputStream) -> Boolean) { var files: Array? = null lock.read { diff --git a/plugins/settings-repository/src/IcsManager.kt b/plugins/settings-repository/src/IcsManager.kt index a7b504ccef36..69280ba098ce 100644 --- a/plugins/settings-repository/src/IcsManager.kt +++ b/plugins/settings-repository/src/IcsManager.kt @@ -198,8 +198,6 @@ class IcsManager(dir: File) { override val enabled: Boolean get() = repositoryActive - override fun listSubFiles(fileSpec: String, roamingType: RoamingType): MutableCollection = repositoryManager.listSubFileNames(buildPath(fileSpec, roamingType, null)) as MutableCollection - override fun processChildren(path: String, roamingType: RoamingType, filter: (name: String) -> Boolean, processor: (name: String, input: InputStream, readOnly: Boolean) -> Boolean) { val fullPath = buildPath(path, roamingType, null) @@ -229,7 +227,7 @@ class IcsManager(dir: File) { protected open fun isAutoCommit(fileSpec: String, roamingType: RoamingType): Boolean = true - override fun loadContent(fileSpec: String, roamingType: RoamingType): InputStream? { + override fun read(fileSpec: String, roamingType: RoamingType): InputStream? { return repositoryManager.read(buildPath(fileSpec, roamingType, projectId)) } diff --git a/plugins/settings-repository/src/RepositoryManager.kt b/plugins/settings-repository/src/RepositoryManager.kt index 1644e60a372b..0b38c271fc58 100644 --- a/plugins/settings-repository/src/RepositoryManager.kt +++ b/plugins/settings-repository/src/RepositoryManager.kt @@ -45,8 +45,6 @@ public interface RepositoryManager { public fun delete(path: String) - public fun listSubFileNames(path: String): Collection - public fun processChildren(path: String, filter: (name: String) -> Boolean, processor: (name: String, inputStream: InputStream) -> Boolean) /** From 6835e9f8d6170ba3a58321df0ffd5f6d8ad884d3 Mon Sep 17 00:00:00 2001 From: "liana.bakradze" Date: Tue, 25 Aug 2015 17:38:36 +0300 Subject: [PATCH 049/246] EDU-406 Assertion failed in Study Editor --- .../edu/learning/editor/StudyFileEditorProvider.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/editor/StudyFileEditorProvider.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/editor/StudyFileEditorProvider.java index 1c9baab95769..77e6f10693f8 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/editor/StudyFileEditorProvider.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/editor/StudyFileEditorProvider.java @@ -13,11 +13,6 @@ import com.jetbrains.edu.learning.StudyUtils; import org.jdom.Element; import org.jetbrains.annotations.NotNull; -/** - * User: lia - * Date: 10.05.14 - * Time: 12:45 - */ class StudyFileEditorProvider implements FileEditorProvider, DumbAware { static final private String EDITOR_TYPE_ID = "StudyEditor"; final private FileEditorProvider defaultTextEditorProvider = TextEditorProvider.getInstance(); @@ -25,7 +20,7 @@ class StudyFileEditorProvider implements FileEditorProvider, DumbAware { @Override public boolean accept(@NotNull Project project, @NotNull VirtualFile file) { TaskFile taskFile = StudyUtils.getTaskFile(project, file); - return taskFile != null && !taskFile.isUserCreated(); + return taskFile != null && !taskFile.isUserCreated() && TextEditorProvider.isTextFile(file); } @NotNull From 3b04b8a71c29f552ac7a4414115db078a72c353a Mon Sep 17 00:00:00 2001 From: Alexander Zolotov Date: Tue, 25 Aug 2015 17:43:09 +0300 Subject: [PATCH 050/246] Simplify retrieving messageBus --- .../service/project/autoimport/ExternalSystemAutoImporter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/autoimport/ExternalSystemAutoImporter.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/autoimport/ExternalSystemAutoImporter.java index 008f66403e7d..e120cf6a10af 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/autoimport/ExternalSystemAutoImporter.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/autoimport/ExternalSystemAutoImporter.java @@ -155,7 +155,7 @@ public class ExternalSystemAutoImporter implements BulkFileListener, DocumentLis entries ); final MessageBus messageBus = project.getMessageBus(); - messageBus.connect(project).subscribe(VirtualFileManager.VFS_CHANGES, autoImporter); + messageBus.connect().subscribe(VirtualFileManager.VFS_CHANGES, autoImporter); EditorFactory.getInstance().getEventMulticaster().addDocumentListener(autoImporter, project); } From 54e82b7a2ba3ae2ad1ddbec78f00d85a1a902bbd Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 25 Aug 2015 16:41:42 +0200 Subject: [PATCH 051/246] cleanup --- .../com/intellij/testFramework/FixtureRule.kt | 31 ------------------- plugins/settings-repository/src/IcsManager.kt | 2 +- plugins/settings-repository/src/sync.kt | 2 +- .../settings-repository/testSrc/GitTest.kt | 10 ++++-- .../testSrc/{TestCase.kt => IcsTestCase.kt} | 10 ++---- .../settings-repository/testSrc/LoadTest.kt | 16 +++++++--- 6 files changed, 23 insertions(+), 48 deletions(-) rename plugins/settings-repository/testSrc/{TestCase.kt => IcsTestCase.kt} (88%) diff --git a/platform/testFramework/testSrc/com/intellij/testFramework/FixtureRule.kt b/platform/testFramework/testSrc/com/intellij/testFramework/FixtureRule.kt index ea4b8f4016f5..492a4954872d 100644 --- a/platform/testFramework/testSrc/com/intellij/testFramework/FixtureRule.kt +++ b/platform/testFramework/testSrc/com/intellij/testFramework/FixtureRule.kt @@ -33,8 +33,6 @@ import com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS import com.intellij.openapi.vfs.newvfs.persistent.PersistentFSImpl import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager -import com.intellij.testFramework.fixtures.IdeaProjectTestFixture -import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory import com.intellij.util.SmartList import com.intellij.util.lang.CompoundRuntimeException import org.junit.rules.ExternalResource @@ -148,35 +146,6 @@ public fun runInEdtAndWait(runnable: () -> Unit) { EdtTestUtil.runInEdtAndWait(runnable) } -public open class FixtureRule() : ExternalResource() { - companion object { - init { - Logger.setFactory(javaClass()) - } - } - - protected var _projectFixture: IdeaProjectTestFixture? = null - - public val projectFixture: IdeaProjectTestFixture - get() = _projectFixture!! - - open fun createBuilder() = IdeaTestFixtureFactory.getFixtureFactory().createLightFixtureBuilder() - - override final fun before() { - val builder = createBuilder() - if (_projectFixture == null) { - _projectFixture = builder.getFixture() - } - - TestRunnerUtil.replaceIdeEventQueueSafely() - runInEdtAndWait { projectFixture.setUp() } - } - - override final fun after() { - runInEdtAndWait { projectFixture.tearDown() } - } -} - public class RuleChain(vararg val rules: TestRule) : TestRule { override fun apply(base: Statement, description: Description): Statement { var statement = base diff --git a/plugins/settings-repository/src/IcsManager.kt b/plugins/settings-repository/src/IcsManager.kt index 69280ba098ce..1d0eea232d42 100644 --- a/plugins/settings-repository/src/IcsManager.kt +++ b/plugins/settings-repository/src/IcsManager.kt @@ -151,7 +151,7 @@ class IcsManager(dir: File) { } } - fun sync(syncType: SyncType, project: Project?, localRepositoryInitializer: (() -> Unit)? = null) = syncManager.sync(syncType, project, localRepositoryInitializer) + fun sync(syncType: SyncType, project: Project? = null, localRepositoryInitializer: (() -> Unit)? = null) = syncManager.sync(syncType, project, localRepositoryInitializer) private fun cancelAndDisableAutoCommit() { if (autoCommitEnabled) { diff --git a/plugins/settings-repository/src/sync.kt b/plugins/settings-repository/src/sync.kt index b85604a5915c..f73b6f6e91fe 100644 --- a/plugins/settings-repository/src/sync.kt +++ b/plugins/settings-repository/src/sync.kt @@ -37,7 +37,7 @@ class SyncManager(private val icsManager: IcsManager, private val autoSyncManage volatile var writeAndDeleteProhibited = false private set - public fun sync(syncType: SyncType, project: Project?, localRepositoryInitializer: (() -> Unit)? = null): UpdateResult? { + public fun sync(syncType: SyncType, project: Project? = null, localRepositoryInitializer: (() -> Unit)? = null): UpdateResult? { var exception: Throwable? = null var restartApplication = false var updateResult: UpdateResult? = null diff --git a/plugins/settings-repository/testSrc/GitTest.kt b/plugins/settings-repository/testSrc/GitTest.kt index 588fa1fd5d08..0046a0af2528 100644 --- a/plugins/settings-repository/testSrc/GitTest.kt +++ b/plugins/settings-repository/testSrc/GitTest.kt @@ -21,6 +21,7 @@ import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.vcs.merge.MergeSession import com.intellij.openapi.vfs.CharsetToolkit import com.intellij.openapi.vfs.VirtualFile +import com.intellij.testFramework.ProjectRule import com.intellij.testFramework.path import com.intellij.util.PathUtilRt import org.assertj.core.api.Assertions.assertThat @@ -37,6 +38,7 @@ import org.jetbrains.settingsRepository.git.GitRepositoryManager import org.jetbrains.settingsRepository.git.commit import org.jetbrains.settingsRepository.git.computeIndexDiff import org.jetbrains.settingsRepository.git.resetHard +import org.junit.ClassRule import org.junit.Test import java.io.File import java.util.Arrays @@ -48,7 +50,11 @@ object AM { val MARKER_ACCEPT_THEIRS: ByteArray = "__accept theirs__".toByteArray() } -class GitTest : TestCase() { +class GitTest : IcsTestCase() { + companion object { + @ClassRule val projectRule = ProjectRule() + } + private val repositoryManager: GitRepositoryManager get() = icsManager.repositoryManager as GitRepositoryManager @@ -403,6 +409,6 @@ class GitTest : TestCase() { } private fun sync(syncType: SyncType) { - icsManager.sync(syncType, fixtureManager.projectFixture.getProject()) + icsManager.sync(syncType) } } \ No newline at end of file diff --git a/plugins/settings-repository/testSrc/TestCase.kt b/plugins/settings-repository/testSrc/IcsTestCase.kt similarity index 88% rename from plugins/settings-repository/testSrc/TestCase.kt rename to plugins/settings-repository/testSrc/IcsTestCase.kt index 47ca047e0544..6c2d67dcc9c9 100644 --- a/plugins/settings-repository/testSrc/TestCase.kt +++ b/plugins/settings-repository/testSrc/IcsTestCase.kt @@ -18,7 +18,6 @@ package org.jetbrains.settingsRepository.test import com.intellij.openapi.components.RoamingType import com.intellij.openapi.components.impl.stores.StreamProvider import com.intellij.openapi.util.io.FileUtil -import com.intellij.testFramework.FixtureRule import com.intellij.testFramework.PlatformTestUtil import com.intellij.testFramework.TemporaryDirectory import org.eclipse.jgit.lib.Repository @@ -27,7 +26,6 @@ import org.jetbrains.jgit.dirCache.edit import org.jetbrains.settingsRepository.IcsManager import org.jetbrains.settingsRepository.git import org.junit.Rule -import org.junit.rules.TestRule import java.io.File import kotlin.properties.Delegates @@ -48,13 +46,9 @@ fun Repository.add(data: ByteArray, path: String): Repository { return this } -abstract class TestCase { - val fixtureManager = FixtureRule() - +abstract class IcsTestCase { val tempDirManager = TemporaryDirectory() - public Rule fun getTemporaryFolder(): TemporaryDirectory = tempDirManager - - public Rule fun getFixtureRule(): TestRule = fixtureManager + @Rule fun getTemporaryFolder() = tempDirManager val icsManager by Delegates.lazy { val icsManager = IcsManager(tempDirManager.newDirectory()) diff --git a/plugins/settings-repository/testSrc/LoadTest.kt b/plugins/settings-repository/testSrc/LoadTest.kt index 5fc5fc29092a..7851a3f56235 100644 --- a/plugins/settings-repository/testSrc/LoadTest.kt +++ b/plugins/settings-repository/testSrc/LoadTest.kt @@ -19,6 +19,7 @@ import com.intellij.configurationStore.SchemeManagerImpl import com.intellij.configurationStore.TestScheme import com.intellij.configurationStore.TestSchemesProcessor import com.intellij.openapi.components.RoamingType +import com.intellij.testFramework.ProjectRule import com.intellij.util.xmlb.serialize import com.intellij.util.xmlb.toByteArray import org.assertj.core.api.Assertions.assertThat @@ -26,15 +27,20 @@ import org.eclipse.jgit.lib.Repository import org.jetbrains.settingsRepository.ReadonlySource import org.jetbrains.settingsRepository.git.cloneBare import org.jetbrains.settingsRepository.git.commit +import org.junit.ClassRule import org.junit.Test import java.io.File -class LoadTest : TestCase() { +class LoadTest : IcsTestCase() { + companion object { + @ClassRule val projectRule = ProjectRule() + } + private val dirPath = "\$ROOT_CONFIG$/keymaps" private fun createSchemeManager(dirPath: String) = SchemeManagerImpl(dirPath, TestSchemesProcessor(), RoamingType.PER_USER, provider, tempDirManager.newDirectory("schemes")) - public Test fun `load scheme`() { + @Test fun `load scheme`() { val localScheme = TestScheme("local") val data = localScheme.serialize().toByteArray() provider.write("$dirPath/local.xml", data) @@ -44,7 +50,7 @@ class LoadTest : TestCase() { assertThat(schemesManager.getAllSchemes()).containsOnly(localScheme) } - public Test fun `load scheme with the same names`() { + @Test fun `load scheme with the same names`() { val localScheme = TestScheme("local") val data = localScheme.serialize().toByteArray() provider.write("$dirPath/local.xml", data) @@ -55,7 +61,7 @@ class LoadTest : TestCase() { assertThat(schemesManager.getAllSchemes()).containsOnly(localScheme) } - public Test fun `load scheme from repo and read-only repo`() { + @Test fun `load scheme from repo and read-only repo`() { val localScheme = TestScheme("local") provider.write("$dirPath/local.xml", localScheme.serialize().toByteArray()) @@ -75,7 +81,7 @@ class LoadTest : TestCase() { } } - public Test fun `scheme overrides read-only`() { + @Test fun `scheme overrides read-only`() { val schemeName = "Emacs" val localScheme = TestScheme(schemeName, "local") From f22e895adac03f011afbd1a80d9ecd448f865ed1 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 25 Aug 2015 16:46:39 +0200 Subject: [PATCH 052/246] cleanup --- platform/configuration-store-impl/src/SchemeManagerImpl.kt | 5 ++++- .../openapi/components/impl/stores/StorageUtil.java | 6 ------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/platform/configuration-store-impl/src/SchemeManagerImpl.kt b/platform/configuration-store-impl/src/SchemeManagerImpl.kt index 48d0ca305a14..317046c04eb6 100644 --- a/platform/configuration-store-impl/src/SchemeManagerImpl.kt +++ b/platform/configuration-store-impl/src/SchemeManagerImpl.kt @@ -612,7 +612,10 @@ public class SchemeManagerImpl(private val deleteUsingIo = false for (name in filesToDelete) { errors.catch { - StorageUtil.delete(provider, "$fileSpec/$name", roamingType) + val spec = "$fileSpec/$name" + if (provider.isApplicable(spec, roamingType)) { + provider.delete(spec, roamingType) + } } } } diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java index 46ca517cee22..950951ba5403 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java @@ -403,12 +403,6 @@ public class StorageUtil { return defaultSeparator == null ? LineSeparator.getSystemLineSeparator() : defaultSeparator; } - public static void delete(@NotNull StreamProvider provider, @NotNull String fileSpec, @NotNull RoamingType type) { - if (provider.isApplicable(fileSpec, type)) { - provider.delete(fileSpec, type); - } - } - public static boolean isProjectOrModuleFile(@NotNull String fileSpec) { return StoragePathMacros.PROJECT_FILE.equals(fileSpec) || fileSpec.startsWith(StoragePathMacros.PROJECT_CONFIG_DIR) || fileSpec.equals(StoragePathMacros.MODULE_FILE); } From f8d0d86a52477e741e7b324622f2e6eff682e294 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 25 Aug 2015 16:58:33 +0200 Subject: [PATCH 053/246] hide StreamProvider --- .../src/DefaultProjectStoreImpl.kt | 5 ---- .../src/FileBasedStorage.kt | 1 - .../src/SchemeManagerFactoryImpl.kt | 4 ++-- .../src/SchemeManagerImpl.kt | 1 - .../src/StateStorageManagerImpl.kt | 9 +------ .../src}/StreamProvider.kt | 2 +- .../testSrc/ApplicationStoreTest.kt | 5 ++-- .../testSrc/MockStreamProvider.kt | 1 - .../impl/stores/StateStorageManager.java | 5 ---- plugins/settings-repository/src/IcsManager.kt | 7 +++--- .../src/copyAppSettingsToRepository.kt | 24 +++++++++++++++---- .../testSrc/IcsTestCase.kt | 2 +- 12 files changed, 31 insertions(+), 35 deletions(-) rename platform/{platform-impl/src/com/intellij/openapi/components/impl/stores => configuration-store-impl/src}/StreamProvider.kt (96%) diff --git a/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt b/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt index f38724a1d14b..a79feef438df 100644 --- a/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt +++ b/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt @@ -18,7 +18,6 @@ package com.intellij.configurationStore import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.components.* import com.intellij.openapi.components.impl.stores.StateStorageManager -import com.intellij.openapi.components.impl.stores.StreamProvider import com.intellij.openapi.project.Project import com.intellij.openapi.project.impl.ProjectImpl import com.intellij.util.containers.ContainerUtil @@ -76,10 +75,6 @@ class DefaultProjectStoreImpl(override val project: ProjectImpl, private val pat override fun collapseMacros(path: String) = throw UnsupportedOperationException("Method collapseMacros not implemented in " + javaClass) override fun getOldStorage(component: Any, componentName: String, operation: StateStorageOperation) = storage - - override fun setStreamProvider(streamProvider: StreamProvider?) = throw UnsupportedOperationException("Method setStreamProvider not implemented in " + javaClass) - - override fun getStreamProvider() = throw UnsupportedOperationException("Method getStreamProviders not implemented in " + javaClass) } // don't want to optimize and use already loaded data - it will add unnecessary complexity and implementation-lock (currently we store loaded archived state in memory, but later implementation can be changed) diff --git a/platform/configuration-store-impl/src/FileBasedStorage.kt b/platform/configuration-store-impl/src/FileBasedStorage.kt index 0b0026531022..afdc850b0f16 100644 --- a/platform/configuration-store-impl/src/FileBasedStorage.kt +++ b/platform/configuration-store-impl/src/FileBasedStorage.kt @@ -24,7 +24,6 @@ import com.intellij.openapi.components.StoragePathMacros import com.intellij.openapi.components.TrackingPathMacroSubstitutor import com.intellij.openapi.components.impl.stores.FileStorage import com.intellij.openapi.components.impl.stores.StorageUtil -import com.intellij.openapi.components.impl.stores.StreamProvider import com.intellij.openapi.util.JDOMUtil import com.intellij.openapi.util.io.systemIndependentPath import com.intellij.openapi.vfs.CharsetToolkit diff --git a/platform/configuration-store-impl/src/SchemeManagerFactoryImpl.kt b/platform/configuration-store-impl/src/SchemeManagerFactoryImpl.kt index d7170e5842f5..e6f4be59e7a3 100644 --- a/platform/configuration-store-impl/src/SchemeManagerFactoryImpl.kt +++ b/platform/configuration-store-impl/src/SchemeManagerFactoryImpl.kt @@ -37,10 +37,10 @@ public abstract class SchemeManagerFactoryBase : SchemesManagerFactory(), Settin abstract val componentManager: ComponentManager override final fun createSchemesManager(directoryName: String, processor: SchemeProcessor, roamingType: RoamingType): SchemesManager { - val storageManager = componentManager.stateStore.getStateStorageManager() + val storageManager = (componentManager.stateStore).getStateStorageManager() val path = checkPath(directoryName) - val manager = SchemeManagerImpl(path, processor, roamingType, storageManager.getStreamProvider(), pathToFile(path, storageManager), componentManager) + val manager = SchemeManagerImpl(path, processor, roamingType, (storageManager as? StateStorageManagerImpl)?.streamProvider, pathToFile(path, storageManager), componentManager) @suppress("CAST_NEVER_SUCCEEDS") managers.add(manager as SchemeManagerImpl) return manager diff --git a/platform/configuration-store-impl/src/SchemeManagerImpl.kt b/platform/configuration-store-impl/src/SchemeManagerImpl.kt index 317046c04eb6..7ec4890f0548 100644 --- a/platform/configuration-store-impl/src/SchemeManagerImpl.kt +++ b/platform/configuration-store-impl/src/SchemeManagerImpl.kt @@ -24,7 +24,6 @@ import com.intellij.openapi.application.runWriteAction import com.intellij.openapi.components.RoamingType import com.intellij.openapi.components.impl.ServiceManagerImpl import com.intellij.openapi.components.impl.stores.StorageUtil -import com.intellij.openapi.components.impl.stores.StreamProvider import com.intellij.openapi.components.service import com.intellij.openapi.extensions.AbstractExtensionPointBean import com.intellij.openapi.options.* diff --git a/platform/configuration-store-impl/src/StateStorageManagerImpl.kt b/platform/configuration-store-impl/src/StateStorageManagerImpl.kt index 9e51a144590b..d24c990e56aa 100644 --- a/platform/configuration-store-impl/src/StateStorageManagerImpl.kt +++ b/platform/configuration-store-impl/src/StateStorageManagerImpl.kt @@ -22,7 +22,6 @@ import com.intellij.openapi.components.* import com.intellij.openapi.components.StateStorage.SaveSession import com.intellij.openapi.components.StateStorageChooserEx.Resolution import com.intellij.openapi.components.impl.stores.StateStorageManager -import com.intellij.openapi.components.impl.stores.StreamProvider import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.io.FileUtilRt import com.intellij.openapi.util.text.StringUtil @@ -56,7 +55,7 @@ open class StateStorageManagerImpl(private val rootTagName: String, private val storageLock = ReentrantLock() private val storages = THashMap() - private var streamProvider: StreamProvider? = null + public var streamProvider: StreamProvider? = null // access under storageLock private var isUseVfsListener = if (componentManager == null) ThreeState.NO else ThreeState.UNSURE // unsure because depends on stream provider state @@ -86,12 +85,6 @@ open class StateStorageManagerImpl(private val rootTagName: String, } } - override final fun getStreamProvider() = streamProvider - - override final fun setStreamProvider(value: StreamProvider?) { - streamProvider = value - } - override final fun getMacroSubstitutor() = pathMacroSubstitutor private data class Macro(val key: String, var value: String) diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.kt b/platform/configuration-store-impl/src/StreamProvider.kt similarity index 96% rename from platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.kt rename to platform/configuration-store-impl/src/StreamProvider.kt index ff2a1206c20f..160b4ac34d1a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.kt +++ b/platform/configuration-store-impl/src/StreamProvider.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.openapi.components.impl.stores +package com.intellij.configurationStore import com.intellij.openapi.components.RoamingType import java.io.InputStream diff --git a/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt b/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt index 5827dc8c2d33..f37c7afe462e 100644 --- a/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt +++ b/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt @@ -17,7 +17,6 @@ package com.intellij.configurationStore import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.components.* -import com.intellij.openapi.components.impl.stores.StreamProvider import com.intellij.openapi.vfs.CharsetToolkit import com.intellij.testFramework.* import com.intellij.util.SmartList @@ -58,7 +57,7 @@ class ApplicationStoreTest { val component = SeveralStoragesConfigured() val streamProvider = MyStreamProvider() - componentStore.storageManager.setStreamProvider(streamProvider) + componentStore.storageManager.streamProvider = streamProvider componentStore.initComponent(component, false) component.foo = "newValue" @@ -76,7 +75,7 @@ class ApplicationStoreTest { map.put(fileSpec, "\n \n \n") streamProvider.data.put(RoamingType.PER_USER, map) - componentStore.storageManager.setStreamProvider(streamProvider) + componentStore.storageManager.streamProvider = streamProvider componentStore.initComponent(component, false) assertThat(component.foo).isEqualTo("newValue") diff --git a/platform/configuration-store-impl/testSrc/MockStreamProvider.kt b/platform/configuration-store-impl/testSrc/MockStreamProvider.kt index 49064a738e3d..c765bb81c6b9 100644 --- a/platform/configuration-store-impl/testSrc/MockStreamProvider.kt +++ b/platform/configuration-store-impl/testSrc/MockStreamProvider.kt @@ -1,7 +1,6 @@ package com.intellij.configurationStore import com.intellij.openapi.components.RoamingType -import com.intellij.openapi.components.impl.stores.StreamProvider import com.intellij.openapi.util.io.FileUtil import com.intellij.util.SmartList import java.io.File diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java index ba5c476962cf..87079b615125 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java @@ -57,11 +57,6 @@ public interface StateStorageManager { */ String collapseMacros(@NotNull String path); - void setStreamProvider(@Nullable StreamProvider streamProvider); - - @Nullable - StreamProvider getStreamProvider(); - interface ExternalizationSession { void setState(@NotNull Storage[] storageSpecs, @NotNull Object component, @NotNull String componentName, @NotNull Object state); diff --git a/plugins/settings-repository/src/IcsManager.kt b/plugins/settings-repository/src/IcsManager.kt index 1d0eea232d42..2ba5dabde263 100644 --- a/plugins/settings-repository/src/IcsManager.kt +++ b/plugins/settings-repository/src/IcsManager.kt @@ -15,6 +15,8 @@ */ package org.jetbrains.settingsRepository +import com.intellij.configurationStore.StateStorageManagerImpl +import com.intellij.configurationStore.StreamProvider import com.intellij.ide.ApplicationLoadListener import com.intellij.openapi.application.Application import com.intellij.openapi.application.ApplicationManager @@ -22,7 +24,6 @@ import com.intellij.openapi.application.PathManager import com.intellij.openapi.components.RoamingType import com.intellij.openapi.components.StoragePathMacros import com.intellij.openapi.components.impl.stores.StorageUtil -import com.intellij.openapi.components.impl.stores.StreamProvider import com.intellij.openapi.components.stateStore import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.progress.ProgressIndicator @@ -135,7 +136,7 @@ class IcsManager(dir: File) { return } - storageManager.setStreamProvider(ProjectLevelProvider(projectId.uid!!)) +// storageManager.setStreamProvider(ProjectLevelProvider(projectId.uid!!)) // updateStoragesFromStreamProvider(storageManager, storageManager.getStorageFileNames()) } @@ -174,7 +175,7 @@ class IcsManager(dir: File) { fun beforeApplicationLoaded(application: Application) { repositoryActive = repositoryManager.isRepositoryExists() - application.stateStore.getStateStorageManager().setStreamProvider(ApplicationLevelProvider()) + (application.stateStore.getStateStorageManager() as StateStorageManagerImpl).streamProvider = ApplicationLevelProvider() autoSyncManager.registerListeners(application) diff --git a/plugins/settings-repository/src/copyAppSettingsToRepository.kt b/plugins/settings-repository/src/copyAppSettingsToRepository.kt index 01716d3a7943..4dad5fb5b938 100644 --- a/plugins/settings-repository/src/copyAppSettingsToRepository.kt +++ b/plugins/settings-repository/src/copyAppSettingsToRepository.kt @@ -1,5 +1,21 @@ +/* + * Copyright 2000-2015 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 org.jetbrains.settingsRepository +import com.intellij.configurationStore.StateStorageManagerImpl import com.intellij.ide.actions.ExportSettingsAction import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.components.* @@ -8,18 +24,18 @@ import com.intellij.openapi.util.io.FileUtilRt import java.io.File fun copyLocalConfig() { - val stateStorageManager = ApplicationManager.getApplication()!!.stateStore.getStateStorageManager() - val streamProvider = stateStorageManager.getStreamProvider()!! as IcsManager.IcsStreamProvider + val storageManager = ApplicationManager.getApplication()!!.stateStore.getStateStorageManager() as StateStorageManagerImpl + val streamProvider = storageManager.streamProvider!! as IcsManager.IcsStreamProvider val fileToComponents = ExportSettingsAction.getExportableComponentsMap(true, false) for (file in fileToComponents.keySet()) { val absolutePath = FileUtilRt.toSystemIndependentName(file.getAbsolutePath()) - var fileSpec = stateStorageManager.collapseMacros(absolutePath) + var fileSpec = storageManager.collapseMacros(absolutePath) if (fileSpec.equals(absolutePath)) { // we have not experienced such problem yet, but we are just aware val canonicalPath = FileUtilRt.toSystemIndependentName(file.getCanonicalPath()) if (!canonicalPath.equals(absolutePath)) { - fileSpec = stateStorageManager.collapseMacros(canonicalPath) + fileSpec = storageManager.collapseMacros(canonicalPath) } } diff --git a/plugins/settings-repository/testSrc/IcsTestCase.kt b/plugins/settings-repository/testSrc/IcsTestCase.kt index 6c2d67dcc9c9..a7b0a7a4d186 100644 --- a/plugins/settings-repository/testSrc/IcsTestCase.kt +++ b/plugins/settings-repository/testSrc/IcsTestCase.kt @@ -15,8 +15,8 @@ */ package org.jetbrains.settingsRepository.test +import com.intellij.configurationStore.StreamProvider import com.intellij.openapi.components.RoamingType -import com.intellij.openapi.components.impl.stores.StreamProvider import com.intellij.openapi.util.io.FileUtil import com.intellij.testFramework.PlatformTestUtil import com.intellij.testFramework.TemporaryDirectory From d7f88ac88982a302825650006f885c560842df1a Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 25 Aug 2015 17:05:30 +0200 Subject: [PATCH 054/246] move SaveSessionBase to configuration-store module --- .../intellij/configurationStore}/SaveSessionBase.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) rename platform/{platform-impl/src/com/intellij/openapi/components/impl/stores => configuration-store-impl/src/com/intellij/configurationStore}/SaveSessionBase.java (87%) diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/SaveSessionBase.java b/platform/configuration-store-impl/src/com/intellij/configurationStore/SaveSessionBase.java similarity index 87% rename from platform/platform-impl/src/com/intellij/openapi/components/impl/stores/SaveSessionBase.java rename to platform/configuration-store-impl/src/com/intellij/configurationStore/SaveSessionBase.java index 4d6db0fb1d27..4f724452f300 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/SaveSessionBase.java +++ b/platform/configuration-store-impl/src/com/intellij/configurationStore/SaveSessionBase.java @@ -13,9 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.openapi.components.impl.stores; +package com.intellij.configurationStore; import com.intellij.openapi.components.StateStorage; +import com.intellij.openapi.components.impl.stores.StateStorageBase; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.JDOMExternalizable; import com.intellij.openapi.util.WriteExternalException; import com.intellij.openapi.vfs.SafeWriteRequestor; @@ -26,6 +28,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public abstract class SaveSessionBase implements StateStorage.SaveSession, StateStorage.ExternalizationSession, SafeWriteRequestor { + private static final Logger LOG = Logger.getInstance(StateStorageBase.class); + private SkipDefaultsSerializationFilter serializationFilter; @SuppressWarnings("deprecation") @@ -48,11 +52,11 @@ public abstract class SaveSessionBase implements StateStorage.SaveSession, State } } catch (WriteExternalException e) { - StateStorageBase.LOG.debug(e); + LOG.debug(e); return; } catch (Throwable e) { - StateStorageBase.LOG.error("Unable to serialize " + componentName + " state", e); + LOG.error("Unable to serialize " + componentName + " state", e); return; } From b0aea560891aa7d5dfd713c5b20148c19c167729 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 25 Aug 2015 17:07:57 +0200 Subject: [PATCH 055/246] move SaveSessionBase to configuration-store module --- .../configurationStore/SaveSessionBase.java | 63 +++++++++---------- 1 file changed, 29 insertions(+), 34 deletions(-) diff --git a/platform/configuration-store-impl/src/com/intellij/configurationStore/SaveSessionBase.java b/platform/configuration-store-impl/src/com/intellij/configurationStore/SaveSessionBase.java index 4f724452f300..7118c993fe30 100644 --- a/platform/configuration-store-impl/src/com/intellij/configurationStore/SaveSessionBase.java +++ b/platform/configuration-store-impl/src/com/intellij/configurationStore/SaveSessionBase.java @@ -13,55 +13,50 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.configurationStore; +package com.intellij.configurationStore -import com.intellij.openapi.components.StateStorage; -import com.intellij.openapi.components.impl.stores.StateStorageBase; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.JDOMExternalizable; -import com.intellij.openapi.util.WriteExternalException; -import com.intellij.openapi.vfs.SafeWriteRequestor; -import com.intellij.util.xmlb.SkipDefaultsSerializationFilter; -import com.intellij.util.xmlb.XmlSerializer; -import org.jdom.Element; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import com.intellij.openapi.components.StateStorage +import com.intellij.openapi.components.impl.stores.StateStorageBase +import com.intellij.openapi.diagnostic.Logger +import com.intellij.openapi.util.JDOMExternalizable +import com.intellij.openapi.util.WriteExternalException +import com.intellij.openapi.vfs.SafeWriteRequestor +import com.intellij.util.xmlb.SkipDefaultsSerializationFilter +import com.intellij.util.xmlb.XmlSerializer +import org.jdom.Element -public abstract class SaveSessionBase implements StateStorage.SaveSession, StateStorage.ExternalizationSession, SafeWriteRequestor { - private static final Logger LOG = Logger.getInstance(StateStorageBase.class); - - private SkipDefaultsSerializationFilter serializationFilter; +abstract class SaveSessionBase : StateStorage.SaveSession, StateStorage.ExternalizationSession, SafeWriteRequestor { + private var serializationFilter: SkipDefaultsSerializationFilter? = null @SuppressWarnings("deprecation") - @Override - public final void setState(@NotNull Object component, @NotNull String componentName, @NotNull Object state) { - Element element; + override fun setState(component: Any, componentName: String, state: Any) { + val element: Element? try { - if (state instanceof Element) { - element = (Element)state; + if (state is Element) { + element = state } - else if (state instanceof JDOMExternalizable) { - element = new Element("temp_element"); - ((JDOMExternalizable)state).writeExternal(element); + else if (state is JDOMExternalizable) { + element = Element("temp_element") + state.writeExternal(element) } else { if (serializationFilter == null) { - serializationFilter = new SkipDefaultsSerializationFilter(); + serializationFilter = SkipDefaultsSerializationFilter() } - element = XmlSerializer.serializeIfNotDefault(state, serializationFilter); + element = XmlSerializer.serializeIfNotDefault(state, serializationFilter) } } - catch (WriteExternalException e) { - LOG.debug(e); - return; + catch (e: WriteExternalException) { + LOG.debug(e) + return } - catch (Throwable e) { - LOG.error("Unable to serialize " + componentName + " state", e); - return; + catch (e: Throwable) { + LOG.error("Unable to serialize $componentName state", e) + return } - setSerializedState(component, componentName, element); + setSerializedState(component, componentName, element) } - protected abstract void setSerializedState(@NotNull Object component, @NotNull String componentName, @Nullable Element element); + protected abstract fun setSerializedState(component: Any, componentName: String, element: Element?) } From 21bb3414557c69be2be612d967225b02ee0baf23 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 25 Aug 2015 17:09:05 +0200 Subject: [PATCH 056/246] move SaveSessionBase to configuration-store module --- .../SaveSessionBase.java => SaveSessionBase.kt} | 2 -- 1 file changed, 2 deletions(-) rename platform/configuration-store-impl/src/{com/intellij/configurationStore/SaveSessionBase.java => SaveSessionBase.kt} (94%) diff --git a/platform/configuration-store-impl/src/com/intellij/configurationStore/SaveSessionBase.java b/platform/configuration-store-impl/src/SaveSessionBase.kt similarity index 94% rename from platform/configuration-store-impl/src/com/intellij/configurationStore/SaveSessionBase.java rename to platform/configuration-store-impl/src/SaveSessionBase.kt index 7118c993fe30..504a6b0387e1 100644 --- a/platform/configuration-store-impl/src/com/intellij/configurationStore/SaveSessionBase.java +++ b/platform/configuration-store-impl/src/SaveSessionBase.kt @@ -16,8 +16,6 @@ package com.intellij.configurationStore import com.intellij.openapi.components.StateStorage -import com.intellij.openapi.components.impl.stores.StateStorageBase -import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.util.JDOMExternalizable import com.intellij.openapi.util.WriteExternalException import com.intellij.openapi.vfs.SafeWriteRequestor From 71a64e9fc26dceefcc29ddfb3bf5fd65102e1f50 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 25 Aug 2015 17:17:59 +0200 Subject: [PATCH 057/246] don't interrupt state reloading due to assert --- .../openapi/roots/impl/CompilerProjectExtensionImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/openapi/roots/impl/CompilerProjectExtensionImpl.java b/java/java-impl/src/com/intellij/openapi/roots/impl/CompilerProjectExtensionImpl.java index dd06dfa7e455..4081e8f56539 100644 --- a/java/java-impl/src/com/intellij/openapi/roots/impl/CompilerProjectExtensionImpl.java +++ b/java/java-impl/src/com/intellij/openapi/roots/impl/CompilerProjectExtensionImpl.java @@ -55,7 +55,6 @@ public class CompilerProjectExtensionImpl extends CompilerProjectExtension { final Element outputPathChild = element.getChild(OUTPUT_TAG); if (outputPathChild != null) { String outputPath = outputPathChild.getAttributeValue(URL); - assert myCompilerOutput == null; myCompilerOutput = VirtualFilePointerManager.getInstance().create(outputPath, myProject, null); } } From c03a41ff5d45dde3238f5fc7192b24ccaeb822e5 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 25 Aug 2015 17:19:57 +0200 Subject: [PATCH 058/246] don't write custom output if inherited --- .../impl/CompilerModuleExtensionImpl.java | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/java/java-impl/src/com/intellij/openapi/roots/impl/CompilerModuleExtensionImpl.java b/java/java-impl/src/com/intellij/openapi/roots/impl/CompilerModuleExtensionImpl.java index eeaa91381bb5..e3eaaa858c1a 100644 --- a/java/java-impl/src/com/intellij/openapi/roots/impl/CompilerModuleExtensionImpl.java +++ b/java/java-impl/src/com/intellij/openapi/roots/impl/CompilerModuleExtensionImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -104,15 +104,17 @@ public class CompilerModuleExtensionImpl extends CompilerModuleExtension { @Override public void writeExternal(final Element element) throws WriteExternalException { assert !myDisposed; - if (myCompilerOutput != null) { - final Element pathElement = new Element(OUTPUT_TAG); - pathElement.setAttribute(ATTRIBUTE_URL, myCompilerOutput); - element.addContent(pathElement); - } - if (myCompilerOutputForTests != null) { - final Element pathElement = new Element(TEST_OUTPUT_TAG); - pathElement.setAttribute(ATTRIBUTE_URL, myCompilerOutputForTests); - element.addContent(pathElement); + if (!myInheritedCompilerOutput) { + if (myCompilerOutput != null) { + final Element pathElement = new Element(OUTPUT_TAG); + pathElement.setAttribute(ATTRIBUTE_URL, myCompilerOutput); + element.addContent(pathElement); + } + if (myCompilerOutputForTests != null) { + final Element pathElement = new Element(TEST_OUTPUT_TAG); + pathElement.setAttribute(ATTRIBUTE_URL, myCompilerOutputForTests); + element.addContent(pathElement); + } } element.setAttribute(INHERIT_COMPILER_OUTPUT, String.valueOf(myInheritedCompilerOutput)); if (myExcludeOutput) { From 5e876fb67827341f8166eadbfce59e03aea76060 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 25 Aug 2015 12:41:17 +0200 Subject: [PATCH 059/246] make IG test light and add a case --- .../LocalVariableHidingMemberVariable.java | 12 ++++---- .../expected.xml | 30 ------------------- .../visibility2/DifferentPackageClass.java | 6 ---- ...bleHidingMemberVariableInspectionTest.java | 30 +++++++++++++++---- 4 files changed, 31 insertions(+), 47 deletions(-) delete mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/local_variable_hiding_member_variable/expected.xml delete mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/visibility2/DifferentPackageClass.java diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/local_variable_hiding_member_variable/LocalVariableHidingMemberVariable.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/local_variable_hiding_member_variable/LocalVariableHidingMemberVariable.java index 353e2b79fde8..3012423ac2f1 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/local_variable_hiding_member_variable/LocalVariableHidingMemberVariable.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/local_variable_hiding_member_variable/LocalVariableHidingMemberVariable.java @@ -14,10 +14,10 @@ public class LocalVariableHidingMemberVariable extends DifferentPackageClass m_barangus = barangus; } - public void foo() - { + public void foo() { int fooBar; - final Object m_barangus = new Object(); + int fooBar2; + final Object m_barangus = new Object(); System.out.println("bar" + m_barangus); } @@ -30,19 +30,19 @@ public class LocalVariableHidingMemberVariable extends DifferentPackageClass public void innerContainer() { new Object() { void foo() { - Object m_barangus = new Object(); + Object m_barangus = new Object(); } }; } public void foreach(List list) { - for (String m_barangus : list) { + for (String m_barangus : list) { } } { - final Object m_barangus = new Object(); + final Object m_barangus = new Object(); } static { diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/local_variable_hiding_member_variable/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/local_variable_hiding_member_variable/expected.xml deleted file mode 100644 index 43bea6603064..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/local_variable_hiding_member_variable/expected.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - LocalVariableHidingMemberVariable.java - 20 - Local variable hides field - Local variable <code>m_barangus</code> hides field in class 'LocalVariableHidingMemberVariable' #loc - - - - LocalVariableHidingMemberVariable.java - 33 - Local variable hides field - Local variable <code>m_barangus</code> hides field in class 'LocalVariableHidingMemberVariable' #loc - - - - LocalVariableHidingMemberVariable.java - 39 - Local variable hides field - Local variable <code>m_barangus</code> hides field in class 'LocalVariableHidingMemberVariable' #loc - - - - LocalVariableHidingMemberVariable.java - 45 - Local variable hides field - Local variable <code>m_barangus</code> hides field in class 'LocalVariableHidingMemberVariable' #loc - - \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility2/DifferentPackageClass.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility2/DifferentPackageClass.java deleted file mode 100644 index 75c8ef39d64a..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility2/DifferentPackageClass.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.siyeh.igtest.visibility2; - -public class DifferentPackageClass -{ - int fooBar; -} diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/LocalVariableHidingMemberVariableInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/LocalVariableHidingMemberVariableInspectionTest.java index 6de4b976fa76..35a8f50e5f0b 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/LocalVariableHidingMemberVariableInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/LocalVariableHidingMemberVariableInspectionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2015 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,13 +15,33 @@ */ package com.siyeh.ig.visibility; -import com.siyeh.ig.IGInspectionTestCase; +import com.intellij.codeInspection.InspectionProfileEntry; +import com.siyeh.ig.LightInspectionTestCase; +import org.jetbrains.annotations.Nullable; -public class LocalVariableHidingMemberVariableInspectionTest extends IGInspectionTestCase { +public class LocalVariableHidingMemberVariableInspectionTest extends LightInspectionTestCase { - public void test() throws Exception { + public void testLocalVariableHidingMemberVariable() { + doTest(); + } + + @Nullable + @Override + protected InspectionProfileEntry getInspection() { final LocalVariableHidingMemberVariableInspection inspection = new LocalVariableHidingMemberVariableInspection(); inspection.m_ignoreStaticMethods = true; - doTest("com/siyeh/igtest/visibility/local_variable_hiding_member_variable", inspection); + return inspection; + } + + @Override + protected String[] getEnvironmentClasses() { + return new String[] { + "package com.siyeh.igtest.visibility2;\n" + + "public class DifferentPackageClass\n" + + "{\n" + + " int fooBar;\n" + + " protected int fooBar2;\n" + + "}\n" + }; } } \ No newline at end of file From cc622018cd63e63a90b42efdacceb4794734cc50 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 25 Aug 2015 16:16:38 +0200 Subject: [PATCH 060/246] Use shouldInspect() method more --- .../ig/bugs/EmptyStatementBodyInspection.java | 16 +++++------- ...NameDiffersFromFileNameInspectionBase.java | 11 +++++--- .../UnnecessaryContinueInspection.java | 10 +++++--- .../UnnecessaryReturnInspection.java | 12 +++++---- .../EmptyCatchBlockInspectionBase.java | 11 ++++---- .../EmptyFinallyBlockInspection.java | 10 +++++--- .../EmptyTryBlockInspection.java | 11 +++++--- .../ig/imports/JavaLangImportInspection.java | 10 +++++--- .../ig/imports/OnDemandImportInspection.java | 10 +++++--- .../imports/SamePackageImportInspection.java | 12 +++++---- .../imports/SingleClassImportInspection.java | 25 ++++++++----------- .../imports/StaticImportInspectionBase.java | 10 +++++--- .../ig/imports/UnusedImportInspection.java | 12 +++++---- .../ClassWithoutConstructorInspection.java | 15 ++++++----- .../DesignForExtensionInspection.java | 11 ++++---- .../EmptySynchronizedStatementInspection.java | 19 +++++++------- 16 files changed, 113 insertions(+), 92 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EmptyStatementBodyInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EmptyStatementBodyInspection.java index afea6ecabdc6..2302d2d824c2 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EmptyStatementBodyInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EmptyStatementBodyInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -74,6 +74,11 @@ public class EmptyStatementBodyInspection extends BaseInspection { return panel; } + @Override + public boolean shouldInspect(PsiFile file) { + return !FileTypeUtils.isInServerPageFile(file); + } + @Override public BaseInspectionVisitor buildVisitor() { return new EmptyStatementVisitor(); @@ -106,9 +111,6 @@ public class EmptyStatementBodyInspection extends BaseInspection { } private void checkLoopStatement(PsiLoopStatement statement) { - if (FileTypeUtils.isInServerPageFile(statement)) { - return; - } final PsiStatement body = statement.getBody(); if (body == null || !isEmpty(body)) { return; @@ -119,9 +121,6 @@ public class EmptyStatementBodyInspection extends BaseInspection { @Override public void visitIfStatement(@NotNull PsiIfStatement statement) { super.visitIfStatement(statement); - if (FileTypeUtils.isInServerPageFile(statement)) { - return; - } final PsiStatement thenBranch = statement.getThenBranch(); if (thenBranch != null && isEmpty(thenBranch)) { registerStatementError(statement); @@ -140,9 +139,6 @@ public class EmptyStatementBodyInspection extends BaseInspection { @Override public void visitSwitchStatement(PsiSwitchStatement statement) { super.visitSwitchStatement(statement); - if (FileTypeUtils.isInServerPageFile(statement)) { - return; - } final PsiCodeBlock body = statement.getBody(); if (body == null || !isEmpty(body)) { return; diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/ClassNameDiffersFromFileNameInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/ClassNameDiffersFromFileNameInspectionBase.java index 3726e6aa38ea..ea2c4076b14d 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/ClassNameDiffersFromFileNameInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/ClassNameDiffersFromFileNameInspectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -17,6 +17,7 @@ package com.siyeh.ig.classlayout; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.psi.PsiJavaFile; import com.intellij.psi.util.FileTypeUtils; import com.siyeh.InspectionGadgetsBundle; @@ -39,6 +40,11 @@ public class ClassNameDiffersFromFileNameInspectionBase extends BaseInspection { "class.name.differs.from.file.name.problem.descriptor"); } + @Override + public boolean shouldInspect(PsiFile file) { + return !FileTypeUtils.isInServerPageFile(file); + } + @Override public BaseInspectionVisitor buildVisitor() { return new ClassNameDiffersFromFileNameVisitor(); @@ -50,9 +56,6 @@ public class ClassNameDiffersFromFileNameInspectionBase extends BaseInspection { @Override public void visitClass(@NotNull PsiClass aClass) { // no call to super, so that it doesn't drill down to inner classes - if (FileTypeUtils.isInServerPageFile(aClass)) { - return; - } final PsiElement parent = aClass.getParent(); if (!(parent instanceof PsiJavaFile)) { return; diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryContinueInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryContinueInspection.java index 77a3ab33f26a..51d0954086bb 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryContinueInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryContinueInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,6 +61,11 @@ public class UnnecessaryContinueInspection extends BaseInspection { return new UnnecessaryContinueVisitor(); } + @Override + public boolean shouldInspect(PsiFile file) { + return !FileTypeUtils.isInServerPageFile(file); + } + @Override public InspectionGadgetsFix buildFix(Object... infos) { return new DeleteUnnecessaryStatementFix("continue"); @@ -70,9 +75,6 @@ public class UnnecessaryContinueInspection extends BaseInspection { @Override public void visitContinueStatement(@NotNull PsiContinueStatement statement) { - if (FileTypeUtils.isInServerPageFile(statement.getContainingFile())) { - return; - } final PsiStatement continuedStatement = statement.findContinuedStatement(); PsiStatement body = null; if (continuedStatement instanceof PsiForeachStatement) { diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryReturnInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryReturnInspection.java index 48c10184cb54..5a91e861441a 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryReturnInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryReturnInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package com.siyeh.ig.controlflow; import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel; import com.intellij.psi.*; +import com.intellij.psi.util.FileTypeUtils; import com.intellij.psi.util.PsiTreeUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; @@ -24,7 +25,6 @@ import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.fixes.DeleteUnnecessaryStatementFix; import com.siyeh.ig.psiutils.ControlFlowUtils; -import com.intellij.psi.util.FileTypeUtils; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -71,6 +71,11 @@ public class UnnecessaryReturnInspection extends BaseInspection { return new DeleteUnnecessaryStatementFix("return"); } + @Override + public boolean shouldInspect(PsiFile file) { + return !FileTypeUtils.isInServerPageFile(file); + } + @Override public BaseInspectionVisitor buildVisitor() { return new UnnecessaryReturnVisitor(); @@ -80,9 +85,6 @@ public class UnnecessaryReturnInspection extends BaseInspection { @Override public void visitReturnStatement(@NotNull PsiReturnStatement statement) { super.visitReturnStatement(statement); - if (FileTypeUtils.isInServerPageFile(statement.getContainingFile())) { - return; - } if (statement.getReturnValue() != null) { return; } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyCatchBlockInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyCatchBlockInspectionBase.java index 628853e6412c..62cf346c9083 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyCatchBlockInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyCatchBlockInspectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,6 @@ import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.ig.psiutils.TestUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -113,6 +112,11 @@ public class EmptyCatchBlockInspectionBase extends BaseInspection { } } + @Override + public boolean shouldInspect(PsiFile file) { + return !FileTypeUtils.isInServerPageFile(file); + } + @Override public BaseInspectionVisitor buildVisitor() { return new EmptyCatchBlockVisitor(); @@ -123,9 +127,6 @@ public class EmptyCatchBlockInspectionBase extends BaseInspection { @Override public void visitTryStatement(@NotNull PsiTryStatement statement) { super.visitTryStatement(statement); - if (FileTypeUtils.isInServerPageFile(statement.getContainingFile())) { - return; - } final PsiCatchSection[] catchSections = statement.getCatchSections(); for (final PsiCatchSection section : catchSections) { checkCatchSection(section); diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyFinallyBlockInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyFinallyBlockInspection.java index 5abb492c0cee..048b9ec89582 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyFinallyBlockInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyFinallyBlockInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -143,6 +143,11 @@ public class EmptyFinallyBlockInspection extends BaseInspection { } } + @Override + public boolean shouldInspect(PsiFile file) { + return !FileTypeUtils.isInServerPageFile(file); + } + @Override public BaseInspectionVisitor buildVisitor() { return new EmptyFinallyBlockVisitor(); @@ -152,9 +157,6 @@ public class EmptyFinallyBlockInspection extends BaseInspection { @Override public void visitTryStatement(@NotNull PsiTryStatement statement) { super.visitTryStatement(statement); - if (FileTypeUtils.isInServerPageFile(statement.getContainingFile())) { - return; - } final PsiCodeBlock finallyBlock = statement.getFinallyBlock(); if (finallyBlock == null) { return; diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyTryBlockInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyTryBlockInspection.java index 04f50afdaa2d..a2a011088924 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyTryBlockInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyTryBlockInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package com.siyeh.ig.errorhandling; import com.intellij.psi.PsiCodeBlock; +import com.intellij.psi.PsiFile; import com.intellij.psi.PsiTryStatement; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; @@ -43,6 +44,11 @@ public class EmptyTryBlockInspection extends BaseInspection { "empty.try.block.problem.descriptor"); } + @Override + public boolean shouldInspect(PsiFile file) { + return !FileTypeUtils.isInServerPageFile(file); + } + @Override public BaseInspectionVisitor buildVisitor() { return new EmptyTryBlockVisitor(); @@ -54,9 +60,6 @@ public class EmptyTryBlockInspection extends BaseInspection { @Override public void visitTryStatement(@NotNull PsiTryStatement statement) { super.visitTryStatement(statement); - if (FileTypeUtils.isInServerPageFile(statement.getContainingFile())) { - return; - } final PsiCodeBlock finallyBlock = statement.getTryBlock(); if (finallyBlock == null) { return; diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/JavaLangImportInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/JavaLangImportInspection.java index 8ac422e74c31..8ec10761c661 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/JavaLangImportInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/JavaLangImportInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,6 +48,11 @@ public class JavaLangImportInspection extends BaseInspection implements CleanupL return new DeleteImportFix(); } + @Override + public boolean shouldInspect(PsiFile file) { + return !FileTypeUtils.isInServerPageFile(file); + } + @Override public BaseInspectionVisitor buildVisitor() { return new JavaLangImportVisitor(); @@ -61,9 +66,6 @@ public class JavaLangImportInspection extends BaseInspection implements CleanupL if (!(aClass.getParent() instanceof PsiJavaFile)) { return; } - if (FileTypeUtils.isInServerPageFile(aClass.getContainingFile())) { - return; - } final PsiJavaFile file = (PsiJavaFile)aClass.getContainingFile(); if (!file.getClasses()[0].equals(aClass)) { return; diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/OnDemandImportInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/OnDemandImportInspection.java index f9d5aea7344d..b1eff0367f24 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/OnDemandImportInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/OnDemandImportInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,6 +36,11 @@ public class OnDemandImportInspection extends BaseInspection { return InspectionGadgetsBundle.message("import.problem.descriptor"); } + @Override + public boolean shouldInspect(PsiFile file) { + return !FileTypeUtils.isInServerPageFile(file); + } + @Override public BaseInspectionVisitor buildVisitor() { return new PackageImportVisitor(); @@ -51,9 +56,6 @@ public class OnDemandImportInspection extends BaseInspection { return; } final PsiJavaFile file = (PsiJavaFile)parent; - if (FileTypeUtils.isInServerPageFile(aClass.getContainingFile())) { - return; - } if (!file.getClasses()[0].equals(aClass)) { return; } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SamePackageImportInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SamePackageImportInspection.java index a1bd67ab359b..602720549847 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SamePackageImportInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SamePackageImportInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,12 +17,12 @@ package com.siyeh.ig.imports; import com.intellij.codeInspection.CleanupLocalInspectionTool; import com.intellij.psi.*; +import com.intellij.psi.util.FileTypeUtils; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.fixes.DeleteImportFix; -import com.intellij.psi.util.FileTypeUtils; import org.jetbrains.annotations.NotNull; public class SamePackageImportInspection extends BaseInspection implements CleanupLocalInspectionTool { @@ -46,6 +46,11 @@ public class SamePackageImportInspection extends BaseInspection implements Clean return new DeleteImportFix(); } + @Override + public boolean shouldInspect(PsiFile file) { + return !FileTypeUtils.isInServerPageFile(file); + } + @Override public BaseInspectionVisitor buildVisitor() { return new SamePackageImportVisitor(); @@ -60,9 +65,6 @@ public class SamePackageImportInspection extends BaseInspection implements Clean if (!(parent instanceof PsiJavaFile)) { return; } - if (FileTypeUtils.isInServerPageFile(importList)) { - return; - } final PsiJavaFile javaFile = (PsiJavaFile)parent; final String packageName = javaFile.getPackageName(); final PsiImportStatement[] importStatements = diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SingleClassImportInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SingleClassImportInspection.java index 9bcad8fc0a95..bcb21fe7390d 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SingleClassImportInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SingleClassImportInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,14 +15,11 @@ */ package com.siyeh.ig.imports; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiImportList; -import com.intellij.psi.PsiImportStatement; -import com.intellij.psi.PsiJavaFile; +import com.intellij.psi.*; +import com.intellij.psi.util.FileTypeUtils; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.intellij.psi.util.FileTypeUtils; import org.jetbrains.annotations.NotNull; public class SingleClassImportInspection extends BaseInspection { @@ -41,6 +38,11 @@ public class SingleClassImportInspection extends BaseInspection { "single.class.import.problem.descriptor"); } + @Override + public boolean shouldInspect(PsiFile file) { + return !FileTypeUtils.isInServerPageFile(file); + } + @Override public BaseInspectionVisitor buildVisitor() { return new PackageImportVisitor(); @@ -51,16 +53,11 @@ public class SingleClassImportInspection extends BaseInspection { @Override public void visitClass(@NotNull PsiClass aClass) { // no call to super, so it doesn't drill down - if (!(aClass.getParent() instanceof PsiJavaFile)) { - return; - } - if (FileTypeUtils.isInServerPageFile(aClass.getContainingFile())) { - return; - } - final PsiJavaFile file = (PsiJavaFile)aClass.getParent(); - if (file == null) { + final PsiElement parent = aClass.getParent(); + if (!(parent instanceof PsiJavaFile)) { return; } + final PsiJavaFile file = (PsiJavaFile)parent; if (!file.getClasses()[0].equals(aClass)) { return; } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/StaticImportInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/StaticImportInspectionBase.java index db4e8f123a51..ebb5febf972d 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/StaticImportInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/StaticImportInspectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -56,6 +56,11 @@ public class StaticImportInspectionBase extends BaseInspection { "static.import.problem.descriptor"); } + @Override + public boolean shouldInspect(PsiFile file) { + return !FileTypeUtils.isInServerPageFile(file); + } + @Override protected InspectionGadgetsFix buildFix(Object... infos) { return new StaticImportFix(); @@ -245,9 +250,6 @@ public class StaticImportInspectionBase extends BaseInspection { return; } final PsiJavaFile file = (PsiJavaFile)parent; - if (FileTypeUtils.isInServerPageFile(file)) { - return; - } if (!file.getClasses()[0].equals(aClass)) { return; } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/UnusedImportInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/UnusedImportInspection.java index 4a3ec992b2f0..33780d975018 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/UnusedImportInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/UnusedImportInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2014 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,12 +16,12 @@ package com.siyeh.ig.imports; import com.intellij.psi.*; +import com.intellij.psi.util.FileTypeUtils; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.fixes.DeleteImportFix; -import com.intellij.psi.util.FileTypeUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -49,6 +49,11 @@ public class UnusedImportInspection extends BaseInspection { return new DeleteImportFix(); } + @Override + public boolean shouldInspect(PsiFile file) { + return !FileTypeUtils.isInServerPageFile(file); + } + @Override public BaseInspectionVisitor buildVisitor() { return new UnusedImportVisitor(); @@ -58,9 +63,6 @@ public class UnusedImportInspection extends BaseInspection { @Override public void visitJavaFile(PsiJavaFile file) { - if (FileTypeUtils.isInServerPageFile(file)) { - return; - } final PsiClass[] classes = file.getClasses(); final PsiPackageStatement packageStatement = file.getPackageStatement(); final PsiModifierList annotationList; diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javabeans/ClassWithoutConstructorInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javabeans/ClassWithoutConstructorInspection.java index d1bd35e9e508..ce338b554bf0 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javabeans/ClassWithoutConstructorInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javabeans/ClassWithoutConstructorInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,12 +19,12 @@ import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.util.FileTypeUtils; import com.intellij.util.IncorrectOperationException; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; -import com.intellij.psi.util.FileTypeUtils; import org.jetbrains.annotations.NotNull; public class ClassWithoutConstructorInspection extends BaseInspection { @@ -98,6 +98,11 @@ public class ClassWithoutConstructorInspection extends BaseInspection { } } + @Override + public boolean shouldInspect(PsiFile file) { + return !FileTypeUtils.isInServerPageFile(file); + } + @Override public BaseInspectionVisitor buildVisitor() { return new ClassWithoutConstructorVisitor(); @@ -109,12 +114,10 @@ public class ClassWithoutConstructorInspection extends BaseInspection { @Override public void visitClass(@NotNull PsiClass aClass) { // no call to super, so it doesn't drill down - if (aClass.isInterface() || aClass.isEnum() || - aClass.isAnnotationType() || FileTypeUtils.isInServerPageFile(aClass)) { + if (aClass.isInterface() || aClass.isEnum() || aClass.isAnnotationType()) { return; } - if (aClass instanceof PsiTypeParameter || - aClass instanceof PsiAnonymousClass) { + if (aClass instanceof PsiTypeParameter || aClass instanceof PsiAnonymousClass) { return; } final PsiMethod[] constructors = aClass.getConstructors(); diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/security/DesignForExtensionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/security/DesignForExtensionInspection.java index 330c38d9d639..95ccf6719278 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/security/DesignForExtensionInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/security/DesignForExtensionInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2014 Dave Griffith, Bas Leijdekkers + * Copyright 2006-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -85,6 +85,11 @@ public class DesignForExtensionInspection extends BaseInspection { } } + @Override + public boolean shouldInspect(PsiFile file) { + return !FileTypeUtils.isInServerPageFile(file); // IDEADEV-25538 + } + @Override public BaseInspectionVisitor buildVisitor() { return new DesignForExtensionVisitor(); @@ -94,10 +99,6 @@ public class DesignForExtensionInspection extends BaseInspection { @Override public void visitMethod(PsiMethod method) { - if (FileTypeUtils.isInServerPageFile(method)) { - // IDEADEV-25538 - return; - } super.visitMethod(method); if (method.isConstructor()) { return; diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/EmptySynchronizedStatementInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/EmptySynchronizedStatementInspection.java index 4a9e0f1dddac..502da183578e 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/EmptySynchronizedStatementInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/EmptySynchronizedStatementInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,12 +16,13 @@ package com.siyeh.ig.threading; import com.intellij.psi.PsiCodeBlock; +import com.intellij.psi.PsiFile; import com.intellij.psi.PsiStatement; import com.intellij.psi.PsiSynchronizedStatement; +import com.intellij.psi.util.FileTypeUtils; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.intellij.psi.util.FileTypeUtils; import org.jetbrains.annotations.NotNull; public class EmptySynchronizedStatementInspection extends BaseInspection { @@ -40,21 +41,21 @@ public class EmptySynchronizedStatementInspection extends BaseInspection { "empty.synchronized.statement.problem.descriptor"); } + @Override + public boolean shouldInspect(PsiFile file) { + return !FileTypeUtils.isInServerPageFile(file); + } + @Override public BaseInspectionVisitor buildVisitor() { return new EmptySynchronizedStatementVisitor(); } - private static class EmptySynchronizedStatementVisitor - extends BaseInspectionVisitor { + private static class EmptySynchronizedStatementVisitor extends BaseInspectionVisitor { @Override - public void visitSynchronizedStatement( - @NotNull PsiSynchronizedStatement statement) { + public void visitSynchronizedStatement(@NotNull PsiSynchronizedStatement statement) { super.visitSynchronizedStatement(statement); - if (FileTypeUtils.isInServerPageFile(statement.getContainingFile())) { - return; - } final PsiCodeBlock body = statement.getBody(); if (body == null) { return; From 3b0189d6266a7761e5c7cee9bd837f96dfbc81f1 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 25 Aug 2015 17:15:13 +0200 Subject: [PATCH 061/246] IG: fix writing settings --- .../ig/numeric/ConfusingFloatingPointLiteralInspection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ConfusingFloatingPointLiteralInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ConfusingFloatingPointLiteralInspection.java index aae01e2ffbff..1b32eb6ea865 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ConfusingFloatingPointLiteralInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ConfusingFloatingPointLiteralInspection.java @@ -62,7 +62,7 @@ public class ConfusingFloatingPointLiteralInspection extends BaseInspection { @Override public void writeSettings(@NotNull Element node) throws WriteExternalException { if (ignoreScientificNotation) { - node.addContent(new Element("option").setAttribute("name", "ignoreScientificNotation").setAttribute("value", "false")); + node.addContent(new Element("option").setAttribute("name", "ignoreScientificNotation").setAttribute("value", "true")); } } From ed817985c59f82df7f528ffb94395fe61d061150 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 25 Aug 2015 17:35:11 +0200 Subject: [PATCH 062/246] IDEA-144307 (Split "Java | Class structure | Abstract class may be interface" into two inspections or add an option to prevent conversion to interfaces with default methods) --- .../siyeh/InspectionGadgetsBundle.properties | 3 +- .../ClassMayBeInterfaceInspection.java | 36 +++++++++++++++---- .../ClassMayBeInterface.html | 4 ++- .../ClassMayBeInterfaceInspectionTest.java | 6 ++-- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties index 831c80af4566..af3247a9ebd2 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties @@ -2165,4 +2165,5 @@ suspicious.literal.underscore.problem.descriptor=Group in number literal with un unary.plus.quickfix=Remove unary '+' super.tear.down.in.finally.display.name='super.tearDown()' not called from 'finally' block super.tear.down.in.finally.problem.descriptor=#ref() not called from 'finally' block #loc -confusing.floating.point.literal.option=Ignore floating point literals in scientific notation \ No newline at end of file +confusing.floating.point.literal.option=Ignore floating point literals in scientific notation +class.may.be.interface.java8.option=Report classes containing non-abstract methods when using Java 8 \ No newline at end of file diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/ClassMayBeInterfaceInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/ClassMayBeInterfaceInspection.java index cbea503c54d5..ef76238402a6 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/ClassMayBeInterfaceInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/ClassMayBeInterfaceInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2014 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,9 @@ package com.siyeh.ig.classlayout; import com.intellij.codeInsight.FileModificationService; import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.WriteExternalException; import com.intellij.psi.*; import com.intellij.psi.search.SearchScope; import com.intellij.psi.search.searches.ClassInheritorsSearch; @@ -27,14 +29,19 @@ import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; +import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.swing.*; import java.util.ArrayList; import java.util.List; public class ClassMayBeInterfaceInspection extends BaseInspection { + @SuppressWarnings("PublicField") + public boolean reportClassesWithNonAbstractMethods = false; + @Override @NotNull public String getDisplayName() { @@ -47,6 +54,20 @@ public class ClassMayBeInterfaceInspection extends BaseInspection { return InspectionGadgetsBundle.message("class.may.be.interface.problem.descriptor"); } + @Nullable + @Override + public JComponent createOptionsPanel() { + return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message("class.may.be.interface.java8.option"), this, + "reportClassesWithNonAbstractMethods"); + } + + @Override + public void writeSettings(@NotNull Element node) throws WriteExternalException { + if (reportClassesWithNonAbstractMethods) { + node.addContent(new Element("option").setAttribute("name", "reportClassesWithNonAbstractMethods").setAttribute("value", "true")); + } + } + @Override protected InspectionGadgetsFix buildFix(Object... infos) { return new ClassMayBeInterfaceFix(); @@ -172,7 +193,7 @@ public class ClassMayBeInterfaceInspection extends BaseInspection { return new ClassMayBeInterfaceVisitor(); } - private static class ClassMayBeInterfaceVisitor extends BaseInspectionVisitor { + private class ClassMayBeInterfaceVisitor extends BaseInspectionVisitor { @Override public void visitClass(@NotNull PsiClass aClass) { @@ -192,7 +213,7 @@ public class ClassMayBeInterfaceInspection extends BaseInspection { registerClassError(aClass); } - public static boolean mayBeInterface(PsiClass aClass) { + public boolean mayBeInterface(PsiClass aClass) { final PsiReferenceList extendsList = aClass.getExtendsList(); if (extendsList != null) { final PsiJavaCodeReferenceElement[] extendsElements = extendsList.getReferenceElements(); @@ -207,7 +228,7 @@ public class ClassMayBeInterfaceInspection extends BaseInspection { return allMethodsPublicAbstract(aClass) && allFieldsPublicStaticFinal(aClass) && allInnerClassesPublic(aClass); } - private static boolean allFieldsPublicStaticFinal(PsiClass aClass) { + private boolean allFieldsPublicStaticFinal(PsiClass aClass) { boolean allFieldsStaticFinal = true; final PsiField[] fields = aClass.getFields(); for (final PsiField field : fields) { @@ -219,10 +240,11 @@ public class ClassMayBeInterfaceInspection extends BaseInspection { return allFieldsStaticFinal; } - private static boolean allMethodsPublicAbstract(PsiClass aClass) { + private boolean allMethodsPublicAbstract(PsiClass aClass) { final PsiMethod[] methods = aClass.getMethods(); for (final PsiMethod method : methods) { - if (!PsiUtil.isLanguageLevel8OrHigher(aClass) && !method.hasModifierProperty(PsiModifier.ABSTRACT)) { + if (!method.hasModifierProperty(PsiModifier.ABSTRACT) && + (!reportClassesWithNonAbstractMethods || !PsiUtil.isLanguageLevel8OrHigher(aClass))) { return false; } else if (!method.hasModifierProperty(PsiModifier.PUBLIC) || method.hasModifierProperty(PsiModifier.FINAL)) { @@ -232,7 +254,7 @@ public class ClassMayBeInterfaceInspection extends BaseInspection { return true; } - private static boolean allInnerClassesPublic(PsiClass aClass) { + private boolean allInnerClassesPublic(PsiClass aClass) { final PsiClass[] innerClasses = aClass.getInnerClasses(); for (PsiClass innerClass : innerClasses) { if (!innerClass.hasModifierProperty(PsiModifier.PUBLIC)) { diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassMayBeInterface.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassMayBeInterface.html index c4ccc3271202..b28a88b76f9a 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassMayBeInterface.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassMayBeInterface.html @@ -4,9 +4,11 @@ Reports abstract classes which can be converted to interfaces. A class may be converted to an interface if it has no superclass (other than Object), has no fields declared that are not static, final, and public, and has no methods declared that are not public and abstract and no inner classes that are not public. -When using a language level of 8.0 or higher classes containing static and non-static methods will also be reported.

+Use the checkbox below to report classes containing static methods and non-abstract methods which can be converted to default + methods, when using a language level of 8 or higher . +

\ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/classlayout/ClassMayBeInterfaceInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/classlayout/ClassMayBeInterfaceInspectionTest.java index 7fbf87c254cd..1eca1dfa8e51 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/classlayout/ClassMayBeInterfaceInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/classlayout/ClassMayBeInterfaceInspectionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -48,6 +48,8 @@ public class ClassMayBeInterfaceInspectionTest extends LightInspectionTestCase { } @Override protected InspectionProfileEntry getInspection() { - return new ClassMayBeInterfaceInspection(); + final ClassMayBeInterfaceInspection inspection = new ClassMayBeInterfaceInspection(); + inspection.reportClassesWithNonAbstractMethods = true; + return inspection; } } From 530cb96829a66222ff754e9fda4cc70c4a2cf1ed Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 25 Aug 2015 18:36:47 +0300 Subject: [PATCH 063/246] [vfs] more accurate Windows short name detection (IDEA-144285) --- .../vfs/impl/local/LocalFileSystemBase.java | 20 ++++++------ .../intellij/openapi/util/io/FileUtil.java | 31 ++++++++++++++++++- .../openapi/util/io/FileUtilLightTest.java | 17 ++++++++++ 3 files changed, 56 insertions(+), 12 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java index 0e249c5d6089..a4136a37a384 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java @@ -74,8 +74,8 @@ public abstract class LocalFileSystemBase extends LocalFileSystem { @Override public VirtualFile findFileByIoFile(@NotNull File file) { - String path = file.getAbsolutePath(); - return findFileByPath(path.replace(File.separatorChar, '/')); + String path = FileUtil.toSystemIndependentName(file.getAbsolutePath()); + return findFileByPath(path); } @NotNull @@ -197,13 +197,11 @@ public abstract class LocalFileSystemBase extends LocalFileSystem { path = path.substring(1); // hack over new File(path).toURI().toURL().getFile() } - if (path.contains("~")) { - try { - path = new File(FileUtil.toSystemDependentName(path)).getCanonicalPath(); - } - catch (IOException e) { - return null; - } + try { + path = FileUtil.resolveShortWindowsName(path); + } + catch (IOException e) { + return null; } } @@ -227,8 +225,8 @@ public abstract class LocalFileSystemBase extends LocalFileSystem { @Override public VirtualFile refreshAndFindFileByIoFile(@NotNull File file) { - String path = file.getAbsolutePath(); - return refreshAndFindFileByPath(path.replace(File.separatorChar, '/')); + String path = FileUtil.toSystemIndependentName(file.getAbsolutePath()); + return refreshAndFindFileByPath(path); } @Override diff --git a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java index 89da3d1c7f31..4ee0f9be1b9d 100644 --- a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java +++ b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java @@ -1016,6 +1016,7 @@ public class FileUtil extends FileUtilRt { * Use {@link FileUtilRt#getExtension(String)} instead to get the unchanged extension. * If you need to check whether a file has a specified extension use {@link FileUtilRt#extensionEquals(String, String)} */ + @SuppressWarnings("StringToUpperCaseOrToLowerCaseWithoutLocale") @NotNull public static String getExtension(@NotNull String fileName) { return FileUtilRt.getExtension(fileName).toLowerCase(); @@ -1023,7 +1024,31 @@ public class FileUtil extends FileUtilRt { @NotNull public static String resolveShortWindowsName(@NotNull String path) throws IOException { - return SystemInfo.isWindows && StringUtil.containsChar(path, '~') ? new File(path).getCanonicalPath() : path; + return SystemInfo.isWindows && containsWindowsShortName(path) ? new File(path).getCanonicalPath() : path; + } + + public static boolean containsWindowsShortName(@NotNull String path) { + if (StringUtil.containsChar(path, '~')) { + path = toSystemIndependentName(path); + + int start = 0; + while (start < path.length()) { + int end = path.indexOf('/', start); + if (end < 0) end = path.length(); + + // "How Windows Generates 8.3 File Names from Long File Names", https://support.microsoft.com/en-us/kb/142982 + int dot = path.lastIndexOf('.', end); + if (dot < start) dot = end; + if (dot - start > 2 && dot - start <= 8 && end - dot - 1 <= 3 && + path.charAt(dot - 2) == '~' && Character.isDigit(path.charAt(dot - 1))) { + return true; + } + + start = end + 1; + } + } + + return false; } public static void collectMatchedFiles(@NotNull File root, @NotNull Pattern pattern, @NotNull List outFiles) { @@ -1672,4 +1697,8 @@ public class FileUtil extends FileUtilRt { FileAttributes lower = FileSystemUtil.getAttributes(path.toLowerCase(Locale.ENGLISH)); return !(attributes.equals(upper) && attributes.equals(lower)); } + + public static boolean isWindowsShortName(@NotNull String fileName) { + return false; + } } diff --git a/platform/util/testSrc/com/intellij/openapi/util/io/FileUtilLightTest.java b/platform/util/testSrc/com/intellij/openapi/util/io/FileUtilLightTest.java index 747c5c79a129..820d1f328669 100644 --- a/platform/util/testSrc/com/intellij/openapi/util/io/FileUtilLightTest.java +++ b/platform/util/testSrc/com/intellij/openapi/util/io/FileUtilLightTest.java @@ -214,4 +214,21 @@ public class FileUtilLightTest { assertThat(FileUtil.sanitizeFileName("a+b+c")).isEqualTo("a_b_c"); } + + @Test + public void windowsShortName() { + assertTrue(FileUtil.containsWindowsShortName("C:\\dir~1")); + assertTrue(FileUtil.containsWindowsShortName("C:\\dir~1\\")); + assertTrue(FileUtil.containsWindowsShortName("C:\\dir~1\\file.txt")); + assertTrue(FileUtil.containsWindowsShortName("C:/dir/file~1")); + assertTrue(FileUtil.containsWindowsShortName("C:/dir/file~1.txt")); + assertTrue(FileUtil.containsWindowsShortName("C:/dir/file~1.1")); + + assertFalse(FileUtil.containsWindowsShortName("~")); + assertFalse(FileUtil.containsWindowsShortName("C:\\some~dir")); + assertFalse(FileUtil.containsWindowsShortName("C:\\some-dir~1")); + assertFalse(FileUtil.containsWindowsShortName("C:/dir/file~1.extension")); + assertFalse(FileUtil.containsWindowsShortName("C:/dir/file.~1")); + assertFalse(FileUtil.containsWindowsShortName("C:/dir/file.ext~1")); + } } From 6193a63ddbb4761bb62a578039e24ab5b0b2f77d Mon Sep 17 00:00:00 2001 From: Daniil Ovchinnikov Date: Tue, 25 Aug 2015 18:28:18 +0300 Subject: [PATCH 064/246] [groovy] static trait method generic return type fixed (& test) --- .../groovy/lang/psi/impl/synthetic/GrTraitMethod.java | 9 +++++++++ .../groovy/lang/resolve/ResolveMethodTest.groovy | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrTraitMethod.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrTraitMethod.java index a5dc08910bee..6f40467d3cc8 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrTraitMethod.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrTraitMethod.java @@ -17,13 +17,22 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.synthetic; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiSubstitutor; +import com.intellij.psi.PsiType; /** * Created by Max Medvedev on 25/04/14 */ public class GrTraitMethod extends GrMethodWrapper { + private final PsiSubstitutor mySubstitutor; + protected GrTraitMethod(PsiMethod method, PsiSubstitutor substitutor) { super(method, substitutor); + mySubstitutor = substitutor; + } + + @Override + public PsiType getReturnType() { + return mySubstitutor.substitute(super.getReturnType()); } public static GrTraitMethod create(PsiMethod method, PsiSubstitutor substitutor) { diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy index e63557be967d..2dd52c720175 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy @@ -2222,4 +2222,14 @@ class X { ''', PsiMethod) } + void 'test static trait method generic return type'() { + def method = resolveByText(''' +trait GenericSourceTrait { + static E someOtherStaticMethod() {null} +} +class SourceConcrete implements GenericSourceTrait {}) +SourceConcrete.someOtherStaticMethod() +''', GrTraitMethod) + assertEquals "java.lang.String", method.returnType.canonicalText + } } From a1f054ff7ad0a8b27d602ab16765490c27f4ea27 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Tue, 25 Aug 2015 18:45:13 +0300 Subject: [PATCH 065/246] Paths are normalized, so it should be reflected in UI. --- platform/util/src/com/intellij/util/PathMappingSettings.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/util/src/com/intellij/util/PathMappingSettings.java b/platform/util/src/com/intellij/util/PathMappingSettings.java index d5b9683a136d..00c3f00d5df6 100644 --- a/platform/util/src/com/intellij/util/PathMappingSettings.java +++ b/platform/util/src/com/intellij/util/PathMappingSettings.java @@ -263,11 +263,11 @@ public class PathMappingSettings extends AbstractPathMapper implements Cloneable } public void setLocalRoot(@Nullable String localRoot) { - myLocalRoot = localRoot; + myLocalRoot = normalize(localRoot); } public void setRemoteRoot(@Nullable String remoteRoot) { - myRemoteRoot = remoteRoot; + myRemoteRoot = normalize(remoteRoot); } @NotNull From 87692ecb0526c10b713e7a3638bb72e324710731 Mon Sep 17 00:00:00 2001 From: "liana.bakradze" Date: Tue, 25 Aug 2015 18:46:52 +0300 Subject: [PATCH 066/246] excluded python helpers from frames view --- .../com/jetbrains/python/edu/debugger/PyEduDebugProcess.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/python/edu/src/com/jetbrains/python/edu/debugger/PyEduDebugProcess.java b/python/edu/src/com/jetbrains/python/edu/debugger/PyEduDebugProcess.java index 0904ec772846..4783df316a85 100644 --- a/python/edu/src/com/jetbrains/python/edu/debugger/PyEduDebugProcess.java +++ b/python/edu/src/com/jetbrains/python/edu/debugger/PyEduDebugProcess.java @@ -4,6 +4,7 @@ import com.google.common.base.Predicate; import com.google.common.collect.Collections2; import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.ui.ExecutionConsole; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.xdebugger.XDebugSession; import com.jetbrains.python.PythonHelpersLocator; import com.jetbrains.python.debugger.*; @@ -55,12 +56,12 @@ class PyEduDebugProcess extends PyDebugProcess { if (frames == null) { return Collections.emptyList(); } - final String debugger = PythonHelpersLocator.getHelperPath(PyDebugRunner.DEBUGGER_MAIN); + final String helpersPath = PythonHelpersLocator.getHelpersRoot().getPath(); return Collections2.filter(frames, new Predicate() { @Override public boolean apply(PyStackFrameInfo frame) { String file = frame.getPosition().getFile(); - return !debugger.equals(file); + return !FileUtil.isAncestor(helpersPath, file, false); } }); } From 8867cbff2fb94ef6b26cd49f1b5ad3af6104e4ce Mon Sep 17 00:00:00 2001 From: Alexander Zolotov Date: Tue, 25 Aug 2015 18:47:40 +0300 Subject: [PATCH 067/246] Revert "Simplify retrieving messageBus" This reverts commit 3b04b8a71c29f552ac7a4414115db078a72c353a. --- .../service/project/autoimport/ExternalSystemAutoImporter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/autoimport/ExternalSystemAutoImporter.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/autoimport/ExternalSystemAutoImporter.java index e120cf6a10af..008f66403e7d 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/autoimport/ExternalSystemAutoImporter.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/autoimport/ExternalSystemAutoImporter.java @@ -155,7 +155,7 @@ public class ExternalSystemAutoImporter implements BulkFileListener, DocumentLis entries ); final MessageBus messageBus = project.getMessageBus(); - messageBus.connect().subscribe(VirtualFileManager.VFS_CHANGES, autoImporter); + messageBus.connect(project).subscribe(VirtualFileManager.VFS_CHANGES, autoImporter); EditorFactory.getInstance().getEventMulticaster().addDocumentListener(autoImporter, project); } From ac2acc315ae55bd46303ffb8ffbc18a85cbfe6ff Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Tue, 25 Aug 2015 18:53:27 +0300 Subject: [PATCH 068/246] Don't remove the slash if it is the only one. --- platform/util/src/com/intellij/util/PathMappingSettings.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/util/src/com/intellij/util/PathMappingSettings.java b/platform/util/src/com/intellij/util/PathMappingSettings.java index 00c3f00d5df6..7c88128cf6fc 100644 --- a/platform/util/src/com/intellij/util/PathMappingSettings.java +++ b/platform/util/src/com/intellij/util/PathMappingSettings.java @@ -299,7 +299,10 @@ public class PathMappingSettings extends AbstractPathMapper implements Cloneable return isAnyEmpty(myLocalRoot, myRemoteRoot); } - private static String trimSlash(String s) { + private static String trimSlash(@NotNull String s) { + if (s.equals("/")) { + return s; + } return StringUtil.trimEnd(s, "/"); } From bcfbe7bb4aeff7b897a7079d395b355ee0d5d8a1 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Tue, 25 Aug 2015 18:14:47 +0300 Subject: [PATCH 069/246] diff: remove unused parameter --- .../vcs/changes/patch/ApplyPatchAction.java | 47 +++++++++---------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchAction.java index fffaf894ca53..3a2a8ad5aefb 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchAction.java @@ -167,7 +167,7 @@ public class ApplyPatchAction extends DumbAwareAction { return showMergeDialog(project, file, mergeData.getBase(), mergeData.getPatched(), reverse, leftPanelTitle, rightPanelTitle); } else { - return showBadDiffDialog(project, file, mergeData, false); + return showBadDiffDialog(project, file, mergeData); } } @@ -250,8 +250,7 @@ public class ApplyPatchAction extends DumbAwareAction { @NotNull private static ApplyPatchStatus showBadDiffDialog(@Nullable Project project, @NotNull VirtualFile file, - @NotNull final ApplyPatchForBaseRevisionTexts texts, - boolean readonly) { + @NotNull final ApplyPatchForBaseRevisionTexts texts) { final Document document = FileDocumentManager.getInstance().getDocument(file); if (texts.getLocal() == null || document == null) return ApplyPatchStatus.FAILURE; @@ -277,28 +276,26 @@ public class ApplyPatchAction extends DumbAwareAction { DiffUtil.addNotification(new DiffIsApproximateNotification(), request); final DiffDialogHints dialogHints = new DiffDialogHints(WindowWrapper.Mode.MODAL); - if (!readonly) { - dialogHints.setCancelAction(new BooleanGetter() { - @Override - public boolean get() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - document.setText(oldContent); - FileDocumentManager.getInstance().saveDocument(document); - } - }); - return true; - } - }); - dialogHints.setOkAction(new BooleanGetter() { - @Override - public boolean get() { - FileDocumentManager.getInstance().saveDocument(document); - return true; - } - }); - } + dialogHints.setCancelAction(new BooleanGetter() { + @Override + public boolean get() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + document.setText(oldContent); + FileDocumentManager.getInstance().saveDocument(document); + } + }); + return true; + } + }); + dialogHints.setOkAction(new BooleanGetter() { + @Override + public boolean get() { + FileDocumentManager.getInstance().saveDocument(document); + return true; + } + }); DiffManager.getInstance().showDiff(project, request, dialogHints); From f226b597e4154d4f53e88d3475cb9fabeb440866 Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Tue, 25 Aug 2015 11:06:34 +0200 Subject: [PATCH 070/246] IDEA-144300 Copy Reference for source folder/content root copies empty string CPP-4315 "Edit | Copy Reference" result doesn't contain the file name --- .../CopyReferenceActionFilesTest.groovy | 127 ++++++++++++++++++ ....groovy => CopyReferenceActionTest.groovy} | 14 +- .../ide/actions/CopyReferenceAction.java | 20 ++- 3 files changed, 149 insertions(+), 12 deletions(-) create mode 100644 java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceActionFilesTest.groovy rename java/java-tests/testSrc/com/intellij/codeInsight/{CopyReferenceTest.groovy => CopyReferenceActionTest.groovy} (93%) diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceActionFilesTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceActionFilesTest.groovy new file mode 100644 index 000000000000..ee2d8b299986 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceActionFilesTest.groovy @@ -0,0 +1,127 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight + +import com.intellij.ide.actions.CopyReferenceAction +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.openapi.vfs.VirtualFileManager +import com.intellij.psi.PsiManager +import com.intellij.testFramework.PsiTestUtil + +public class CopyReferenceActionFilesTest extends CodeInsightTestCase { + VirtualFile additionalRoot + + @Override + protected void setUp() throws Exception { + super.setUp(); + + ApplicationManager.application.runWriteAction(new Runnable() { + @Override + void run() { + additionalRoot = VirtualFileManager.getInstance().findFileByUrl("temp:///").createChildDirectory(this, "newRoot"); + } + }) + } + + @Override + protected void tearDown() throws Exception { + try { + ApplicationManager.application.runWriteAction(new Runnable() { + @Override + void run() { + additionalRoot.delete(this) + } + }) + } + finally { + super.tearDown(); + } + } + + public void testCopyFile_RegisteredAsSourceRoots_ShouldContainItsName() throws Exception { + // CPP-4315 "Edit | Copy Reference" result doesn't contain the file name + + VirtualFile dir + VirtualFile dir_subfile + VirtualFile file + + ApplicationManager.application.runWriteAction(new Runnable() { + @Override + void run() { + dir = additionalRoot.createChildDirectory(this, "dir"); + dir_subfile = dir.createChildData(this, "dir_subfile.txt"); + file = additionalRoot.createChildData(this, "file.txt"); + + PsiTestUtil.addContentRoot(getModule(), additionalRoot); + PsiTestUtil.addSourceRoot(getModule(), dir); + PsiTestUtil.addSourceRoot(getModule(), file); + } + }) + + assertEquals("dir", CopyReferenceAction.elementToFqn(PsiManager.getInstance(project).findDirectory(dir))); + assertEquals("dir_subfile.txt", CopyReferenceAction.elementToFqn(PsiManager.getInstance(project).findFile(dir_subfile))); + assertEquals("file.txt", CopyReferenceAction.elementToFqn(PsiManager.getInstance(project).findFile(file))); + } + + public void testCopyFile_RegisteredAsContentRoot_ShouldContainItsFullPath() throws Exception { + // IDEA-144300 Copy Reference for source folder/content root copies empty string + + VirtualFile dir + VirtualFile dir_subfile + VirtualFile file + + ApplicationManager.application.runWriteAction(new Runnable() { + @Override + void run() { + dir = additionalRoot.createChildDirectory(this, "dir"); + dir_subfile = dir.createChildData(this, "dir_subfile.txt"); + file = additionalRoot.createChildData(this, "file.txt"); + + PsiTestUtil.addContentRoot(getModule(), dir); + PsiTestUtil.addContentRoot(getModule(), file); + } + }) + + assertEquals(dir.getPath(), CopyReferenceAction.elementToFqn(PsiManager.getInstance(project).findDirectory(dir))); + assertEquals("dir_subfile.txt", CopyReferenceAction.elementToFqn(PsiManager.getInstance(project).findFile(dir_subfile))); + assertEquals(file.getPath(), CopyReferenceAction.elementToFqn(PsiManager.getInstance(project).findFile(file))); + } + + public void testCopyFile_RegisteredAsNestedContentRoot_ShouldContainPathFromOuterMostRoot() throws Exception { + // IDEA-144300 Copy Reference for source folder/content root copies empty string + + VirtualFile dir + VirtualFile dir_dir + VirtualFile dir_dir_file + + ApplicationManager.application.runWriteAction(new Runnable() { + @Override + void run() { + dir = additionalRoot.createChildDirectory(this, "dir"); + dir_dir = dir.createChildDirectory(this, "dir_dir"); + dir_dir_file = dir_dir.createChildData(this, "file.txt"); + + PsiTestUtil.addContentRoot(getModule(), dir); + PsiTestUtil.addContentRoot(getModule(), dir_dir); + } + }) + + assertEquals(dir.getPath(), CopyReferenceAction.elementToFqn(PsiManager.getInstance(project).findDirectory(dir))); + assertEquals("dir_dir", CopyReferenceAction.elementToFqn(PsiManager.getInstance(project).findDirectory(dir_dir))); + assertEquals("dir_dir/file.txt", CopyReferenceAction.elementToFqn(PsiManager.getInstance(project).findFile(dir_dir_file))); + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceActionTest.groovy similarity index 93% rename from java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceTest.groovy rename to java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceActionTest.groovy index a5ef7e03d287..773ab0ab74a0 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceActionTest.groovy @@ -1,14 +1,14 @@ package com.intellij.codeInsight -import com.intellij.JavaTestUtil; -import com.intellij.ide.actions.CopyReferenceAction; -import com.intellij.openapi.actionSystem.ActionManager; -import com.intellij.openapi.actionSystem.IdeActions; -import com.intellij.psi.PsiFile; -import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; +import com.intellij.JavaTestUtil +import com.intellij.ide.actions.CopyReferenceAction +import com.intellij.openapi.actionSystem.ActionManager +import com.intellij.openapi.actionSystem.IdeActions +import com.intellij.psi.PsiFile +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase import org.jetbrains.annotations.NonNls -public class CopyReferenceTest extends LightCodeInsightFixtureTestCase { +public class CopyReferenceActionTest extends LightCodeInsightFixtureTestCase { @NonNls private static final String BASE_PATH = "/codeInsight/copyReference"; protected int oldSetting; diff --git a/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java b/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java index 4dffefbd5454..b3fb0e52f2df 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java @@ -35,6 +35,7 @@ import com.intellij.openapi.ide.CopyPasteManager; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; @@ -282,14 +283,23 @@ public class CopyReferenceAction extends DumbAwareAction { private static String getVirtualFileFqn(@NotNull VirtualFile virtualFile, @NotNull Project project) { final LogicalRoot logicalRoot = LogicalRootsManager.getLogicalRootsManager(project).findLogicalRoot(virtualFile); - if (logicalRoot != null && logicalRoot.getVirtualFile() != null) { - return ObjectUtils.assertNotNull(VfsUtilCore.getRelativePath(virtualFile, logicalRoot.getVirtualFile(), '/')); + VirtualFile logicalRootFile = logicalRoot != null ? logicalRoot.getVirtualFile() : null; + if (logicalRootFile != null && !virtualFile.equals(logicalRootFile)) { + return ObjectUtils.assertNotNull(VfsUtilCore.getRelativePath(virtualFile, logicalRootFile, '/')); } - final VirtualFile contentRoot = ProjectRootManager.getInstance(project).getFileIndex().getContentRootForFile(virtualFile); - if (contentRoot != null) { - return ObjectUtils.assertNotNull(VfsUtilCore.getRelativePath(virtualFile, contentRoot, '/')); + VirtualFile outerMostRoot = null; + VirtualFile each = virtualFile; + ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex(); + while (each != null && (each = index.getContentRootForFile(each)) != null) { + outerMostRoot = each; + each = each.getParent(); } + + if (outerMostRoot != null && !outerMostRoot.equals(virtualFile)) { + return ObjectUtils.assertNotNull(VfsUtilCore.getRelativePath(virtualFile, outerMostRoot, '/')); + } + return virtualFile.getPath(); } } From 3ef6388d968ff84967f5e30b464f43975c409445 Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Tue, 25 Aug 2015 12:45:27 +0200 Subject: [PATCH 071/246] IDEA-144316 Copy Reference should work for excluded subfolders same way as it works for regular project subdirs --- .../CopyReferenceActionFilesTest.groovy | 24 +++++++++++++++++++ .../ide/actions/CopyReferenceAction.java | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceActionFilesTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceActionFilesTest.groovy index ee2d8b299986..2820da2fd78d 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceActionFilesTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceActionFilesTest.groovy @@ -124,4 +124,28 @@ public class CopyReferenceActionFilesTest extends CodeInsightTestCase { assertEquals("dir_dir", CopyReferenceAction.elementToFqn(PsiManager.getInstance(project).findDirectory(dir_dir))); assertEquals("dir_dir/file.txt", CopyReferenceAction.elementToFqn(PsiManager.getInstance(project).findFile(dir_dir_file))); } + + public void testCopyFile_UnderExcludeRoot_ShouldContainPathFromTheCorrespondingContentRoot() throws Exception { + // IDEA-144316 Copy Reference should work for excluded subfolders same way as it works for regular project subdirs + + VirtualFile dir + VirtualFile dir_dir + VirtualFile dir_dir_file + + ApplicationManager.application.runWriteAction(new Runnable() { + @Override + void run() { + dir = additionalRoot.createChildDirectory(this, "dir"); + dir_dir = dir.createChildDirectory(this, "dir_dir"); + dir_dir_file = dir_dir.createChildData(this, "file.txt"); + + PsiTestUtil.addContentRoot(getModule(), dir); + PsiTestUtil.addExcludedRoot(getModule(), dir_dir); + } + }) + + assertEquals(dir.getPath(), CopyReferenceAction.elementToFqn(PsiManager.getInstance(project).findDirectory(dir))); + assertEquals("dir_dir", CopyReferenceAction.elementToFqn(PsiManager.getInstance(project).findDirectory(dir_dir))); + assertEquals("dir_dir/file.txt", CopyReferenceAction.elementToFqn(PsiManager.getInstance(project).findFile(dir_dir_file))); + } } diff --git a/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java b/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java index b3fb0e52f2df..bf2ade88ec78 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java @@ -291,7 +291,7 @@ public class CopyReferenceAction extends DumbAwareAction { VirtualFile outerMostRoot = null; VirtualFile each = virtualFile; ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex(); - while (each != null && (each = index.getContentRootForFile(each)) != null) { + while (each != null && (each = index.getContentRootForFile(each, false)) != null) { outerMostRoot = each; each = each.getParent(); } From 8bd481f989b1a78e39235c73dbab14c7517e2bdf Mon Sep 17 00:00:00 2001 From: "liana.bakradze" Date: Tue, 25 Aug 2015 19:44:43 +0300 Subject: [PATCH 072/246] EDU-407 Files created by user code are invisible --- .../jetbrains/edu/learning/StudyTaskManager.java | 9 +++++++++ .../edu/learning/actions/StudyRunAction.java | 1 + .../learning/courseGeneration/StudyGenerator.java | 2 ++ .../projectView/StudyTreeStructureProvider.java | 15 +++++++++++++++ 4 files changed, 27 insertions(+) diff --git a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyTaskManager.java b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyTaskManager.java index 5ca158f09fe5..22130fe1a1f5 100644 --- a/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyTaskManager.java +++ b/python/educational/interactive-learning/src/com/jetbrains/edu/learning/StudyTaskManager.java @@ -36,6 +36,7 @@ public class StudyTaskManager implements PersistentStateComponent myStudyStatusMap = new HashMap(); public Map myTaskStatusMap = new HashMap(); public Map> myUserTests = new HashMap>(); + public List myInvisibleFiles = new ArrayList(); private StudyTaskManager() { } @@ -184,4 +185,12 @@ public class StudyTaskManager implements PersistentStateComponent nodes, + @NotNull final AbstractTreeNode node, + @NotNull final Project project, + @NotNull final VirtualFile virtualFile) { + if (!StudyTaskManager.getInstance(project).isInvisibleFile(virtualFile.getPath())) { + String fileName = virtualFile.getName(); + if (!fileName.contains(EduNames.WINDOW_POSTFIX) && !fileName.contains(EduNames.WINDOWS_POSTFIX)) { + nodes.add(node); + } + } + } + protected boolean isCourseBasedProject(@NotNull final AbstractTreeNode parent) { final Project project = parent.getProject(); if (project != null) { From 3f7d533d0a48fd0c21761fcfbb1caa8307354bfe Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 25 Aug 2015 19:21:28 +0300 Subject: [PATCH 073/246] use owr own shutdown hook to delete temp folders marked as deleteOnExit --- .../intellij/openapi/util/io/FileUtilRt.java | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java b/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java index 457da71ca778..061e263310a6 100644 --- a/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java +++ b/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java @@ -32,7 +32,9 @@ import java.nio.channels.FileChannel; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; +import java.util.Queue; import java.util.UUID; +import java.util.concurrent.ConcurrentLinkedQueue; /** * Stripped-down version of {@code com.intellij.openapi.util.io.FileUtil}. @@ -298,7 +300,9 @@ public class FileUtilRt { boolean deleteOnExit) throws IOException { File file = doCreateTempFile(dir, prefix, suffix, true); if (deleteOnExit) { - file.deleteOnExit(); + //file.deleteOnExit(); + // default deleteOnExit does not remove dirs if they are not empty + FilesToDeleteHolder.ourFilesToDelete.add(file.getPath()); } if (!file.isDirectory()) { throw new IOException("Cannot create directory: " + file); @@ -306,6 +310,25 @@ public class FileUtilRt { return file; } + private static class FilesToDeleteHolder { + public static final Queue ourFilesToDelete = createFilesToDelete(); + + private static Queue createFilesToDelete() { + final ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue(); + Runtime.getRuntime().addShutdownHook(new Thread("FileUtil deleteOnExit") { + @Override + public void run() { + String name = queue.poll(); + while (name != null) { + delete(new File(name)); + name = queue.poll(); + } + } + }); + return queue; + } + } + @NotNull public static File createTempFile(@NotNull @NonNls String prefix, @Nullable @NonNls String suffix) throws IOException { return createTempFile(prefix, suffix, true); // deleteOnExit by default From 30e6ccc381cd622eb565edb5bcce892a36f3601c Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 25 Aug 2015 19:44:03 +0300 Subject: [PATCH 074/246] reverted deleteOnExit by default, see IDEA-CR-4563, introduced an inspection for that --- .../util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java b/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java index 061e263310a6..3dcb22f7ee52 100644 --- a/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java +++ b/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java @@ -331,7 +331,7 @@ public class FileUtilRt { @NotNull public static File createTempFile(@NotNull @NonNls String prefix, @Nullable @NonNls String suffix) throws IOException { - return createTempFile(prefix, suffix, true); // deleteOnExit by default + return createTempFile(prefix, suffix, false); //false until TeamCity fixes its plugin } @NotNull @@ -360,6 +360,7 @@ public class FileUtilRt { boolean create, boolean deleteOnExit) throws IOException { File file = doCreateTempFile(dir, prefix, suffix, false); if (deleteOnExit) { + //noinspection SSBasedInspection file.deleteOnExit(); } if (!create) { From 5654d16c30c11d4f4f87898c3e089d1f0dc2d2ba Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 25 Aug 2015 19:50:40 +0300 Subject: [PATCH 075/246] IDEA-CR-4589 (cleanup) --- platform/util/src/com/intellij/openapi/util/io/FileUtil.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java index 4ee0f9be1b9d..367745c2d5d4 100644 --- a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java +++ b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java @@ -1697,8 +1697,4 @@ public class FileUtil extends FileUtilRt { FileAttributes lower = FileSystemUtil.getAttributes(path.toLowerCase(Locale.ENGLISH)); return !(attributes.equals(upper) && attributes.equals(lower)); } - - public static boolean isWindowsShortName(@NotNull String fileName) { - return false; - } } From ac6c8c60e73c5e9249c4ce90379346012b2cddda Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Aug 2015 18:52:42 +0200 Subject: [PATCH 076/246] more VFS logging for blinking PerforceMoveRenameTest --- .../vfs/newvfs/persistent/PersistentFSImpl.java | 16 ++++++++++++---- .../vfs/newvfs/persistent/RefreshWorker.java | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java index da3d889bf7b0..d47bdd808339 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java @@ -1027,6 +1027,9 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone } private VirtualFileSystemEntry applyEvent(@NotNull VFileEvent event) { + if (LOG.isDebugEnabled()) { + LOG.debug("Applying " + event); + } try { if (event instanceof VFileCreateEvent) { final VFileCreateEvent createEvent = (VFileCreateEvent)event; @@ -1050,17 +1053,22 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone } else if (event instanceof VFilePropertyChangeEvent) { final VFilePropertyChangeEvent propertyChangeEvent = (VFilePropertyChangeEvent)event; + VirtualFile file = propertyChangeEvent.getFile(); + Object newValue = propertyChangeEvent.getNewValue(); if (VirtualFile.PROP_NAME.equals(propertyChangeEvent.getPropertyName())) { - executeRename(propertyChangeEvent.getFile(), (String)propertyChangeEvent.getNewValue()); + executeRename(file, (String)newValue); } else if (VirtualFile.PROP_WRITABLE.equals(propertyChangeEvent.getPropertyName())) { - executeSetWritable(propertyChangeEvent.getFile(), ((Boolean)propertyChangeEvent.getNewValue()).booleanValue()); + executeSetWritable(file, ((Boolean)newValue).booleanValue()); + if (LOG.isDebugEnabled()) { + LOG.debug("File " + file + " writable=" + file.isWritable()); + } } else if (VirtualFile.PROP_HIDDEN.equals(propertyChangeEvent.getPropertyName())) { - executeSetHidden(propertyChangeEvent.getFile(), ((Boolean)propertyChangeEvent.getNewValue()).booleanValue()); + executeSetHidden(file, ((Boolean)newValue).booleanValue()); } else if (VirtualFile.PROP_SYMLINK_TARGET.equals(propertyChangeEvent.getPropertyName())) { - executeSetTarget(propertyChangeEvent.getFile(), (String)propertyChangeEvent.getNewValue()); + executeSetTarget(file, (String)newValue); } } } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java index aee93ddac025..07fcc562978d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java @@ -147,7 +147,7 @@ public class RefreshWorker { boolean currentWritable = persistence.isWritable(file); boolean upToDateWritable = attributes.isWritable(); if (LOG_ATTRIBUTES.isDebugEnabled()) { - LOG_ATTRIBUTES.debug("file=%s writable vfs=%b persistence=%b real=%b", file, file.isWritable(), currentWritable, upToDateWritable); + LOG_ATTRIBUTES.debug("file=" + file + " writable vfs=" + file.isWritable() + " persistence=" + currentWritable + " real=" + upToDateWritable); } if (currentWritable != upToDateWritable) { scheduleAttributeChange(file, VirtualFile.PROP_WRITABLE, currentWritable, upToDateWritable); From 6075505e194476e98536b53260403bd4c7fb3b77 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Tue, 25 Aug 2015 18:45:29 +0300 Subject: [PATCH 077/246] TreeTraverser: EdgeFilter & guided traversal --- .../util/containers/TreeTraverserTest.java | 80 ++++++- .../containers/FilteredTraverserBase.java | 196 ++++++++++++++---- .../intellij/util/containers/JBIterable.java | 10 +- .../intellij/util/containers/JBIterator.java | 2 +- .../util/containers/TreeTraversal.java | 120 +++++++++-- 5 files changed, 341 insertions(+), 67 deletions(-) diff --git a/platform/platform-tests/testSrc/com/intellij/util/containers/TreeTraverserTest.java b/platform/platform-tests/testSrc/com/intellij/util/containers/TreeTraverserTest.java index fe4baed38dad..48e0a4e0d04b 100644 --- a/platform/platform-tests/testSrc/com/intellij/util/containers/TreeTraverserTest.java +++ b/platform/platform-tests/testSrc/com/intellij/util/containers/TreeTraverserTest.java @@ -17,6 +17,7 @@ package com.intellij.util.containers; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Conditions; +import com.intellij.util.Consumer; import com.intellij.util.Function; import com.intellij.util.Functions; import com.intellij.util.PairFunction; @@ -235,6 +236,43 @@ public class TreeTraverserTest extends TestCase { assertEquals(JBIterable.generate(1, INCREMENT).take(37).toList(), numTraverser2(TreeTraversal.PLAIN_BFS).fun(1).toList()); } + // GuidedTraversal ---------------------------------------------- + + @NotNull + private static Function.Mono> initGuide(@NotNull final TreeTraversal traversal) { + return new Function.Mono>() { + @Override + public TreeTraversal.GuidedIt fun(TreeTraversal.GuidedIt it) { + return it.setGuide(new Consumer>() { + @Override + public void consume(TreeTraversal.GuidedIt it) { + if (traversal == TreeTraversal.PRE_ORDER_DFS) { + it.queueNext(it.curChild).result(it.curChild); + } + else if (traversal == TreeTraversal.POST_ORDER_DFS) { + it.queueNext(it.curChild).result(it.curChild == null ? it.curParent : null); + } + else if (traversal == TreeTraversal.PLAIN_BFS) { + it.queueLast(it.curChild).result(it.curChild); + } + } + }); + } + }; + } + + public void testGuidedDfs() { + verifyGuidedTraversal(TreeTraversal.PRE_ORDER_DFS); + verifyGuidedTraversal(TreeTraversal.POST_ORDER_DFS); + verifyGuidedTraversal(TreeTraversal.PLAIN_BFS); + } + + private static void verifyGuidedTraversal(TreeTraversal traversal) { + assertEquals(numTraverser2(TreeTraversal.GUIDED_TRAVERSAL).fun(1).intercept(initGuide(traversal)).toList(), + numTraverser2(traversal).fun(1).toList()); + } + + // FilteredTraverser ---------------------------------------------- @NotNull @@ -259,28 +297,28 @@ public class TreeTraverserTest extends TestCase { public void testSkipExpandedDfs() { FilteredTraverser t = filteredTraverser(); - assertEquals(Arrays.asList(2, 8, 9, 10, 4), t.withRoot(1).expand(IS_ODD).leavesOnlyDfsTraversal().toList()); + assertEquals(Arrays.asList(2, 8, 9, 10, 4), t.withRoot(1).expand(IS_ODD).leavesDfsTraversal().toList()); } public void testRangeChildrenLeavesDfs() { FilteredTraverser t = filteredTraverser(); - assertEquals(Arrays.asList(5, 6, 3, 11, 12, 13), t.withRoot(1).children(Conditions.not(inRange(7, 10))).leavesOnlyDfsTraversal().toList()); + assertEquals(Arrays.asList(5, 6, 3, 11, 12, 13), t.withRoot(1).children(Conditions.not(inRange(7, 10))).leavesDfsTraversal().toList()); } public void testRangeChildrenLeavesBfs() { FilteredTraverser t = filteredTraverser(); - assertEquals(Arrays.asList(5, 6, 3, 11, 12, 13), t.withRoot(1).children(Conditions.not(inRange(7, 10))).leavesOnlyDfsTraversal().toList()); + assertEquals(Arrays.asList(5, 6, 3, 11, 12, 13), t.withRoot(1).children(Conditions.not(inRange(7, 10))).leavesDfsTraversal().toList()); } public void testSkipExpandedBfs() { FilteredTraverser t = filteredTraverser(); - assertEquals(Arrays.asList(2, 4, 8, 9, 10), t.withRoot(1).expand(IS_ODD).leavesOnlyBfsTraversal().toList()); + assertEquals(Arrays.asList(2, 4, 8, 9, 10), t.withRoot(1).expand(IS_ODD).leavesBfsTraversal().toList()); } public void testExpandSkipFilterReset() { FilteredTraverser t = filteredTraverser(); assertEquals(Arrays.asList(1, 5, 7, 3, 9, 11, 13), t.withRoot(1).expand(IS_ODD). - withTraversal(TreeTraversal.LEAVES_ONLY_DFS).reset().filter(IS_ODD).toList()); + withTraversal(TreeTraversal.LEAVES_DFS).reset().filter(IS_ODD).toList()); } public void testForceExlcudeReset() { @@ -295,7 +333,7 @@ public class TreeTraverserTest extends TestCase { public void testForceSkipLeavesDfs() { FilteredTraverser t = filteredTraverser(); - assertEquals(Arrays.asList(6, 8, 10, 12), t.withRoot(1).forceExpandAndSkip(IS_ODD).leavesOnlyDfsTraversal().toList()); + assertEquals(Arrays.asList(6, 8, 10, 12), t.withRoot(1).forceExpandAndSkip(IS_ODD).leavesDfsTraversal().toList()); } public void testFilterChildren() { @@ -327,4 +365,34 @@ public class TreeTraverserTest extends TestCase { assertEquals(Arrays.asList(21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1), cursor.backtrace().toList()); } + public void testEdgeFilter() { + FilteredTraverser t = filteredTraverser(); + JBIterable it = t.children(new FilteredTraverserBase.EdgeFilter() { + @Override + public boolean value(Integer integer) { + return (integer / curParent) % 2 == 0; + } + }).withRoot(1).traverse(); + assertEquals(Arrays.asList(1, 2, 5, 8, 10, 4, 11), it.toList()); + assertEquals(Arrays.asList(1, 2, 5, 8, 10, 4, 11), it.toList()); + } + + public void testStatefulChildFilter() { + FilteredTraverser t = filteredTraverser(); + class F extends JBIterable.StatefulFilter { + int count; + boolean value; + F(boolean initialVal) { value = initialVal; } + + public boolean value(Integer integer) { + return count ++ > 0 == value; + } + } + + JBIterable it = t.children(new F(true)).withRoot(1).traverse(); + assertEquals(Arrays.asList(1, 5, 6, 7, 3, 9, 10, 4, 12, 13), it.toList()); + assertEquals(Arrays.asList(1, 5, 6, 7, 3, 9, 10, 4, 12, 13), it.toList()); + assertEquals(it.toList(), t.forceExpandAndSkip(new F(false)).withRoot(1).reset().traverse().toList()); + } + } diff --git a/platform/util/src/com/intellij/util/containers/FilteredTraverserBase.java b/platform/util/src/com/intellij/util/containers/FilteredTraverserBase.java index 5e01284c0cd5..86c31037247c 100644 --- a/platform/util/src/com/intellij/util/containers/FilteredTraverserBase.java +++ b/platform/util/src/com/intellij/util/containers/FilteredTraverserBase.java @@ -16,6 +16,8 @@ package com.intellij.util.containers; import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Conditions; +import com.intellij.util.Consumer; import com.intellij.util.Function; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -24,7 +26,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; -import static com.intellij.openapi.util.Conditions.*; +import static com.intellij.openapi.util.Conditions.not; public abstract class FilteredTraverserBase> implements Iterable { @@ -62,7 +64,7 @@ public abstract class FilteredTraverserBase leavesOnlyDfsTraversal() { - return traverse(TreeTraversal.LEAVES_ONLY_DFS); + public final JBIterable leavesDfsTraversal() { + return traverse(TreeTraversal.LEAVES_DFS); } @NotNull @@ -96,13 +98,13 @@ public abstract class FilteredTraverserBase leavesOnlyBfsTraversal() { - return traverse(TreeTraversal.LEAVES_ONLY_BFS); + public final JBIterable leavesBfsTraversal() { + return traverse(TreeTraversal.LEAVES_BFS); } @NotNull public Self reset() { - return newInstance(Meta.empty().forceExclude(meta.forceExclude).forceExpandAndSkip(meta.forceExpandAndSkip).withRoots(meta.roots)); + return newInstance(meta.reset()); } @NotNull @@ -162,17 +164,20 @@ public abstract class FilteredTraverserBase children(@NotNull T node) { - if (isAlwaysLeaf(node)) return JBIterable.empty(); - JBIterable children = JBIterable.from(tree.fun(node)); - if (meta.childFilter == TRUE && meta.forceExpandAndSkip == Condition.FALSE) { - return children.filter(not(meta.forceExclude)); + if (isAlwaysLeaf(node)) { + return JBIterable.empty(); + } + else if (meta.childFilter.next == null && meta.forceExpandAndSkip.next == null) { + return JBIterable.from(tree.fun(node)).filter(not(meta.forceExclude.OR())); + } + else { + // traverse subtree to select accepted children + return TreeTraversal.GUIDED_TRAVERSAL.traversal(node, tree).intercept(meta.createChildrenGuide(node)); } - // traverse subtree to select accepted children - return newInstance(meta.forChildren(children)).traverse(); } protected boolean isAlwaysLeaf(@NotNull T node) { - return !meta.expandFilter.value(node); + return !meta.expandFilter.valueAnd(node); } @NotNull @@ -185,24 +190,30 @@ public abstract class FilteredTraverserBase extends JBIterable.StatefulFilter { + protected T curParent; + + } + + @SuppressWarnings("unchecked") protected static class Meta { final Iterable roots; final TreeTraversal traversal; - final Condition expandFilter; - final Condition childFilter; - final Condition resultFilter; + final Cond expandFilter; + final Cond childFilter; + final Cond resultFilter; - final Condition forceExclude; - final Condition forceExpandAndSkip; + final Cond forceExclude; + final Cond forceExpandAndSkip; public Meta(@NotNull Iterable roots, @NotNull TreeTraversal traversal, - @NotNull Condition expandFilter, - @NotNull Condition childFilter, - @NotNull Condition resultFilter, - @NotNull Condition forceExclude, - @NotNull Condition forceExpandAndSkip) { + @NotNull Cond expandFilter, + @NotNull Cond childFilter, + @NotNull Cond resultFilter, + @NotNull Cond forceExclude, + @NotNull Cond forceExpandAndSkip) { this.roots = roots; this.traversal = traversal; this.expandFilter = expandFilter; @@ -212,6 +223,10 @@ public abstract class FilteredTraverserBase reset() { + return new Meta(roots, TreeTraversal.PRE_ORDER_DFS, Cond.TRUE, Cond.TRUE, Cond.TRUE, forceExclude, forceExpandAndSkip); + } + public Meta withRoots(@NotNull Iterable roots) { return new Meta(roots, traversal, expandFilter, childFilter, resultFilter, forceExclude, forceExpandAndSkip); } @@ -221,42 +236,147 @@ public abstract class FilteredTraverserBase expand(@NotNull Condition filter) { - return new Meta(roots, traversal, and2(expandFilter, filter), childFilter, resultFilter, forceExclude, - forceExpandAndSkip); + return new Meta(roots, traversal, expandFilter.append(filter), childFilter, resultFilter, forceExclude, forceExpandAndSkip); } public Meta children(@NotNull Condition filter) { - return new Meta(roots, traversal, expandFilter, and2(childFilter, filter), resultFilter, forceExclude, - forceExpandAndSkip); + return new Meta(roots, traversal, expandFilter, childFilter.append(filter), resultFilter, forceExclude, forceExpandAndSkip); } public Meta filter(@NotNull Condition filter) { - return new Meta(roots, traversal, expandFilter, childFilter, and2(resultFilter, filter), forceExclude, - forceExpandAndSkip); + return new Meta(roots, traversal, expandFilter, childFilter, resultFilter.append(filter), forceExclude, forceExpandAndSkip); } // forceExclude and forceSkip filter is always accumulated public Meta forceExclude(Condition filter) { - return new Meta(roots, traversal, expandFilter, childFilter, resultFilter, or2(forceExclude, filter), - forceExpandAndSkip); + return new Meta(roots, traversal, expandFilter, childFilter, resultFilter, forceExclude.append(filter), forceExpandAndSkip); } public Meta forceExpandAndSkip(Condition filter) { - return new Meta(roots, traversal, expandFilter, childFilter, resultFilter, forceExclude, or2(forceExpandAndSkip, filter)); + return new Meta(roots, traversal, expandFilter, childFilter, resultFilter, forceExclude, forceExpandAndSkip.append(filter)); } - public Meta forChildren(JBIterable children) { - Condition expand = or2(forceExpandAndSkip, not(childFilter)); - return new Meta(children, TreeTraversal.LEAVES_ONLY_DFS, expand, TRUE, not(or2(expand, forceExclude)), FALSE, FALSE); + Function.Mono> createChildrenGuide(final T parent) { + final Condition expand = buildExpandConditionForChildren(parent); + class G implements Consumer>, Function.Mono> { + + @Override + public TreeTraversal.GuidedIt fun(TreeTraversal.GuidedIt it) { + return it.setGuide(this); + } + + @Override + public void consume(TreeTraversal.GuidedIt it) { + doPerformChildrenGuidance(it, expand); + } + } + return new G(); + } + + private void doPerformChildrenGuidance(TreeTraversal.GuidedIt it, Condition expand) { + if (it.curChild == null) return; + if (forceExclude.valueOr(it.curChild)) return; + if (it.curParent == null || expand.value(it.curChild)) { + it.queueNext(it.curChild); + } + else { + it.result(it.curChild); + } + } + + private Condition buildExpandConditionForChildren(T parent) { + // implement: or2(forceExpandAndSkip, not(childFilter)); + // and handle JBIterable.StatefulTransform and EdgeFilter conditions + Cond copy = null; + boolean invert = true; + Cond c = childFilter; + while (c != null) { + Condition impl = JBIterable.Stateful.copy(c.impl); + if (impl != (invert ? Condition.TRUE : Condition.FALSE)) { + copy = new Cond(invert ? not(impl) : impl, copy); + if (impl instanceof EdgeFilter) { + ((EdgeFilter)impl).curParent = parent; + } + } + if (c.next == null) { + c = invert ? forceExpandAndSkip : null; + invert = false; + } + else { + c = c.next; + } + } + return copy == null ? Condition.FALSE : copy.OR(); } private static final Meta EMPTY = new Meta( JBIterable.empty(), TreeTraversal.PRE_ORDER_DFS, - TRUE, TRUE, TRUE, - FALSE, FALSE); + Cond.TRUE, Cond.TRUE, Cond.TRUE, + Cond.FALSE, Cond.FALSE); public static Meta empty() { return (Meta)EMPTY; } + } + + private static class Cond { + final static Cond TRUE = new Cond(Conditions.TRUE, null); + final static Cond FALSE = new Cond(Conditions.FALSE, null); + + final Condition impl; + final Cond next; + + Cond(Condition impl, Cond next) { + this.impl = impl; + this.next = next; + } + + Cond append(Condition impl) { + return new Cond(impl, this); + } + + private boolean valueAnd(T t) { + for (Cond c = this; c != null; c = c.next) { + if (!c.impl.value(t)) return false; + } + return true; + } + + private boolean valueOr(T t) { + for (Cond c = this; c != null; c = c.next) { + if (c.impl.value(t)) return true; + } + return false; + } + + Condition OR() { + return new Condition() { + @Override + public boolean value(T t) { + return valueOr(t); + } + }; + } + + Condition AND() { + return new Condition() { + @Override + public boolean value(T t) { + return valueAnd(t); + } + }; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("Cond{"); + for (Cond c = this; c != null; c = c.next) { + sb.append(JBIterator.toShortString(c.impl)); + if (c.next != null) sb.append(", "); + } + return sb.append("}").toString(); + } + } + } diff --git a/platform/util/src/com/intellij/util/containers/JBIterable.java b/platform/util/src/com/intellij/util/containers/JBIterable.java index 9893805e5bca..aa82ccda6540 100644 --- a/platform/util/src/com/intellij/util/containers/JBIterable.java +++ b/platform/util/src/com/intellij/util/containers/JBIterable.java @@ -58,10 +58,12 @@ import java.util.*; * .toList();} *

*

Anything which can be done using {@code JBIterable} could be done in a different fashion - * (often with {@link Iterables}), however the use of {@code JBIterable} makes many sets of + * (often with {@code Iterables}), however the use of {@code JBIterable} makes many sets of * operations significantly more concise. * * @author Marcin Mikosik + * + * @noinspection unchecked */ public abstract class JBIterable implements Iterable { @@ -270,7 +272,6 @@ public abstract class JBIterable implements Iterable { * @param type the type of elements desired */ public final JBIterable filter(@NotNull Class type) { - //noinspection unchecked return (JBIterable)filter(Conditions.instanceOf(type)); } @@ -371,13 +372,13 @@ public abstract class JBIterable implements Iterable { * The most generic iterator transformation. */ @NotNull - public final JBIterable intercept(@NotNull final Function, Iterator> function) { + public final > JBIterable intercept(@NotNull final Function> function) { if (this == EMPTY) return empty(); final JBIterable thisIterable = this; return new JBIterable() { @Override public Iterator iterator() { - return function.fun(thisIterable.iterator()); + return function.fun((X)thisIterable.iterator()); } }; } @@ -459,7 +460,6 @@ public abstract class JBIterable implements Iterable { return collection; } - @SuppressWarnings("unchecked") public abstract static class Stateful implements Cloneable { @NotNull diff --git a/platform/util/src/com/intellij/util/containers/JBIterator.java b/platform/util/src/com/intellij/util/containers/JBIterator.java index ababafdf6474..0edb914742d1 100644 --- a/platform/util/src/com/intellij/util/containers/JBIterator.java +++ b/platform/util/src/com/intellij/util/containers/JBIterator.java @@ -232,7 +232,7 @@ public abstract class JBIterator implements Iterator { }); } - private static String toShortString(@NotNull Object o) { + static String toShortString(@NotNull Object o) { String fqn = o.getClass().getName(); return StringUtil.replace(o.toString(), fqn, StringUtil.getShortName(fqn, '.')); } diff --git a/platform/util/src/com/intellij/util/containers/TreeTraversal.java b/platform/util/src/com/intellij/util/containers/TreeTraversal.java index 87258b7c75a2..76e7aae5f7e8 100644 --- a/platform/util/src/com/intellij/util/containers/TreeTraversal.java +++ b/platform/util/src/com/intellij/util/containers/TreeTraversal.java @@ -16,6 +16,7 @@ package com.intellij.util.containers; import com.intellij.openapi.util.Condition; +import com.intellij.util.Consumer; import com.intellij.util.Function; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -115,17 +116,36 @@ public abstract class TreeTraversal { public abstract JBIterable backtrace(); } - @NotNull - private static Iterable children(@NotNull T root, @NotNull Function> tree) { - return JBIterable.from(tree.fun(root)); + public static abstract class GuidedIt extends It { + @Nullable + public T curChild, curParent; + @Nullable + public Iterable curChildren; + public boolean curNoChildren; + + public abstract GuidedIt setGuide(Consumer> guide); + + public abstract GuidedIt queueNext(T child); + public abstract GuidedIt queueLast(T child); + public abstract GuidedIt result(T node); + } + @NotNull + public static final TreeTraversal GUIDED_TRAVERSAL = new TreeTraversal("GUIDED_TRAVERSAL") { + @NotNull + @Override + public It createIterator(@NotNull Iterable roots, @NotNull Function> tree) { + return new GuidedItImpl(roots, tree); + } + }; + /** * Returns an iterator over the nodes in a tree structure, using pre-order * traversal. That is, each node's subtrees are traversed after the node itself is returned. * *

No guarantees are made about the behavior of the traversal when nodes change while - * iteration is in progress or when the iterators generated by {@link #children} are advanced. + * iteration is in progress or when the iterators generated by {@code tree} are advanced. */ @NotNull public static final TreeTraversal PRE_ORDER_DFS = new TreeTraversal("PRE_ORDER_DFS") { @@ -141,7 +161,7 @@ public abstract class TreeTraversal { * traversal. That is, each node's subtrees are traversed before the node itself is returned. *

*

No guarantees are made about the behavior of the traversal when nodes change while - * iteration is in progress or when the iterators generated by {@link #children} are advanced. + * iteration is in progress or when the iterators generated by {@code tree} are advanced. */ @NotNull public static final TreeTraversal POST_ORDER_DFS = new TreeTraversal("POST_ORDER_DFS") { @@ -154,7 +174,7 @@ public abstract class TreeTraversal { @NotNull - public static final TreeTraversal LEAVES_ONLY_DFS = new TreeTraversal("LEAVES_ONLY_DFS") { + public static final TreeTraversal LEAVES_DFS = new TreeTraversal("LEAVES_DFS") { @NotNull @Override public It createIterator(@NotNull Iterable roots, @NotNull Function> tree) { @@ -167,7 +187,7 @@ public abstract class TreeTraversal { * traversal. That is, all the nodes of depth 0 are returned, then depth 1, then 2, and so on. *

*

No guarantees are made about the behavior of the traversal when nodes change while - * iteration is in progress or when the iterators generated by {@link #children} are advanced. + * iteration is in progress or when the iterators generated by {@code tree} are advanced. */ @NotNull public static final TreeTraversal PLAIN_BFS = new TreeTraversal("PLAIN_BFS") { @@ -188,7 +208,7 @@ public abstract class TreeTraversal { }; @NotNull - public static final TreeTraversal LEAVES_ONLY_BFS = new TreeTraversal("LEAVES_ONLY_BFS") { + public static final TreeTraversal LEAVES_BFS = new TreeTraversal("LEAVES_BFS") { @NotNull @Override public It createIterator(@NotNull Iterable roots, @NotNull Function> tree) { @@ -198,7 +218,7 @@ public abstract class TreeTraversal { // ----------------------------------------------------------------------------- - // Iterators + // Iterators: DFS // ----------------------------------------------------------------------------- private abstract static class DfsIt extends TracingIt { @@ -303,6 +323,10 @@ public abstract class TreeTraversal { } } + // ----------------------------------------------------------------------------- + // Iterators: BFS + // ----------------------------------------------------------------------------- + private static final class BfsIterator extends It { final Function> tree; @@ -317,7 +341,7 @@ public abstract class TreeTraversal { public T nextImpl() { if (queue.isEmpty()) return stop(); T result = queue.remove(); - for (T t : children(result, tree)) queue.add(t); + JBIterable.from(tree.fun(result)).addAllTo(queue); return result; } } @@ -336,9 +360,10 @@ public abstract class TreeTraversal { public T nextImpl() { while (!queue.isEmpty()) { T result = queue.remove(); - Iterator childrenIt = children(result, tree).iterator(); - if (!childrenIt.hasNext()) return result; - while (childrenIt.hasNext()) queue.add(childrenIt.next()); + Iterable children = tree.fun(result); + Iterator it = children == null ? null: children.iterator(); + if (it == null || !it.hasNext()) return result; + while (it.hasNext()) queue.add(it.next()); } return stop(); } @@ -360,7 +385,7 @@ public abstract class TreeTraversal { public T nextImpl() { if (queue.isEmpty()) return stop(); T result = queue.remove(); - for (T t : children(result, tree)) { + for (T t : JBIterable.from(tree.fun(result))) { if (paths.containsKey(t)) continue; queue.add(t); paths.put(t, result); @@ -395,7 +420,68 @@ public abstract class TreeTraversal { }; } } - + + // ----------------------------------------------------------------------------- + // Misc + // ----------------------------------------------------------------------------- + private static final class GuidedItImpl extends GuidedIt { + final ArrayDeque> stack = new ArrayDeque>(); + final Function> tree; + + Consumer> guide; + T curResult; + + GuidedItImpl(@NotNull Iterable roots, Function> tree) { + this.tree = tree; + stack.addLast(P.create(roots)); + } + + public GuidedIt setGuide(Consumer> guide) { + this.guide = guide; + return this; + } + + public GuidedIt queueNext(T child) { + if (child != null) stack.addLast(P.create(child)); + return this; + } + + public GuidedIt queueLast(T child) { + if (child != null) stack.addFirst(P.create(child)); + return this; + } + + public GuidedIt result(T node) { + curResult = node; + return this; + } + + @Override + public T nextImpl() { + if (guide == null) return stop(); + while (!stack.isEmpty()) { + P top = stack.getLast(); + Iterator it = top.iterator(tree); + boolean hasNext = it.hasNext(); + curResult = null; + if (top.node != null || hasNext) { + curChild = hasNext ? it.next() : null; + curParent = top.node; + curChildren = top.itle; + curNoChildren = top.empty; + guide.consume(this); + } + if (!hasNext) { + stack.removeLast(); + } + if (curResult != null) { + return curResult; + } + } + return stop(); + } + } + private static class P { T node; Iterable itle; @@ -404,8 +490,8 @@ public abstract class TreeTraversal { Iterator iterator(@NotNull Function> tree) { if (it != null) return it; - it = (itle != null ? itle : (itle = children(node, tree))).iterator(); - empty = !it.hasNext(); + it = (itle != null ? itle : JBIterable.from(itle = tree.fun(node))).iterator(); + empty = itle == null || !it.hasNext(); return it; } From 85bea6141bf5d3013b573b37e62905cbaf72924d Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 25 Aug 2015 20:22:01 +0300 Subject: [PATCH 078/246] Cleanup (sane overload; warnings; typos; pointless annotations) --- .../migration/MigrationMapSet.java | 4 +- .../src/SchemeManagerImpl.kt | 2 +- .../testFramework/TemporaryDirectory.kt | 2 +- .../intellij/openapi/util/io/FileUtilRt.java | 1 + .../intellij/openapi/util/io/FileUtil.java | 78 +++++++++---------- .../util/UniqueFileNamesProvider.java | 6 +- .../src/settings/IcsSettings.kt | 17 +++- 7 files changed, 60 insertions(+), 50 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/migration/MigrationMapSet.java b/java/java-impl/src/com/intellij/refactoring/migration/MigrationMapSet.java index da55fd30befa..4c1a640a0e92 100644 --- a/java/java-impl/src/com/intellij/refactoring/migration/MigrationMapSet.java +++ b/java/java-impl/src/com/intellij/refactoring/migration/MigrationMapSet.java @@ -1,6 +1,6 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -239,7 +239,7 @@ public class MigrationMapSet { for(int i = 0; i < myMaps.size(); i++){ MigrationMap map = myMaps.get(i); - filePaths[i] = dir + File.separator + namesProvider.generateUniqueName(FileUtil.sanitizeName(map.getName())) + ".xml"; + filePaths[i] = dir + File.separator + namesProvider.generateUniqueName(FileUtil.sanitizeFileName(map.getName(), false)) + ".xml"; documents[i] = saveMap(map); } diff --git a/platform/configuration-store-impl/src/SchemeManagerImpl.kt b/platform/configuration-store-impl/src/SchemeManagerImpl.kt index 7ec4890f0548..48bc88175a2a 100644 --- a/platform/configuration-store-impl/src/SchemeManagerImpl.kt +++ b/platform/configuration-store-impl/src/SchemeManagerImpl.kt @@ -508,7 +508,7 @@ public class SchemeManagerImpl(private val var fileNameWithoutExtension = currentFileNameWithoutExtension if (fileNameWithoutExtension == null || isRenamed(scheme)) { - fileNameWithoutExtension = nameGenerator.generateUniqueName(FileUtil.sanitizeName(scheme.getName())) + fileNameWithoutExtension = nameGenerator.generateUniqueName(FileUtil.sanitizeFileName(scheme.getName(), false)) } val newHash = JDOMUtil.getTreeHash(element!!, true) diff --git a/platform/testFramework/testSrc/com/intellij/testFramework/TemporaryDirectory.kt b/platform/testFramework/testSrc/com/intellij/testFramework/TemporaryDirectory.kt index fd18b1aebbfa..816255b1afbf 100644 --- a/platform/testFramework/testSrc/com/intellij/testFramework/TemporaryDirectory.kt +++ b/platform/testFramework/testSrc/com/intellij/testFramework/TemporaryDirectory.kt @@ -35,7 +35,7 @@ public class TemporaryDirectory : ExternalResource() { private var sanitizedName: String? = null override fun apply(base: Statement, description: Description): Statement { - sanitizedName = FileUtil.sanitizeName(description.getMethodName()) + sanitizedName = FileUtil.sanitizeFileName(description.getMethodName(), false) return super.apply(base, description) } diff --git a/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java b/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java index 3dcb22f7ee52..173c099c118c 100644 --- a/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java +++ b/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java @@ -797,6 +797,7 @@ public class FileUtilRt { return path.isDirectory() || path.mkdirs(); } + @SuppressWarnings("Duplicates") public static void copy(@NotNull File fromFile, @NotNull File toFile) throws IOException { if (!ensureCanCreateFile(toFile)) { return; diff --git a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java index 367745c2d5d4..d980bf0eac7d 100644 --- a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java +++ b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java @@ -46,7 +46,8 @@ public class FileUtil extends FileUtilRt { static { if (!Patches.USE_REFLECTION_TO_ACCESS_JDK7) throw new RuntimeException("Please migrate FileUtilRt to JDK8"); } - @NonNls public static final String ASYNC_DELETE_EXTENSION = ".__del__"; + + public static final String ASYNC_DELETE_EXTENSION = ".__del__"; public static final int REGEX_PATTERN_FLAGS = SystemInfo.isFileSystemCaseSensitive ? 0 : Pattern.CASE_INSENSITIVE; @@ -417,7 +418,7 @@ public class FileUtil extends FileUtilRt { private static File getTempFile(@NotNull String originalFileName, @NotNull String parent) { int randomSuffix = (int)(System.currentTimeMillis() % 1000); for (int i = randomSuffix; ; i++) { - @NonNls String name = "___" + originalFileName + i + ASYNC_DELETE_EXTENSION; + String name = "___" + originalFileName + i + ASYNC_DELETE_EXTENSION; File tempFile = new File(parent, name); if (!tempFile.exists()) return tempFile; } @@ -470,6 +471,7 @@ public class FileUtil extends FileUtilRt { performCopy(fromFile, toFile, false); } + @SuppressWarnings("Duplicates") private static void performCopy(@NotNull File fromFile, @NotNull File toFile, final boolean syncTimestamp) throws IOException { final FileOutputStream fos; try { @@ -619,7 +621,7 @@ public class FileUtil extends FileUtilRt { return FileUtilRt.getNameWithoutExtension(name); } - public static String createSequentFileName(@NotNull File aParentFolder, @NotNull @NonNls String aFilePrefix, @NotNull String aExtension) { + public static String createSequentFileName(@NotNull File aParentFolder, @NotNull String aFilePrefix, @NotNull String aExtension) { return findSequentNonexistentFile(aParentFolder, aFilePrefix, aExtension).getName(); } @@ -635,17 +637,18 @@ public class FileUtil extends FileUtilRt { } @NotNull - public static String toSystemDependentName(@NonNls @NotNull String aFileName) { + public static String toSystemDependentName(@NotNull String aFileName) { return FileUtilRt.toSystemDependentName(aFileName); } @NotNull - public static String toSystemIndependentName(@NonNls @NotNull String aFileName) { + public static String toSystemIndependentName(@NotNull String aFileName) { return FileUtilRt.toSystemIndependentName(aFileName); } - @NotNull - public static String nameToCompare(@NonNls @NotNull String name) { + /** @deprecated to be removed in IDEA 17 */ + @SuppressWarnings({"unused", "StringToUpperCaseOrToLowerCaseWithoutLocale"}) + public static String nameToCompare(@NotNull String name) { return (SystemInfo.isFileSystemCaseSensitive ? name : name.toLowerCase()).replace('\\', '/'); } @@ -1148,7 +1151,7 @@ public class FileUtil extends FileUtilRt { builder.append(ch); } - // handle ant shorthand: mypackage/test/ is interpreted as if it were mypackage/test/** + // handle ant shorthand: my_package/test/ is interpreted as if it were my_package/test/** final boolean isTrailingSlash = builder.length() > 0 && builder.charAt(builder.length() - 1) == '/'; if (asteriskCount == 0 && isTrailingSlash || recursive && asteriskCount == 2) { if (isTrailingSlash) { @@ -1185,26 +1188,21 @@ public class FileUtil extends FileUtilRt { return success; } - /** - * Has duplicate: {@link com.intellij.coverage.listeners.CoverageListener#sanitize(java.lang.String, java.lang.String)} - * as FileUtil is not available in client's vm - */ @NotNull public static String sanitizeFileName(@NotNull String name) { return sanitizeFileName(name, true); } - /** - * Difference - not only letter or digit allowed, but space, @, - - */ - @NotNull + /** @deprecated use {@link #sanitizeFileName(String, boolean)} (to be removed in IDEA 17) */ + @SuppressWarnings("unused") public static String sanitizeName(@NotNull String name) { return sanitizeFileName(name, false); } @NotNull - private static String sanitizeFileName(@NotNull String name, boolean strict) { + public static String sanitizeFileName(@NotNull String name, boolean strict) { StringBuilder result = null; + int last = 0; int length = name.length(); for (int i = 0; i < length; i++) { @@ -1238,6 +1236,7 @@ public class FileUtil extends FileUtilRt { if (last < length) { result.append(name, last, length); } + return result.toString(); } @@ -1368,13 +1367,8 @@ public class FileUtil extends FileUtilRt { } File providedFile = new File(providedPath); - if (providedFile.exists()) { - String name = providedFile.getName(); - for (String fileName : fileNames) { - if (name.equals(fileName)) { - return toSystemDependentName(providedFile.getPath()); - } - } + if (providedFile.exists() && ArrayUtil.indexOf(fileNames, providedFile.getName()) >= 0) { + return toSystemDependentName(providedFile.getPath()); } if (providedFile.isDirectory()) { //user chose folder with file @@ -1462,56 +1456,56 @@ public class FileUtil extends FileUtilRt { } @NotNull - public static File createTempDirectory(@NotNull @NonNls String prefix, @Nullable @NonNls String suffix) throws IOException { + public static File createTempDirectory(@NotNull String prefix, @Nullable String suffix) throws IOException { return FileUtilRt.createTempDirectory(prefix, suffix); } @NotNull - public static File createTempDirectory(@NotNull @NonNls String prefix, @Nullable @NonNls String suffix, boolean deleteOnExit) + public static File createTempDirectory(@NotNull String prefix, @Nullable String suffix, boolean deleteOnExit) throws IOException { return FileUtilRt.createTempDirectory(prefix, suffix, deleteOnExit); } @NotNull - public static File createTempDirectory(@NotNull File dir, @NotNull @NonNls String prefix, @Nullable @NonNls String suffix) + public static File createTempDirectory(@NotNull File dir, @NotNull String prefix, @Nullable String suffix) throws IOException { return FileUtilRt.createTempDirectory(dir, prefix, suffix); } @NotNull public static File createTempDirectory(@NotNull File dir, - @NotNull @NonNls String prefix, - @Nullable @NonNls String suffix, + @NotNull String prefix, + @Nullable String suffix, boolean deleteOnExit) throws IOException { return FileUtilRt.createTempDirectory(dir, prefix, suffix, deleteOnExit); } @NotNull - public static File createTempFile(@NotNull @NonNls String prefix, @Nullable @NonNls String suffix) throws IOException { + public static File createTempFile(@NotNull String prefix, @Nullable String suffix) throws IOException { return FileUtilRt.createTempFile(prefix, suffix); } @NotNull - public static File createTempFile(@NotNull @NonNls String prefix, @Nullable @NonNls String suffix, boolean deleteOnExit) + public static File createTempFile(@NotNull String prefix, @Nullable String suffix, boolean deleteOnExit) throws IOException { return FileUtilRt.createTempFile(prefix, suffix, deleteOnExit); } @NotNull - public static File createTempFile(@NonNls File dir, @NotNull @NonNls String prefix, @Nullable @NonNls String suffix) throws IOException { + public static File createTempFile(File dir, @NotNull String prefix, @Nullable String suffix) throws IOException { return FileUtilRt.createTempFile(dir, prefix, suffix); } @NotNull - public static File createTempFile(@NonNls File dir, @NotNull @NonNls String prefix, @Nullable @NonNls String suffix, boolean create) + public static File createTempFile(File dir, @NotNull String prefix, @Nullable String suffix, boolean create) throws IOException { return FileUtilRt.createTempFile(dir, prefix, suffix, create); } @NotNull - public static File createTempFile(@NonNls File dir, - @NotNull @NonNls String prefix, - @Nullable @NonNls String suffix, + public static File createTempFile(File dir, + @NotNull String prefix, + @Nullable String suffix, boolean create, boolean deleteOnExit) throws IOException { return FileUtilRt.createTempFile(dir, prefix, suffix, create, deleteOnExit); @@ -1553,16 +1547,16 @@ public class FileUtil extends FileUtilRt { } @NotNull - public static String loadFile(@NotNull File file, @Nullable @NonNls String encoding) throws IOException { + public static String loadFile(@NotNull File file, @Nullable String encoding) throws IOException { return FileUtilRt.loadFile(file, encoding); } @NotNull - public static String loadFile(@NotNull File file, @NotNull @NonNls Charset encoding) throws IOException { + public static String loadFile(@NotNull File file, @NotNull Charset encoding) throws IOException { return String.valueOf(FileUtilRt.loadFileText(file, encoding)); } @NotNull - public static String loadFile(@NotNull File file, @Nullable @NonNls String encoding, boolean convertLineSeparators) throws IOException { + public static String loadFile(@NotNull File file, @Nullable String encoding, boolean convertLineSeparators) throws IOException { return FileUtilRt.loadFile(file, encoding, convertLineSeparators); } @@ -1572,7 +1566,7 @@ public class FileUtil extends FileUtilRt { } @NotNull - public static char[] loadFileText(@NotNull File file, @Nullable @NonNls String encoding) throws IOException { + public static char[] loadFileText(@NotNull File file, @Nullable String encoding) throws IOException { return FileUtilRt.loadFileText(file, encoding); } @@ -1587,7 +1581,7 @@ public class FileUtil extends FileUtilRt { } @NotNull - public static List loadLines(@NotNull File file, @Nullable @NonNls String encoding) throws IOException { + public static List loadLines(@NotNull File file, @Nullable String encoding) throws IOException { return FileUtilRt.loadLines(file, encoding); } @@ -1597,7 +1591,7 @@ public class FileUtil extends FileUtilRt { } @NotNull - public static List loadLines(@NotNull String path, @Nullable @NonNls String encoding) throws IOException { + public static List loadLines(@NotNull String path, @Nullable String encoding) throws IOException { return FileUtilRt.loadLines(path, encoding); } diff --git a/platform/util/src/com/intellij/util/UniqueFileNamesProvider.java b/platform/util/src/com/intellij/util/UniqueFileNamesProvider.java index 08245922bdea..2774661843a2 100644 --- a/platform/util/src/com/intellij/util/UniqueFileNamesProvider.java +++ b/platform/util/src/com/intellij/util/UniqueFileNamesProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -33,7 +33,7 @@ public class UniqueFileNamesProvider { } public String suggestName(String originalName) { - String s = FileUtil.sanitizeName(originalName); + String s = FileUtil.sanitizeFileName(originalName, false); if (!contains(s)) { myExistingNames.add(s); return s; @@ -58,7 +58,7 @@ public class UniqueFileNamesProvider { } public static String convertName(String s) { - return FileUtil.sanitizeName(s); + return FileUtil.sanitizeFileName(s, false); } public void reserveFileName(final String fileName) { diff --git a/plugins/settings-repository/src/settings/IcsSettings.kt b/plugins/settings-repository/src/settings/IcsSettings.kt index 082ea5522582..47f127543b5e 100644 --- a/plugins/settings-repository/src/settings/IcsSettings.kt +++ b/plugins/settings-repository/src/settings/IcsSettings.kt @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2015 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 org.jetbrains.settingsRepository import com.fasterxml.jackson.annotation.JsonIgnore @@ -90,7 +105,7 @@ class ReadonlySource(var url: String? = null, var active: Boolean = true) { fileName = fileName.substring(0, fileName.length() - suffix.length()) } // the convention is that the .git extension should be used for bare repositories - return "${FileUtil.sanitizeName(fileName)}.${Integer.toHexString(url!!.hashCode())}.git" + return "${FileUtil.sanitizeFileName(fileName, false)}.${Integer.toHexString(url!!.hashCode())}.git" } } } \ No newline at end of file From 0bf5ad7a76de713b9ac6d18550abd480259bdc68 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Tue, 25 Aug 2015 18:58:18 +0300 Subject: [PATCH 079/246] don't show warning message in Quick Doc popup if javadoc was generated from sources (following IDEA-143699) --- .../javadoc/JavaDocInfoGenerator.java | 55 ++++++++++++---- ...JdkClassWhenExternalDocIsNotAvailable.html | 64 +++++++++++++++++++ .../javadoc/JavaDocInfoGeneratorTest.java | 14 +++- 3 files changed, 120 insertions(+), 13 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/javadocIG/documentationForJdkClassWhenExternalDocIsNotAvailable.html diff --git a/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java b/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java index afb99f98519d..9176e09dbc09 100644 --- a/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java +++ b/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java @@ -29,6 +29,8 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.JavaSdk; import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.roots.PackageIndex; +import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.Pair; @@ -383,23 +385,52 @@ public class JavaDocInfoGenerator { return null; if (docURLs != null) { - if (buffer.length() == 0) { - buffer.append(""); + if (elementHasSourceCode()) { + LOG.debug("Documentation for " + myElement + " was generated from source code, it wasn't found at following URLs: ", docURLs); + } + else { + if (buffer.length() == 0) { + buffer.append(""); + } + String errorSection = "

Following external urls were checked:
   " + + StringUtil.join(docURLs, new Function() { + @Override + public String fun(String url) { + return XmlStringUtil.escapeString(url); + } + }, "
   ") + + "
The documentation for this element is not found. Please add all the needed paths to API docs in " + + "Project Settings.

"; + buffer.insert(buffer.indexOf(""), errorSection); } - String errorSection = "

Following external urls were checked:
   " + - StringUtil.join(docURLs, new Function() { - @Override - public String fun(String url) { - return XmlStringUtil.escapeString(url); - } - }, "
   ") + - "
The documentation for this element is not found. Please add all the needed paths to API docs in " + - "Project Settings.

"; - buffer.insert(buffer.indexOf(""), errorSection); } return fixupDoc(buffer); } + private boolean elementHasSourceCode() { + VirtualFile[] files; + if (myElement instanceof PsiDirectory) { + final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage((PsiDirectory)myElement); + if (aPackage == null) return false; + files = PackageIndex.getInstance(myProject).getDirectoriesByPackageName(aPackage.getQualifiedName(), true); + } + else if (myElement instanceof PsiPackage) { + files = PackageIndex.getInstance(myProject).getDirectoriesByPackageName(((PsiPackage)myElement).getQualifiedName(), true); + } + else { + PsiFile containingFile = myElement.getNavigationElement().getContainingFile(); + if (containingFile == null) return false; + VirtualFile virtualFile = containingFile.getVirtualFile(); + if (virtualFile == null) return false; + files = new VirtualFile[] {virtualFile}; + } + ProjectFileIndex projectFileIndex = ProjectFileIndex.SERVICE.getInstance(myProject); + for (VirtualFile file : files) { + if (projectFileIndex.isInSource(file)) return true; + } + return false; + } + private void generateClassJavaDoc(@NonNls StringBuilder buffer, PsiClass aClass, boolean generatePrologueAndEpilogue) { if (aClass instanceof PsiAnonymousClass) return; if (generatePrologueAndEpilogue) diff --git a/java/java-tests/testData/codeInsight/javadocIG/documentationForJdkClassWhenExternalDocIsNotAvailable.html b/java/java-tests/testData/codeInsight/javadocIG/documentationForJdkClassWhenExternalDocIsNotAvailable.html new file mode 100644 index 000000000000..f601876a818d --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadocIG/documentationForJdkClassWhenExternalDocIsNotAvailable.html @@ -0,0 +1,64 @@ + java.lang
public final class String
+extends java.lang.Object
+implements java.io.Serializable, java.lang.Comparable<String>, java.lang.CharSequence
+ The String class represents character strings. All + string literals in Java programs, such as "abc", are + implemented as instances of this class. +

+ Strings are constant; their values cannot be changed after they + are created. String buffers support mutable strings. + Because String objects are immutable they can be shared. For example: +

+       String str = "abc";
+   

+ is equivalent to: +

+       char data[] = {'a', 'b', 'c'};
+       String str = new String(data);
+   

+ Here are some more examples of how strings can be used: +

+       System.out.println("abc");
+       String cde = "cde";
+       System.out.println("abc" + cde);
+       String c = "abc".substring(2,3);
+       String d = cde.substring(1, 2);
+   
+

+ The class String includes methods for examining + individual characters of the sequence, for comparing strings, for + searching strings, for extracting substrings, and for creating a + copy of a string with all characters translated to uppercase or to + lowercase. Case mapping is based on the Unicode Standard version + specified by the Character class. +

+ The Java language provides special support for the string + concatenation operator ( + ), and for conversion of + other objects to strings. String concatenation is implemented + through the StringBuilder(or StringBuffer) + class and its append method. + String conversions are implemented through the method + toString, defined by Object and + inherited by all classes in Java. For additional information on + string concatenation and conversion, see Gosling, Joy, and Steele, + The Java Language Specification. + +

Unless otherwise noted, passing a null argument to a constructor + or method in this class will cause a NullPointerException to be + thrown. + +

A String represents a string in the UTF-16 format + in which supplementary characters are represented by surrogate + pairs (see the section Unicode + Character Representations in the Character class for + more information). + Index values refer to char code units, so a supplementary + character uses two positions in a String. +

The String class provides methods for dealing with + Unicode code points (i.e., characters), in addition to those for + dealing with Unicode code units (i.e., char values). + +

Since:
JDK1.0
See Also:
Object.toString(), +StringBuffer, +StringBuilder, +java.nio.charset.Charset
\ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java index 6e5f94a36540..e12a8e628eda 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java @@ -29,6 +29,8 @@ import com.intellij.testFramework.PsiTestUtil; import java.io.File; import java.io.IOException; +import java.util.Collections; +import java.util.List; /** * @author yole @@ -220,7 +222,11 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase { } private void verifyJavaDoc(final PsiElement field) throws IOException { - String docInfo = new JavaDocInfoGenerator(getProject(), field).generateDocInfo(null); + verifyJavaDoc(field, null); + } + + private void verifyJavaDoc(final PsiElement field, List docUrls) throws IOException { + String docInfo = new JavaDocInfoGenerator(getProject(), field).generateDocInfo(docUrls); assertNotNull(docInfo); assertEquals(exampleHtmlFileText(getTestName(true)), replaceEnvironmentDependentContent(docInfo)); } @@ -291,6 +297,12 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase { PsiMethod method = psiClass.getMethods()[0]; verifyJavaDoc(method); } + + public void testDocumentationForJdkClassWhenExternalDocIsNotAvailable() throws Exception { + PsiClass aClass = JavaPsiFacade.getInstance(myProject).findClass("java.lang.String", GlobalSearchScope.allScope(myProject)); + assertNotNull(aClass); + verifyJavaDoc(aClass, Collections.singletonList("dummyUrl")); + } @Override protected String getTestDataPath() { From 55df687635abd3e2cf2e0981192cc8f2f46b65e8 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Tue, 25 Aug 2015 20:28:53 +0300 Subject: [PATCH 080/246] enable showing javadoc for packages in library sources --- .../javadoc/JavaDocInfoGenerator.java | 5 ++- .../codeInsight/documentation/library-src.jar | Bin 0 -> 1465 bytes .../libraryPackageDocumentation.html | 2 ++ .../JavaExternalDocumentationTest.java | 2 +- .../javadoc/JavaDocInfoGeneratorTest.java | 30 ++++++++++++++++++ 5 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/documentation/library-src.jar create mode 100644 java/java-tests/testData/codeInsight/javadocIG/libraryPackageDocumentation.html diff --git a/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java b/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java index 9176e09dbc09..2637e6e1e91e 100644 --- a/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java +++ b/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java @@ -683,7 +683,10 @@ public class JavaDocInfoGenerator { } private void generatePackageJavaDoc(final StringBuilder buffer, final PsiPackage psiPackage, boolean generatePrologueAndEpilogue) { - for(PsiDirectory directory: psiPackage.getDirectories()) { + VirtualFile[] dirs = PackageIndex.getInstance(myProject).getDirectoriesByPackageName(psiPackage.getQualifiedName(), true); + for (VirtualFile dir : dirs) { + PsiDirectory directory = PsiManager.getInstance(myProject).findDirectory(dir); + if (directory == null) continue; final PsiFile packageInfoFile = directory.findFile(PsiPackage.PACKAGE_INFO_FILE); if (packageInfoFile != null) { final ASTNode node = packageInfoFile.getNode(); diff --git a/java/java-tests/testData/codeInsight/documentation/library-src.jar b/java/java-tests/testData/codeInsight/documentation/library-src.jar new file mode 100644 index 0000000000000000000000000000000000000000..423bc77ce8d71f5c63d685433b383b5bd7a85df1 GIT binary patch literal 1465 zcmWIWW@h1HVBlb2aGEFS&VU417+4sR^K=)PI{D-knrH^ zmjX_vON$iF9Ar_s>eb7~qGPC0CQF@{ef#=&c%*;t{I9Z!>E|3)xrs-4 zcxu`mXMC*q*CnzbVd?VjKS&jc6{r_zJ<5z#T8+w;}*?(@<{{KGq$Cho+ zr<7)`YqR;?IQ5gZ%51SKCsfW<9K82!?XB6h?Q?jKbIF}vz`EaR{RfMAGftFzt$(K} zCw#q&`?|kt=?hJd6*f7~b8d%DUm&!@B`)J*=Yg<`?BRbxRh0hy`+xpS!TWD2SLLto z^33_*6aK*-=gwa}?WOCf<#pzac9@2T&pAII ze^$*a&!0AZ3b-1<40c42lfR|~&UXCLlMt&M*EZP_0C-tV`+I{%TyUv?3pq> z=UwHgFQ=q*O=Qis&yv~r?d;u>{%ZCXGrqGBoB3yL$*f4X z2*YF>nbWJcn}R*Yvwn|37tq-o!5(8|;$q;!nR|gskN_et + Description of com.jetbrains package \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/JavaExternalDocumentationTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/JavaExternalDocumentationTest.java index a8e9bad2967f..cacabc9a9cca 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/JavaExternalDocumentationTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/JavaExternalDocumentationTest.java @@ -118,7 +118,7 @@ public class JavaExternalDocumentationTest extends PlatformTestCase { } @NotNull - private static VirtualFile getJarFile(String name) { + public static VirtualFile getJarFile(String name) { VirtualFile file = getVirtualFile(getDataFile(name)); assertNotNull(file); VirtualFile jarFile = JarFileSystem.getInstance().getJarRootForLocalFile(file); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java index e12a8e628eda..606c3b2cc699 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java @@ -17,10 +17,19 @@ package com.intellij.codeInsight.javadoc; import com.intellij.JavaTestUtil; import com.intellij.codeInsight.CodeInsightTestCase; +import com.intellij.codeInsight.JavaExternalDocumentationTest; import com.intellij.lang.java.JavaDocumentationProvider; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.roots.ModuleRootModificationUtil; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiTreeUtil; @@ -303,6 +312,27 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase { assertNotNull(aClass); verifyJavaDoc(aClass, Collections.singletonList("dummyUrl")); } + + public void testLibraryPackageDocumentation() throws Exception { + final VirtualFile libClasses = JavaExternalDocumentationTest.getJarFile("library.jar"); + final VirtualFile libSources = JavaExternalDocumentationTest.getJarFile("library-src.jar"); + + ApplicationManager.getApplication().runWriteAction(() -> { + final Library library = LibraryTablesRegistrar.getInstance().getLibraryTable(myProject).createLibrary("myLib"); + final Library.ModifiableModel model = library.getModifiableModel(); + model.addRoot(libClasses, OrderRootType.CLASSES); + model.addRoot(libSources, OrderRootType.SOURCES); + model.commit(); + + Module[] modules = ModuleManager.getInstance(myProject).getModules(); + assertSize(1, modules); + ModuleRootModificationUtil.addDependency(modules[0], library); + }); + + PsiPackage aPackage = JavaPsiFacade.getInstance(myProject).findPackage("com.jetbrains"); + assertNotNull(aPackage); + verifyJavaDoc(aPackage); + } @Override protected String getTestDataPath() { From 762d931633349d85b3aca04969cd5128973917b5 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 25 Aug 2015 20:43:04 +0300 Subject: [PATCH 081/246] delete temp folder if there are no files to keep --- .../src/com/intellij/testFramework/UsefulTestCase.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java index 399340124fbb..f20ae8f2c842 100644 --- a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java @@ -157,13 +157,16 @@ public abstract class UsefulTestCase extends TestCase { FileUtil.resetCanonicalTempPathCache(ORIGINAL_TEMP_DIR); if (hasTmpFilesToKeep()) { File[] files = new File(myTempDir).listFiles(); - if (files != null) { + if (files != null && files.length > 0) { for (File file : files) { if (!shouldKeepTmpFile(file)) { FileUtil.delete(file); } } } + else { + FileUtil.delete(new File(myTempDir)); + } } else { FileUtil.delete(new File(myTempDir)); From 5bad6c26666506809901c9f88387835edaf5b18d Mon Sep 17 00:00:00 2001 From: irengrig Date: Tue, 25 Aug 2015 20:00:00 +0200 Subject: [PATCH 082/246] project startup tasks, rename "state manager" - https://upsource.labs.intellij.net/IDEA/review/IDEA-CR-4512?commentId=6a999617-89fb-4c98-b0de-0941b70f4d68 --- .../startup/ProjectStartupConfigurable.java | 4 ++-- .../startup/ProjectStartupRunner.java | 18 +++++++++--------- ...ion.java => ProjectStartupTaskManager.java} | 10 +++++----- .../src/META-INF/PlatformExtensions.xml | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) rename platform/lang-impl/src/com/intellij/execution/startup/{ProjectStartupConfiguration.java => ProjectStartupTaskManager.java} (94%) diff --git a/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupConfigurable.java b/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupConfigurable.java index 9c6562c41b8c..1967ed422966 100644 --- a/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupConfigurable.java +++ b/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupConfigurable.java @@ -61,13 +61,13 @@ import java.util.List; public class ProjectStartupConfigurable implements SearchableConfigurable, Configurable.NoScroll { private final Project myProject; private Tree myTree; - private ProjectStartupConfiguration myConfiguration; + private ProjectStartupTaskManager myConfiguration; private ToolbarDecorator myDecorator; private JBCheckBox mySharedCheckBox; public ProjectStartupConfigurable(Project project) { myProject = project; - myConfiguration = ProjectStartupConfiguration.getInstance(myProject); + myConfiguration = ProjectStartupTaskManager.getInstance(myProject); } @NotNull diff --git a/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupRunner.java b/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupRunner.java index d4b72af214de..39e97f114db6 100644 --- a/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupRunner.java +++ b/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupRunner.java @@ -41,26 +41,26 @@ public class ProjectStartupRunner implements StartupActivity { @Override public void runActivity(@NotNull Project project) { - final ProjectStartupConfiguration projectStartupConfiguration = ProjectStartupConfiguration.getInstance(project); - if (projectStartupConfiguration.isEmpty()) return; + final ProjectStartupTaskManager projectStartupTaskManager = ProjectStartupTaskManager.getInstance(project); + if (projectStartupTaskManager.isEmpty()) return; RunManagerImpl.getInstanceImpl(project).addRunManagerListener(new RunManagerAdapter() { @Override public void runConfigurationRemoved(@NotNull RunnerAndConfigurationSettings settings) { - projectStartupConfiguration.delete(settings.getName()); + projectStartupTaskManager.delete(settings.getName()); } @Override public void runConfigurationChanged(@NotNull RunnerAndConfigurationSettings settings, String existingId) { if (existingId != null) { - projectStartupConfiguration.rename(existingId, settings); + projectStartupTaskManager.rename(existingId, settings); } - projectStartupConfiguration.checkOnChange(settings); + projectStartupTaskManager.checkOnChange(settings); } @Override public void runConfigurationAdded(@NotNull RunnerAndConfigurationSettings settings) { - projectStartupConfiguration.checkOnChange(settings); + projectStartupTaskManager.checkOnChange(settings); } }); final Alarm alarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, project); @@ -81,15 +81,15 @@ public class ProjectStartupRunner implements StartupActivity { } private void runActivities(final Project project) { - final List configurations = ProjectStartupConfiguration.getInstance(project).getStartupConfigurations(); + final List configurations = ProjectStartupTaskManager.getInstance(project).getStartupConfigurations(); final Executor executor = DefaultRunExecutor.getRunExecutorInstance(); for (final RunnerAndConfigurationSettings configuration : configurations) { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { ProgramRunnerUtil.executeConfiguration(project, configuration, executor); - ProjectStartupConfiguration.NOTIFICATION_GROUP - .createNotification(ProjectStartupConfiguration.PREFIX + " started '" + configuration.getName() + "'", MessageType.INFO) + ProjectStartupTaskManager.NOTIFICATION_GROUP + .createNotification(ProjectStartupTaskManager.PREFIX + " started '" + configuration.getName() + "'", MessageType.INFO) .notify(project); } }, ModalityState.any()); diff --git a/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupConfiguration.java b/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupTaskManager.java similarity index 94% rename from platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupConfiguration.java rename to platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupTaskManager.java index 8a199c45e977..0f434a86d83b 100644 --- a/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupConfiguration.java +++ b/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupTaskManager.java @@ -34,7 +34,7 @@ import java.util.List; /** * @author Irina.Chernushina on 8/19/2015. */ -public class ProjectStartupConfiguration { +public class ProjectStartupTaskManager { public static final NotificationGroup NOTIFICATION_GROUP = NotificationGroup.logOnlyGroup("Project Startup Tasks Messages"); @NonNls public static final String PREFIX = "Project Startup Tasks: "; private final Project myProject; @@ -43,12 +43,12 @@ public class ProjectStartupConfiguration { private final RunManagerEx myRunManager; private boolean myInitialized; - public static ProjectStartupConfiguration getInstance(@NotNull final Project project) { - return ServiceManager.getService(project, ProjectStartupConfiguration.class); + public static ProjectStartupTaskManager getInstance(@NotNull final Project project) { + return ServiceManager.getService(project, ProjectStartupTaskManager.class); } - public ProjectStartupConfiguration(Project project, ProjectStartupSharedConfiguration shared, ProjectStartupLocalConfiguration local, - @NotNull RunManager runManager) { + public ProjectStartupTaskManager(Project project, ProjectStartupSharedConfiguration shared, ProjectStartupLocalConfiguration local, + @NotNull RunManager runManager) { myProject = project; myShared = shared; myLocal = local; diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index ae0b130a2115..4b191a1e89a4 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -420,7 +420,7 @@ - + From 859d712b57b18f7fe5c0e0cef4fce6779b41611a Mon Sep 17 00:00:00 2001 From: irengrig Date: Tue, 25 Aug 2015 20:09:45 +0200 Subject: [PATCH 083/246] project startup tasks, verify/correct project startup tasks state on service initialization --- .../startup/ProjectStartupConfigurable.java | 18 ++++++++++-------- .../startup/ProjectStartupTaskManager.java | 14 ++++++++------ 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupConfigurable.java b/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupConfigurable.java index 1967ed422966..08fc802dc8a7 100644 --- a/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupConfigurable.java +++ b/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupConfigurable.java @@ -61,13 +61,12 @@ import java.util.List; public class ProjectStartupConfigurable implements SearchableConfigurable, Configurable.NoScroll { private final Project myProject; private Tree myTree; - private ProjectStartupTaskManager myConfiguration; + private ProjectStartupTaskManager myProjectStartupTaskManager; private ToolbarDecorator myDecorator; private JBCheckBox mySharedCheckBox; public ProjectStartupConfigurable(Project project) { myProject = project; - myConfiguration = ProjectStartupTaskManager.getInstance(myProject); } @NotNull @@ -97,6 +96,8 @@ public class ProjectStartupConfigurable implements SearchableConfigurable, Confi @Nullable @Override public JComponent createComponent() { + myProjectStartupTaskManager = ProjectStartupTaskManager.getInstance(myProject); + myTree = new Tree(); installRenderer(); myDecorator = ToolbarDecorator.createDecorator(myTree) @@ -291,23 +292,24 @@ public class ProjectStartupConfigurable implements SearchableConfigurable, Confi @Override public boolean isModified() { - if (mySharedCheckBox.isSelected() != myConfiguration.isShared()) return true; - final List recorded = myConfiguration.getStartupConfigurations(); + if (mySharedCheckBox.isSelected() != myProjectStartupTaskManager.isShared()) return true; + final List recorded = myProjectStartupTaskManager.getStartupConfigurations(); final List current = ((ProjectStartupTasksTreeModel)myTree.getModel()).getConfigurations(); return ! Comparing.equal(recorded, current); } @Override public void apply() throws ConfigurationException { - myConfiguration.setStartupConfigurations(((ProjectStartupTasksTreeModel)myTree.getModel()).getConfigurations(), mySharedCheckBox.isSelected()); + myProjectStartupTaskManager + .setStartupConfigurations(((ProjectStartupTasksTreeModel)myTree.getModel()).getConfigurations(), mySharedCheckBox.isSelected()); } @Override public void reset() { - final ProjectStartupTasksTreeModel model = new ProjectStartupTasksTreeModel(myConfiguration.getStartupConfigurations()); + final ProjectStartupTasksTreeModel model = new ProjectStartupTasksTreeModel(myProjectStartupTaskManager.getStartupConfigurations()); setModel(model); - mySharedCheckBox.setSelected(myConfiguration.isShared()); - mySharedCheckBox.setEnabled(myConfiguration.isShared() || myConfiguration.canBeShared()); + mySharedCheckBox.setSelected(myProjectStartupTaskManager.isShared()); + mySharedCheckBox.setEnabled(myProjectStartupTaskManager.isShared() || myProjectStartupTaskManager.canBeShared()); canBeSharedCheck(model); selectPathOrFirst(null); diff --git a/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupTaskManager.java b/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupTaskManager.java index 0f434a86d83b..c3c683ce7d18 100644 --- a/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupTaskManager.java +++ b/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupTaskManager.java @@ -41,7 +41,6 @@ public class ProjectStartupTaskManager { private final ProjectStartupSharedConfiguration myShared; private final ProjectStartupLocalConfiguration myLocal; private final RunManagerEx myRunManager; - private boolean myInitialized; public static ProjectStartupTaskManager getInstance(@NotNull final Project project) { return ServiceManager.getService(project, ProjectStartupTaskManager.class); @@ -53,16 +52,19 @@ public class ProjectStartupTaskManager { myShared = shared; myLocal = local; myRunManager = (RunManagerEx)runManager; + verifyState(); + } + + private void verifyState() { + if (! myShared.isEmpty()) { + myLocal.shared(); + myLocal.clear(); + } } public List getStartupConfigurations() { final List result = new ArrayList(); if (! myShared.isEmpty()) { - if (! myInitialized) { - myLocal.shared(); - myInitialized = true; - } - myLocal.clear(); return fillResult(result, myShared.getList(), true); } return fillResult(result, myLocal.getList(), false); From d4d7d527c4e602fa133fbebcb4415ded9d6858b5 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 25 Aug 2015 21:28:07 +0300 Subject: [PATCH 084/246] reverted deletion of empty test folders for now --- .../src/com/intellij/testFramework/UsefulTestCase.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java index f20ae8f2c842..399340124fbb 100644 --- a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java @@ -157,16 +157,13 @@ public abstract class UsefulTestCase extends TestCase { FileUtil.resetCanonicalTempPathCache(ORIGINAL_TEMP_DIR); if (hasTmpFilesToKeep()) { File[] files = new File(myTempDir).listFiles(); - if (files != null && files.length > 0) { + if (files != null) { for (File file : files) { if (!shouldKeepTmpFile(file)) { FileUtil.delete(file); } } } - else { - FileUtil.delete(new File(myTempDir)); - } } else { FileUtil.delete(new File(myTempDir)); From aacd379d4bf9832df8e4817ba6b428eb9a62c31e Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 25 Aug 2015 20:41:29 +0200 Subject: [PATCH 085/246] make IG test light --- .../MalformedFormatString.java | 20 ++--- .../bugs/malformed_format_string/expected.xml | 79 ------------------- .../MalformedFormatStringInspectionTest.java | 19 +++-- 3 files changed, 23 insertions(+), 95 deletions(-) delete mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/expected.xml diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/MalformedFormatString.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/MalformedFormatString.java index f494f0190e25..52bad312b971 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/MalformedFormatString.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/MalformedFormatString.java @@ -7,30 +7,30 @@ public class MalformedFormatString { public void foo() { - String.format("%", 3.0); - System.out.printf("%", 3.0); - System.out.printf("%q", 3.0); - System.out.printf("%d", 3.0); - System.out.printf(new Locale(""),"%d%s", 3.0, "foo"); + String.format("%", 3.0); + System.out.printf("%", 3.0); + System.out.printf("%q", 3.0); + System.out.printf("%d", 3.0); + System.out.printf(new Locale(""),"%d%s", 3.0, "foo"); } public static void main(String[] args) { String local = "hmm"; String good = String.format("%s %s", 1, 2); // this is valid according to the inspector (correct) - String warn = String.format("%s %s", 1); // this is invalid according to the inspector (correct) + String warn = String.format("%s %s", 1); // this is invalid according to the inspector (correct) String invalid = String.format("%s %s" + local, 1); // this is valid according to the inspector (INCORRECT!) - String interesting = String.format("%s %s" + "hmm", 1); // this is invalid according to the inspector (correct) + String interesting = String.format("%s %s" + "hmm", 1); // this is invalid according to the inspector (correct) String intAsChar = String.format("symbol '%1$c' (numeric value %1$d)", 60); // integer->char conversion is ok (correct) } public void outOfMemory() { - String.format("%2147483640$s", "s"); + String.format("%2147483640$s", "s"); } public void optionalSettings() { SomeOtherLogger logger = new SomeOtherLogger(); - logger.d("%s %s", 1); // this is invalid according to the inspector (correct) + logger.d("%s %s", 1); // this is invalid according to the inspector (correct) } public class SomeOtherLogger { @@ -40,7 +40,7 @@ public class MalformedFormatString { } void shouldWarn() { - String.format("%1$c %1$d", 10L); + String.format("%1$c %1$d", 10L); } void shouldNotWarn() { diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/expected.xml deleted file mode 100644 index 8363c90a165c..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/expected.xml +++ /dev/null @@ -1,79 +0,0 @@ - - - - MalformedFormatString.java - 10 - Malformed format string - Too many arguments for format string "%" #loc - - - - MalformedFormatString.java - 11 - Malformed format string - Too many arguments for format string "%" #loc - - - - MalformedFormatString.java - 12 - Malformed format string - Format string "%q" is malformed #loc - - - - MalformedFormatString.java - 13 - Malformed format string - Format string "%d" does not match the type of its arguments #loc - - - - MalformedFormatString.java - 14 - Malformed format string - Format string "%d%s" does not match the type of its arguments #loc - - - - MalformedFormatString.java - 21 - Malformed format string - Too few arguments for format string "%s %s" #loc - - - - - - MalformedFormatString.java - 23 - Malformed format string - Too few arguments for format string "%s %s" + "hmm" #loc - - - - MalformedFormatString.java - 28 - Malformed format string - Too few arguments for format string "%2147483640$s" #loc - - - - MalformedFormatString.java - 33 - Malformed format string - Too few arguments for format string "%s %s" #loc - - - - MalformedFormatString.java - 43 - Malformed format string - Format string <code>"%1$c %1$d"</code> does not match the type of its arguments #loc - - \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/MalformedFormatStringInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/MalformedFormatStringInspectionTest.java index 6d0149c9d8f1..c3ea5da0f6b4 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/MalformedFormatStringInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/MalformedFormatStringInspectionTest.java @@ -1,14 +1,21 @@ package com.siyeh.ig.bugs; -import com.siyeh.ig.IGInspectionTestCase; +import com.intellij.codeInspection.InspectionProfileEntry; +import com.siyeh.ig.LightInspectionTestCase; +import org.jetbrains.annotations.Nullable; -public class MalformedFormatStringInspectionTest extends IGInspectionTestCase { +public class MalformedFormatStringInspectionTest extends LightInspectionTestCase { - public void test() throws Exception { - MalformedFormatStringInspection inspection = new MalformedFormatStringInspection(); + public void testMalformedFormatString() { + doTest(); + } + + @Nullable + @Override + protected InspectionProfileEntry getInspection() { + final MalformedFormatStringInspection inspection = new MalformedFormatStringInspection(); inspection.classNames.add("com.siyeh.igtest.bugs.malformed_format_string.MalformedFormatString.SomeOtherLogger"); inspection.methodNames.add("d"); - - doTest("com/siyeh/igtest/bugs/malformed_format_string", inspection); + return inspection; } } \ No newline at end of file From 198485cf29b4a705a2109cfa412a234589a25598 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 25 Aug 2015 20:57:04 +0200 Subject: [PATCH 086/246] IDEA-143355 (String.format() with java.sql.Timestamp) --- .../src/com/siyeh/ig/bugs/FormatDecode.java | 8 ++++---- .../malformed_format_string/MalformedFormatString.java | 6 +++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/FormatDecode.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/FormatDecode.java index f09496b9a3e7..9c027f4e96a7 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/FormatDecode.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/FormatDecode.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2014 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package com.siyeh.ig.bugs; import com.intellij.psi.CommonClassNames; import com.intellij.psi.PsiType; +import com.intellij.psi.util.InheritanceUtil; import java.util.ArrayList; import java.util.HashSet; @@ -151,11 +152,10 @@ class FormatDecode { @Override public boolean valid(PsiType type) { final String text = type.getCanonicalText(); - return PsiType.LONG.equals(type) || CommonClassNames.JAVA_LANG_LONG.equals(text) || - CommonClassNames.JAVA_UTIL_DATE.equals(text) || - CommonClassNames.JAVA_UTIL_CALENDAR.equals(text); + InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_DATE) || + InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_CALENDAR); } } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/MalformedFormatString.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/MalformedFormatString.java index 52bad312b971..0302496818f9 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/MalformedFormatString.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/MalformedFormatString.java @@ -1,7 +1,7 @@ package com.siyeh.igtest.bugs.malformed_format_string; import java.util.Locale; - +import java.sql.Timestamp; public class MalformedFormatString { @@ -47,4 +47,8 @@ public class MalformedFormatString { String.format("%c", 0x10300); String charAsInt = String.format("%1$d %1$c", 10); // int followed by char should be ok too. } + + String timestamp(Timestamp ts) { + return String.format("%tF %tT", ts, ts); + } } From 1f32e521f48655a1d7edaabe513548a43b499d70 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Aug 2015 20:57:11 +0200 Subject: [PATCH 087/246] remove unused PsiFormatUtil.getRawExternalName --- .../com/intellij/psi/util/PsiFormatUtil.java | 34 ------------------- 1 file changed, 34 deletions(-) diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiFormatUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiFormatUtil.java index feccd0171c95..a5a913bf8093 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/PsiFormatUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/PsiFormatUtil.java @@ -452,40 +452,6 @@ public class PsiFormatUtil extends PsiFormatUtilBase { return builder.toString(); } - @Nullable - public static String getRawExternalName(PsiModifierListOwner owner) { - final StringBuilder builder = new StringBuilder(); - final PsiClass psiClass = PsiTreeUtil.getParentOfType(owner, PsiClass.class, false); - if (psiClass == null) return null; - ClassUtil.formatClassName(psiClass, builder); - if (owner instanceof PsiMethod) { - builder.append(" "); - formatMethod((PsiMethod)owner, PsiSubstitutor.EMPTY, - SHOW_NAME | SHOW_FQ_NAME | SHOW_TYPE | SHOW_RAW_TYPE | SHOW_PARAMETERS | SHOW_FQ_CLASS_NAMES, - SHOW_TYPE | SHOW_RAW_TYPE | SHOW_FQ_CLASS_NAMES, - Integer.MAX_VALUE, builder); - } - else if (owner instanceof PsiParameter) { - final PsiElement declarationScope = ((PsiParameter)owner).getDeclarationScope(); - if (!(declarationScope instanceof PsiMethod)) { - return null; - } - final PsiMethod psiMethod = (PsiMethod)declarationScope; - - builder.append(" "); - formatMethod(psiMethod, PsiSubstitutor.EMPTY, - SHOW_NAME | SHOW_FQ_NAME | SHOW_TYPE | SHOW_RAW_TYPE | SHOW_PARAMETERS | SHOW_FQ_CLASS_NAMES, - SHOW_TYPE | SHOW_RAW_TYPE | SHOW_FQ_CLASS_NAMES, - Integer.MAX_VALUE, builder); - builder.append(" "); - builder.append(psiMethod.getParameterList().getParameterIndex((PsiParameter)owner)); - } - else { - return null; - } - return builder.toString(); - } - public static String getPackageDisplayName(@NotNull final PsiClass psiClass) { if (psiClass instanceof PsiTypeParameter) { PsiTypeParameterListOwner owner = ((PsiTypeParameter)psiClass).getOwner(); From c3bf675eab1dc89884d8cbfde3788b8d0b57504a Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Aug 2015 21:14:34 +0200 Subject: [PATCH 088/246] don't mention LookupItem in EmptyLookupItem --- .../lookup/impl/EmptyLookupItem.java | 20 ++++++++++++++++--- .../codeInsight/lookup/impl/LookupImpl.java | 2 +- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/EmptyLookupItem.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/EmptyLookupItem.java index ce8c913b1b99..c186a2ee66ab 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/EmptyLookupItem.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/EmptyLookupItem.java @@ -15,19 +15,33 @@ */ package com.intellij.codeInsight.lookup.impl; -import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementPresentation; +import org.jetbrains.annotations.NotNull; /** * @author peter */ -public class EmptyLookupItem extends LookupItem { +public class EmptyLookupItem extends LookupElement { + private final String myText; private final boolean myLoading; public EmptyLookupItem(final String s, boolean loading) { - super(s, " "); + myText = s; myLoading = loading; } + @NotNull + @Override + public String getLookupString() { + return " "; + } + + @Override + public void renderElement(LookupElementPresentation presentation) { + presentation.setItemText(myText); + } + public boolean isLoading() { return myLoading; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index 84ed80e0c3ea..93e44e5be1d1 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -424,7 +424,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable, } private void addEmptyItem(CollectionListModel model) { - LookupItem item = new EmptyLookupItem(myCalculating ? " " : LangBundle.message("completion.no.suggestions"), false); + LookupElement item = new EmptyLookupItem(myCalculating ? " " : LangBundle.message("completion.no.suggestions"), false); myMatchers.put(item, new CamelHumpMatcher("")); model.add(item); From b429d869c8e9a77949bf6f9233eeb4a2e8096070 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Aug 2015 21:22:51 +0200 Subject: [PATCH 089/246] let VariableLookupItem render itself --- .../lookup/VariableLookupItem.java | 19 ++++++++++++-- .../impl/JavaElementLookupRenderer.java | 26 ++----------------- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/lookup/VariableLookupItem.java b/java/java-impl/src/com/intellij/codeInsight/lookup/VariableLookupItem.java index 8eea1dd64231..ab7420175c92 100644 --- a/java/java-impl/src/com/intellij/codeInsight/lookup/VariableLookupItem.java +++ b/java/java-impl/src/com/intellij/codeInsight/lookup/VariableLookupItem.java @@ -20,6 +20,7 @@ import com.intellij.codeInsight.TailType; import com.intellij.codeInsight.completion.*; import com.intellij.codeInsight.daemon.impl.JavaColorProvider; import com.intellij.codeInsight.daemon.impl.analysis.HighlightControlFlowUtil; +import com.intellij.codeInsight.lookup.impl.JavaElementLookupRenderer; import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.RangeMarker; @@ -92,6 +93,7 @@ public class VariableLookupItem extends LookupItem implements Typed } @Override + @NotNull public PsiType getType() { return getSubstitutor().substitute(getObject().getType()); } @@ -124,12 +126,25 @@ public class VariableLookupItem extends LookupItem implements Typed @Override public void renderElement(LookupElementPresentation presentation) { - super.renderElement(presentation); + boolean qualify = getAttribute(FORCE_QUALIFY) != null; + + PsiVariable variable = getObject(); + String name = variable.getName(); + if (qualify && variable instanceof PsiField && ((PsiField)variable).getContainingClass() != null) { + name = ((PsiField)variable).getContainingClass().getName() + "." + name; + } + presentation.setItemText(name); + + presentation.setIcon(DefaultLookupItemRenderer.getRawIcon(this, presentation.isReal())); + presentation.setStrikeout(JavaElementLookupRenderer.isToStrikeout(this)); + if (myHelper != null) { - myHelper.renderElement(presentation, getAttribute(FORCE_QUALIFY) != null ? Boolean.TRUE : null, getSubstitutor()); + myHelper.renderElement(presentation, qualify ? Boolean.TRUE : null, getSubstitutor()); } if (myColor != null) { presentation.setTypeText("", new ColorIcon(12, myColor)); + } else { + presentation.setTypeText(getType().getPresentableText()); } } diff --git a/java/java-impl/src/com/intellij/codeInsight/lookup/impl/JavaElementLookupRenderer.java b/java/java-impl/src/com/intellij/codeInsight/lookup/impl/JavaElementLookupRenderer.java index bf64fce02a79..e30d5d0043a0 100644 --- a/java/java-impl/src/com/intellij/codeInsight/lookup/impl/JavaElementLookupRenderer.java +++ b/java/java-impl/src/com/intellij/codeInsight/lookup/impl/JavaElementLookupRenderer.java @@ -19,7 +19,6 @@ import com.intellij.codeInsight.completion.JavaCompletionUtil; import com.intellij.codeInsight.lookup.DefaultLookupItemRenderer; import com.intellij.codeInsight.lookup.LookupElementPresentation; import com.intellij.codeInsight.lookup.LookupItem; -import com.intellij.codeInsight.lookup.VariableLookupItem; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.impl.beanProperties.BeanPropertyElement; @@ -34,8 +33,7 @@ import java.util.List; public class JavaElementLookupRenderer implements ElementLookupRenderer { @Override public boolean handlesItem(final Object element) { - return element instanceof PsiVariable || - element instanceof PsiKeyword || element instanceof PsiExpression || + return element instanceof PsiKeyword || element instanceof PsiExpression || element instanceof PsiTypeElement || element instanceof BeanPropertyElement; } @@ -69,18 +67,6 @@ public class JavaElementLookupRenderer implements ElementLookupRenderer { } } } - else if (o instanceof PsiArrayType) { - name = ((PsiArrayType)o).getDeepComponentType().getPresentableText(); - } - else if (o instanceof PsiType) { - name = ((PsiType)o).getPresentableText(); - } - - if (item.getAttribute(LookupItem.FORCE_QUALIFY) != null) { - if (o instanceof PsiMember && ((PsiMember)o).getContainingClass() != null) { - name = ((PsiMember)o).getContainingClass().getName() + "." + name; - } - } return StringUtil.notNullize(name); } @@ -91,15 +77,7 @@ public class JavaElementLookupRenderer implements ElementLookupRenderer { if (o instanceof PsiElement) { final PsiElement element = (PsiElement)o; if (element.isValid()) { - if (element instanceof PsiVariable){ - PsiVariable variable = (PsiVariable)element; - PsiType type = variable.getType(); - if (item instanceof VariableLookupItem) { - type = ((VariableLookupItem)item).getSubstitutor().substitute(type); - } - text = type.getPresentableText(); - } - else if (element instanceof PsiExpression){ + if (element instanceof PsiExpression){ PsiExpression expression = (PsiExpression)element; PsiType type = expression.getType(); if (type != null){ From c89b9ff1b292ecf5b226699df87cfea451111f19 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Aug 2015 21:36:39 +0200 Subject: [PATCH 090/246] don't overburden java/js insert handlers with live templates --- .../completion/DefaultInsertHandler.java | 19 ++++--------------- .../SmartCompletionTemplateItem.java | 17 ++++++----------- 2 files changed, 10 insertions(+), 26 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/DefaultInsertHandler.java b/java/java-impl/src/com/intellij/codeInsight/completion/DefaultInsertHandler.java index c3472a58937f..39a74f7a5e29 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/DefaultInsertHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/DefaultInsertHandler.java @@ -26,11 +26,9 @@ import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiDocumentManager; -import com.intellij.psi.PsiFile; import com.intellij.psi.codeStyle.CommonCodeStyleSettings; -import org.jetbrains.annotations.NotNull; -public class DefaultInsertHandler extends TemplateInsertHandler implements Cloneable { +public class DefaultInsertHandler implements InsertHandler { public static final DefaultInsertHandler NO_TAIL_HANDLER = new DefaultInsertHandler(){ @Override @@ -40,13 +38,9 @@ public class DefaultInsertHandler extends TemplateInsertHandler implements Clone }; @Override - public void handleInsert(final InsertionContext context, LookupElement item) { - super.handleInsert(context, item); - - handleInsertInner(context, (LookupItem)item, context.getCompletionChar()); - } - - private void handleInsertInner(InsertionContext context, LookupItem item, final char completionChar) { + public void handleInsert(final InsertionContext context, LookupElement lookupElement) { + LookupItem item = (LookupItem)lookupElement; + char completionChar = context.getCompletionChar(); final Project project = context.getProject(); final Editor editor = context.getEditor(); final Document document = editor.getDocument(); @@ -170,11 +164,6 @@ public class DefaultInsertHandler extends TemplateInsertHandler implements Clone return editor.getCaretModel().getOffset(); } - @Override - protected void populateInsertMap(@NotNull final PsiFile file, @NotNull final OffsetMap offsetMap) { - JavaCompletionUtil.initOffsets(file, offsetMap); - } - public static class InsertHandlerState{ int tailOffset; int caretOffset; diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/SmartCompletionTemplateItem.java b/java/java-impl/src/com/intellij/codeInsight/completion/SmartCompletionTemplateItem.java index 3936b22bf89d..fd5cd78f3b8d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/SmartCompletionTemplateItem.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/SmartCompletionTemplateItem.java @@ -1,32 +1,29 @@ package com.intellij.codeInsight.completion; -import com.intellij.codeInsight.lookup.LookupItem; import com.intellij.codeInsight.lookup.TypedLookupItem; import com.intellij.codeInsight.template.Template; +import com.intellij.codeInsight.template.impl.LiveTemplateLookupElementImpl; import com.intellij.codeInsight.template.impl.TemplateImpl; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiExpression; import com.intellij.psi.PsiType; import com.intellij.util.IncorrectOperationException; -import org.jetbrains.annotations.NonNls; /** * @author peter */ -public class SmartCompletionTemplateItem extends LookupItem