Merge branch 'vromanik/ph' appcode/181.3203 clion/181.3209 dbe/181.3207 idea/181.3204 phpstorm/181.3205 pycharm/181.3202 pycharm/181.3206 rubymine/181.3208 webstorm/181.3211
authorVasily Romanikhin <vasily.romanikhin@jetbrains.com>
Sat, 27 Jan 2018 20:31:26 +0000 (23:31 +0300)
committerVasily Romanikhin <vasily.romanikhin@jetbrains.com>
Sat, 27 Jan 2018 20:31:26 +0000 (23:31 +0300)
216 files changed:
build/conf/ideaCE/mac/images/communitydmg.png [deleted file]
build/conf/ideaCE/mac/images/dmg_background.tiff [new file with mode: 0644]
build/groovy/org/jetbrains/intellij/build/IdeaCommunityProperties.groovy
community-guitests/testSrc/com/intellij/testGuiFramework/tests/community/TypeAheadTest.kt
java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java
java/idea-ui/src/com/intellij/projectImport/ProjectFormatPanel.java
java/java-impl/src/com/intellij/psi/codeStyle/JavaCodeStyleSettings.java
java/java-impl/src/com/intellij/psi/impl/JavaCodeBlockModificationListener.java
java/java-tests/testData/codeInsight/parameterInfo/HighlightCurrentParameterAfterTypingFirstArgumentOfThree.java [new file with mode: 0644]
java/java-tests/testData/compileServer/incremental/membersChange/replaceMethodWithBridge.log [new file with mode: 0644]
java/java-tests/testData/compileServer/incremental/membersChange/replaceMethodWithBridge/src/ppp/Util.java [new file with mode: 0644]
java/java-tests/testData/compileServer/incremental/membersChange/replaceMethodWithBridge/src/stubs/ObjectStubBase.java [new file with mode: 0644]
java/java-tests/testData/compileServer/incremental/membersChange/replaceMethodWithBridge/src/stubs/Stub.java [new file with mode: 0644]
java/java-tests/testData/compileServer/incremental/membersChange/replaceMethodWithBridge/src/stubs/StubBase.java [new file with mode: 0644]
java/java-tests/testData/compileServer/incremental/membersChange/replaceMethodWithBridge/src/stubs/StubBase.java.new [new file with mode: 0644]
java/java-tests/testData/compileServer/incremental/membersChange/replaceMethodWithBridge/src/stubs/StubElement.java [new file with mode: 0644]
java/java-tests/testData/junit/configurations/mock JUnit/junit/framework/TestCase.class [deleted file]
java/java-tests/testData/junit/configurations/mock JUnit/junit/framework/TestCase.java [deleted file]
java/java-tests/testData/junit/configurations/mock JUnit/junit/framework/ThirdPartyClass.class [deleted file]
java/java-tests/testData/junit/configurations/mock JUnit/junit/framework/ThirdPartyClass.java [deleted file]
java/java-tests/testData/junit/configurations/mock JUnit/org/junit/Test.class [deleted file]
java/java-tests/testData/junit/configurations/mock JUnit/org/junit/Test.java [deleted file]
java/java-tests/testData/junit/configurations/mock JUnit/org/junit/runner/RunWith.class [deleted file]
java/java-tests/testData/junit/configurations/mock JUnit/org/junit/runner/RunWith.java [deleted file]
java/java-tests/testData/junit/configurations/module1/test1/DerivedTest.java
java/java-tests/testData/junit/configurations/module1/test1/ThirdPartyTest.java [new file with mode: 0644]
java/java-tests/testData/junit/configurations/module1/test1/nested/TestWithJunit4.java [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/java/codeInsight/ParameterInfoTest.java
java/java-tests/testSrc/com/intellij/java/codeInsight/completion/JavaAutoPopupTest.groovy
java/java-tests/testSrc/com/intellij/java/execution/BaseConfigurationTestCase.java
java/java-tests/testSrc/com/intellij/java/execution/ConfigurationRefactoringsTest.java
java/java-tests/testSrc/com/intellij/java/execution/ConfigurationsTest.java
java/java-tests/testSrc/com/intellij/java/refactoring/SafeDeleteTest.java
java/java-tests/testSrc/com/intellij/psi/impl/PsiModificationTrackerTest.java [moved from java/java-tests/testSrc/com/intellij/java/psi/PsiModificationTrackerTest.java with 99% similarity]
jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java
jps/jps-builders/testSrc/org/jetbrains/ether/MemberChangeTest.java
platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/WinExeInstallerBuilder.groovy
platform/build-scripts/tools/mac/scripts/makedmg.pl
platform/build-scripts/tools/mac/scripts/makedmg.sh
platform/configuration-store-impl/src/ComponentStoreImpl.kt
platform/configuration-store-impl/src/DirectoryBasedStorage.kt
platform/configuration-store-impl/src/StateMap.kt
platform/configuration-store-impl/src/XmlElementStorage.kt
platform/configuration-store-impl/testSrc/DoNotSaveDefaults.kt
platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java
platform/core-impl/src/com/intellij/psi/impl/ChangedPsiRangeUtil.java [new file with mode: 0644]
platform/core-impl/src/com/intellij/psi/impl/DocumentCommitThread.java
platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java
platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java
platform/core-impl/src/com/intellij/psi/impl/source/text/DiffLog.java
platform/core-impl/src/com/intellij/util/CachedValueLeakChecker.java
platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ExternalProjectsManagerImpl.java
platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ExternalProjectsState.java
platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/wizard/AbstractExternalModuleBuilder.java
platform/lang-api/src/com/intellij/application/options/CodeStyle.java
platform/lang-api/src/com/intellij/facet/frameworks/SettingsConnectionService.java
platform/lang-api/src/com/intellij/openapi/options/colors/AttributesDescriptor.java
platform/lang-api/src/com/intellij/openapi/options/colors/ColorDescriptor.java
platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsManager.java
platform/lang-api/src/com/intellij/psi/codeStyle/ProjectCodeStyleSettingsManager.java
platform/lang-impl/src/com/intellij/application/options/TabbedLanguageCodeStylePanel.java
platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java
platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionAssertions.java
platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java
platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionPhase.java
platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java
platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java
platform/lang-impl/src/com/intellij/codeInsight/editorActions/fillParagraph/ParagraphFillHandler.java
platform/lang-impl/src/com/intellij/codeInsight/highlighting/EscapeHandler.java
platform/lang-impl/src/com/intellij/codeInspection/ProblematicWhitespaceInspection.java
platform/lang-impl/src/com/intellij/codeInspection/ui/actions/ExportHTMLAction.java
platform/lang-impl/src/com/intellij/formatting/contextConfiguration/ConfigureCodeStyleOnSelectedFragment.java
platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java
platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java [deleted file]
platform/lang-impl/src/com/intellij/psi/codeStyle/extractor/ExtractCodeStyleAction.java
platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectionRegistrarImpl.java
platform/lang-impl/src/com/intellij/util/JdkBundleList.java [deleted file]
platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
platform/platform-api/src/com/intellij/ide/actions/ActionsCollector.java [new file with mode: 0644]
platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java
platform/platform-api/src/com/intellij/ui/components/JBList.java
platform/platform-impl/src/com/intellij/featureStatistics/FeatureUsageTrackerImpl.java
platform/platform-impl/src/com/intellij/ide/SystemHealthMonitor.java
platform/platform-impl/src/com/intellij/ide/actions/SwitchBootJdkAction.java [new file with mode: 0644]
platform/platform-impl/src/com/intellij/ide/actions/ToggleFullScreenAction.java
platform/platform-impl/src/com/intellij/idea/IdeaApplication.java
platform/platform-impl/src/com/intellij/internal/statistic/UsageTrigger.java
platform/platform-impl/src/com/intellij/internal/statistic/actions/PersistFUStatisticsSessionAction.java [new file with mode: 0755]
platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/actions/ActionsCollectorImpl.java [moved from platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/actions/ActionsCollector.java with 77% similarity]
platform/platform-impl/src/com/intellij/internal/statistic/eventLog/FeatureUsageEventLogger.kt [new file with mode: 0644]
platform/platform-impl/src/com/intellij/internal/statistic/eventLog/LogEventSerializer.kt [new file with mode: 0644]
platform/platform-impl/src/com/intellij/internal/statistic/eventLog/LogEvents.kt [new file with mode: 0644]
platform/platform-impl/src/com/intellij/internal/statistic/service/ConfigurableStatisticsService.java
platform/platform-impl/src/com/intellij/internal/statistic/service/fus/FUStatisticsService.java
platform/platform-impl/src/com/intellij/internal/statistic/service/fus/FUStatisticsWhiteListGroupsService.java
platform/platform-impl/src/com/intellij/internal/statistic/service/fus/collectors/FUStatisticsPersistence.java
platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java
platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingManagerImpl.java
platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentComboLabel.java
platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java
platform/platform-impl/src/com/intellij/util/JdkBundle.java
platform/platform-impl/src/com/intellij/util/JdkBundleList.java [new file with mode: 0644]
platform/platform-resources-en/src/messages/ActionsBundle.properties
platform/platform-resources-en/src/messages/IdeBundle.properties
platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml
platform/platform-resources/src/META-INF/PlatformExtensions.xml
platform/platform-resources/src/idea/LangActions.xml
platform/platform-resources/src/idea/PlatformActions.xml
platform/platform-tests/testSrc/com/intellij/ide/fileTemplates/impl/LightFileTemplatesTest.java
platform/platform-tests/testSrc/com/intellij/util/JdkBundleListTest.java [deleted file]
platform/platform-tests/testSrc/com/intellij/util/JdkBundleTest.java
platform/platform-tests/testSrc/com/intellij/util/containers/TreeTraverserTest.java
platform/projectModel-api/src/com/intellij/openapi/components/StorageScheme.java
platform/projectModel-api/src/com/intellij/openapi/project/ExternalStorageConfigurationManager.kt [new file with mode: 0644]
platform/projectModel-api/src/com/intellij/openapi/project/ProjectUtilCore.kt
platform/projectModel-api/src/com/intellij/openapi/projectRoots/ProjectJdkTable.java
platform/testFramework/src/_FirstInSuiteTest.java
platform/testFramework/src/com/intellij/psi/formatter/FormatterTestCase.java
platform/testFramework/src/com/intellij/testFramework/LeakHunter.java
platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java
platform/testFramework/src/com/intellij/testFramework/PerformanceTestInfo.java [new file with mode: 0644]
platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java
platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java
platform/testGuiFramework/src/com/intellij/testGuiFramework/framework/GuiTestUtil.java
platform/testGuiFramework/src/com/intellij/testGuiFramework/idea/IdeaGuiTestUtil.kt
platform/util/resources/misc/registry.properties
platform/util/src/com/intellij/util/VersionUtil.java
platform/util/src/com/intellij/util/containers/NotNullList.java
platform/util/src/com/intellij/util/containers/TreeTraversal.java
platform/util/src/com/intellij/util/ref/DebugReflectionUtil.java
platform/util/testSrc/com/intellij/util/VersionUtilTest.java
platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsCheckBoxWithSpinnerConfigurable.java
platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsDirectoryConfigurationPanel.java
plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseProjectCodeStyleData.java
plugins/git4idea/src/git4idea/GitUtil.java
plugins/git4idea/src/git4idea/config/GitVcsSettings.java
plugins/git4idea/src/git4idea/index/GitIndexUtil.java
plugins/git4idea/src/git4idea/merge/GitPullDialog.java
plugins/git4idea/src/git4idea/push/GitPushSupport.java
plugins/git4idea/src/git4idea/push/GitPushTarget.java
plugins/git4idea/src/git4idea/push/GitPushTargetPanel.java
plugins/git4idea/src/git4idea/push/GitPusher.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleModuleBuilder.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleProjectImportBuilder.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/IdeaGradleProjectSettingsControlBuilder.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/ImportFromGradleControl.java
plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleProjectSettings.java
plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleSettings.java
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/propertyUtil.kt [new file with mode: 0644]
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/PropertyKind.kt [new file with mode: 0644]
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/PropertyResolveResult.kt [new file with mode: 0644]
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.kt
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/processors/GroovyAllVariantsProcessor.java
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/processors/GroovyResolverProcessor.java
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/processors/GroovyResolverProcessorImpl.java
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/processors/ProcessorWithCommonHints.kt [new file with mode: 0644]
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/processors/PropertyProcessor.kt [new file with mode: 0644]
plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveClassTest.groovy
plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolvePropertyTest.groovy
plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolvePropertyViaAliasedImportTest.groovy [new file with mode: 0644]
plugins/groovy/testdata/resolve/imports/getterWithAlias.groovy [new file with mode: 0644]
plugins/groovy/testdata/resolve/imports/getterWithGetterAlias.groovy [new file with mode: 0644]
plugins/groovy/testdata/resolve/imports/getterWithSetterAlias.groovy [new file with mode: 0644]
plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingSettingsForm.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilder.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenProjectBuilder.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenProjectImportProvider.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenProjectImportStep.java
plugins/settings-repository/src/upstreamEditor.kt
plugins/xpath/xpath-lang/test/org/intellij/lang/xpath/xslt/Xslt2HighlightingTest.java
plugins/xpath/xpath-lang/test/org/intellij/lang/xpath/xslt/XsltHighlightingTest.java
plugins/yaml/resources/messages/YAMLBundle.properties
plugins/yaml/src/org/jetbrains/yaml/meta/impl/YamlDuplicatedKeysInspectionBase.java [new file with mode: 0644]
plugins/yaml/src/org/jetbrains/yaml/meta/impl/YamlMissingKeysInspectionBase.java
python/build/DMG_background.png [deleted file]
python/build/dmg_background.tiff [new file with mode: 0644]
python/build/groovy/org/jetbrains/intellij/build/pycharm/PyCharmCommunityProperties.groovy
python/build/icon-robots.txt
python/educational-python/build/DMG_background.png [deleted file]
python/educational-python/build/dmg_background.tiff [new file with mode: 0644]
python/educational-python/build/groovy/org/jetbrains/intellij/build/pycharm/edu/PyCharmEduProperties.groovy
python/educational-python/build/icon-robots.txt
python/src/com/jetbrains/python/testing/PyTestLineMarkerProvider.kt [new file with mode: 0644]
spellchecker/src/META-INF/SpellCheckerPlugin.xml
spellchecker/src/com/intellij/spellchecker/SpellCheckerManager.java
spellchecker/src/com/intellij/spellchecker/SpellCheckerNotificationUtils.java [new file with mode: 0644]
spellchecker/src/com/intellij/spellchecker/dictionary/AggregatedDictionary.java
spellchecker/src/com/intellij/spellchecker/dictionary/CustomDictionaryProvider.java
spellchecker/src/com/intellij/spellchecker/dictionary/ProjectDictionary.java
spellchecker/src/com/intellij/spellchecker/inspections/SpellCheckingInspection.java
spellchecker/src/com/intellij/spellchecker/jetbrains.dic
spellchecker/src/com/intellij/spellchecker/quickfixes/SaveTo.java [new file with mode: 0644]
spellchecker/src/com/intellij/spellchecker/settings/CustomDictionariesPanel.java
spellchecker/src/com/intellij/spellchecker/settings/SpellCheckerSettings.java
spellchecker/src/com/intellij/spellchecker/settings/SpellCheckerSettingsPane.form
spellchecker/src/com/intellij/spellchecker/settings/SpellCheckerSettingsPane.java
spellchecker/src/com/intellij/spellchecker/state/AggregatedDictionaryState.java [deleted file]
spellchecker/src/com/intellij/spellchecker/state/CachedDictionaryState.java
spellchecker/src/com/intellij/spellchecker/tokenizer/SpellcheckingStrategy.java
spellchecker/src/com/intellij/spellchecker/util/SpellCheckerBundle.properties
spellchecker/testData/inspection/quickfixes/emptySaveTo.txt [new file with mode: 0644]
spellchecker/testData/inspection/quickfixes/noTypoSaveTo.txt [new file with mode: 0644]
spellchecker/testSrc/com/intellij/spellchecker/dictionary/AggregatedDictionaryTest.java
spellchecker/testSrc/com/intellij/spellchecker/dictionary/AppDictionaryTest.java [new file with mode: 0644]
spellchecker/testSrc/com/intellij/spellchecker/dictionary/ProjectDictionaryTest.java [new file with mode: 0644]
spellchecker/testSrc/com/intellij/spellchecker/inspection/quickfixes/PlainTextSpellCheckerFixesTest.java
xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsProvider.java
xml/impl/src/com/intellij/codeInsight/daemon/impl/quickfix/IgnoreExtResourceAction.java
xml/impl/src/com/intellij/javaee/ExternalResourceConfigurable.java
xml/relaxng/test/org/intellij/plugins/relaxNG/HighlightingTestBase.java
xml/relaxng/test/org/intellij/plugins/relaxNG/RngXmlHighlightingTest.java
xml/tests/src/com/intellij/codeInsight/daemon/XmlHighlightingTest.java
xml/xml-psi-impl/src/com/intellij/javaee/CoreExternalResourceManager.java
xml/xml-psi-impl/src/com/intellij/javaee/ExternalResourceManagerEx.java
xml/xml-psi-impl/src/com/intellij/javaee/ExternalResourceManagerExImpl.java

diff --git a/build/conf/ideaCE/mac/images/communitydmg.png b/build/conf/ideaCE/mac/images/communitydmg.png
deleted file mode 100644 (file)
index bb8e6e3..0000000
Binary files a/build/conf/ideaCE/mac/images/communitydmg.png and /dev/null differ
diff --git a/build/conf/ideaCE/mac/images/dmg_background.tiff b/build/conf/ideaCE/mac/images/dmg_background.tiff
new file mode 100644 (file)
index 0000000..d9b5f35
Binary files /dev/null and b/build/conf/ideaCE/mac/images/dmg_background.tiff differ
index 9b8dbe98036e57b5fec554e73c9cdab634d9e5fc..6f6c8e9b2bce7fa7b4b2e7c42a199c6d1e0c669c 100644 (file)
@@ -110,7 +110,7 @@ class IdeaCommunityProperties extends BaseIdeaProperties {
         associateIpr = true
         enableYourkitAgentInEAP = false
         bundleIdentifier = "com.jetbrains.intellij.ce"
-        dmgImagePath = "$projectHome/build/conf/ideaCE/mac/images/communitydmg.png"
+        dmgImagePath = "$projectHome/build/conf/ideaCE/mac/images/dmg_background.tiff"
         icnsPathForEAP = "$projectHome/build/conf/ideaCE/mac/images/communityEAP.icns"
       }
 
index 8e3b0021797031d5cb7fe8cc1b45d29be1b6adbc..1fedb6d31b13f5f759fb57c8bd67eef731456d75 100644 (file)
@@ -10,8 +10,9 @@ import com.intellij.testGuiFramework.framework.RunWithIde
 import com.intellij.testGuiFramework.impl.GuiTestCase
 import com.intellij.testGuiFramework.impl.GuiTestUtilKt
 import com.intellij.testGuiFramework.launcher.ide.CommunityIde
+import com.intellij.testGuiFramework.util.Key
 import com.intellij.ui.popup.PopupFactoryImpl
-import org.fest.swing.timing.Pause
+import org.fest.swing.timing.Pause.pause
 import org.fest.swing.timing.Timeout
 import org.junit.Test
 import java.util.concurrent.TimeUnit
@@ -24,22 +25,22 @@ class TypeAheadTest : GuiTestCase() {
     createProject()
     ideFrame {
       //a pause to wait when an (Edit Configurations...) action will be enabled
-      Pause.pause(5000)
+      pause(5000)
       waitForBackgroundTasksToFinish()
       openRunDebugConfiguration()
       dialog("Run/Debug Configurations") {
         addJUnitConfiguration()
         for (i in 0..20) {
           combobox("Test kind:").selectItem("Category")
-          Pause.pause(2000)
+          pause(2000)
           combobox("Test kind:").selectItem("Class")
-          Pause.pause(2000)
+          pause(2000)
           combobox("Test kind:").selectItem("Method")
-          Pause.pause(2000)
+          pause(2000)
         }
         button("OK").click()
       }
-      Pause.pause(30000)
+      pause(30000)
     }
   }
 
@@ -74,9 +75,10 @@ class TypeAheadTest : GuiTestCase() {
       actionButton("Run").waitUntilEnabledAndShowing()
       for (i in 0..attempts) {
         button("Main").click()
-        if (ensureEditConfigurationsIsEnabled()) break;
+        if (ensureEditConfigurationsIsEnabled()) break
         else if (i == attempts - 1) throw Exception("Action 'Edit Configurations' is still disabled")
-        Pause.pause(timeoutInterval, TimeUnit.SECONDS)
+        pause(timeoutInterval, TimeUnit.SECONDS)
+        shortcut(Key.ESCAPE)
       }
       popupClick("Edit Configurations...")
     }
index 22901597d9741c9a7b760daa6fe3b9fdea97defc..541f1529a293e9f646fd8a9e78c33db6eca9386d 100644 (file)
@@ -166,14 +166,8 @@ public class JUnitUtil {
     final PsiClass topLevelClass = PsiTreeUtil.getTopmostParentOfType(psiClass, PsiClass.class);
     if (topLevelClass != null) {
       final PsiAnnotation annotation = AnnotationUtil.findAnnotationInHierarchy(topLevelClass, Collections.singleton(RUN_WITH));
-      if (annotation != null) {
-        final PsiAnnotationMemberValue attributeValue = annotation.findAttributeValue("value");
-        if (attributeValue instanceof PsiClassObjectAccessExpression) {
-          final String runnerName = ((PsiClassObjectAccessExpression)attributeValue).getOperand().getType().getCanonicalText();
-          if (!(PARAMETERIZED_CLASS_NAME.equals(runnerName) || SUITE_CLASS_NAME.equals(runnerName))) {
-            return true;
-          }
-        }
+      if (annotation != null && !isInheritorOrSelfRunner(annotation, RUNNERS_REQUIRE_ANNOTATION_ON_TEST_METHOD)) {
+        return true;
       }
     }
 
index 78080722681da164211136cf3c69617c9eceb45c..343022e861afee9e3ae56062582d52aea9a7e65b 100644 (file)
@@ -1,25 +1,11 @@
-/*
- * 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.
- */
-
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.projectImport;
 
 import com.intellij.ide.util.PropertiesComponent;
 import com.intellij.ide.util.projectWizard.WizardContext;
 import com.intellij.openapi.components.StorageScheme;
 import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
 
@@ -28,7 +14,7 @@ public class ProjectFormatPanel {
   public static final String DIR_BASED = Project.DIRECTORY_STORE_FOLDER + " (directory based)";
   private static final String FILE_BASED = ".ipr (file based)";
 
-  private JComboBox myStorageFormatCombo;
+  private JComboBox<String> myStorageFormatCombo;
   private JPanel myWholePanel;
 
   public ProjectFormatPanel() {
@@ -41,19 +27,15 @@ public class ProjectFormatPanel {
     return myWholePanel;
   }
 
+  @NotNull
   public JComboBox getStorageFormatComboBox() {
     return myStorageFormatCombo;
   }
 
-  public void updateData(WizardContext context) {
-    StorageScheme format =
-      FILE_BASED.equals(myStorageFormatCombo.getSelectedItem()) ? StorageScheme.DEFAULT : StorageScheme.DIRECTORY_BASED;
+  public void updateData(@NotNull WizardContext context) {
+    StorageScheme format = FILE_BASED.equals(myStorageFormatCombo.getSelectedItem()) ? StorageScheme.DEFAULT : StorageScheme.DIRECTORY_BASED;
     context.setProjectStorageFormat(format);
-    setDefaultFormat(isDefault());
-  }
-
-  public static void setDefaultFormat(boolean value) {
-    PropertiesComponent.getInstance().setValue(STORAGE_FORMAT_PROPERTY, value ? FILE_BASED : DIR_BASED, DIR_BASED);
+    PropertiesComponent.getInstance().setValue(STORAGE_FORMAT_PROPERTY, isDefault() ? FILE_BASED : DIR_BASED, DIR_BASED);
   }
 
   public void setVisible(boolean visible) {
index ae23e49e06195132080618d8bdd74b297f8fecf3..bd24227a6cea10d7da39c64471494da6920287fc 100644 (file)
  */
 package com.intellij.psi.codeStyle;
 
+import com.intellij.application.options.CodeStyle;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.InvalidDataException;
 import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.psi.PsiFile;
 import org.jdom.Element;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.TestOnly;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -368,7 +371,15 @@ public class JavaCodeStyleSettings extends CustomCodeStyleSettings implements Im
     }
   }
 
+  public static JavaCodeStyleSettings getInstance(@NotNull PsiFile file) {
+    return CodeStyle.getCustomSettings(file, JavaCodeStyleSettings.class);
+  }
+
+  /**
+   * For production code use {@link #getInstance(PsiFile)}
+   */
+  @TestOnly
   public static JavaCodeStyleSettings getInstance(@NotNull Project project) {
-    return CodeStyleSettingsManager.getSettings(project).getCustomSettings(JavaCodeStyleSettings.class);
+    return CodeStyle.getSettings(project).getCustomSettings(JavaCodeStyleSettings.class);
   }
 }
index 3df8d9f01953f50a81a6b4e4de281964f03a5be9..cdc5dcb82ea57d9c811f75110de7e6d252231ad0 100644 (file)
@@ -61,7 +61,7 @@ public class JavaCodeBlockModificationListener extends PsiTreeChangePreprocessor
 
   @Override
   protected boolean containsStructuralElements(@NotNull PsiElement element) {
-    return mayHaveJavaStructureInside(element);
+    return mayHaveModifiedJavaStructureInside(element);
   }
 
   @Override
@@ -69,7 +69,7 @@ public class JavaCodeBlockModificationListener extends PsiTreeChangePreprocessor
     Set<PsiElement> changedChildren = getChangedChildren(event);
 
     PsiModificationTrackerImpl tracker = (PsiModificationTrackerImpl)myPsiManager.getModificationTracker();
-    if (!changedChildren.isEmpty() && changedChildren.stream().anyMatch(JavaCodeBlockModificationListener::mayHaveJavaStructureInside)) {
+    if (!changedChildren.isEmpty() && changedChildren.stream().anyMatch(JavaCodeBlockModificationListener::mayHaveModifiedJavaStructureInside)) {
       tracker.incCounter();
     }
 
@@ -104,12 +104,12 @@ public class JavaCodeBlockModificationListener extends PsiTreeChangePreprocessor
     return Collections.emptySet();
   }
 
-  private static boolean mayHaveJavaStructureInside(@NotNull PsiElement root) {
-    return !SyntaxTraverser.psiTraverser(root)
+  private static boolean mayHaveModifiedJavaStructureInside(@NotNull PsiElement root) {
+    return SyntaxTraverser.psiTraverser(root)
       .expand(e -> !TreeUtil.isCollapsedChameleon(e.getNode()))
       .traverse()
+      .filter(e -> !(e instanceof PsiModifiableCodeBlock) || ((PsiModifiableCodeBlock)e).shouldChangeModificationCount(e))
       .filter(e -> e instanceof PsiClass || e instanceof PsiLambdaExpression || TreeUtil.isCollapsedChameleon(e.getNode()))
-      .isEmpty();
+      .isNotEmpty();
   }
-
 }
diff --git a/java/java-tests/testData/codeInsight/parameterInfo/HighlightCurrentParameterAfterTypingFirstArgumentOfThree.java b/java/java-tests/testData/codeInsight/parameterInfo/HighlightCurrentParameterAfterTypingFirstArgumentOfThree.java
new file mode 100644 (file)
index 0000000..c2f1551
--- /dev/null
@@ -0,0 +1,7 @@
+class A {
+    void foo() {}
+    void foo(int a, int b, int c) {}
+    {
+        foo(<caret>)
+    }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/compileServer/incremental/membersChange/replaceMethodWithBridge.log b/java/java-tests/testData/compileServer/incremental/membersChange/replaceMethodWithBridge.log
new file mode 100644 (file)
index 0000000..7e4d3f2
--- /dev/null
@@ -0,0 +1,12 @@
+Cleaning output files:
+out/production/ReplaceMethodWithBridge/stubs/StubBase.class
+End of files
+Compiling files:
+src/stubs/StubBase.java
+End of files
+Cleaning output files:
+out/production/ReplaceMethodWithBridge/ppp/Util.class
+End of files
+Compiling files:
+src/ppp/Util.java
+End of files
\ No newline at end of file
diff --git a/java/java-tests/testData/compileServer/incremental/membersChange/replaceMethodWithBridge/src/ppp/Util.java b/java/java-tests/testData/compileServer/incremental/membersChange/replaceMethodWithBridge/src/ppp/Util.java
new file mode 100644 (file)
index 0000000..cc39da5
--- /dev/null
@@ -0,0 +1,11 @@
+package ppp;
+
+import stubs.StubBase;
+import stubs.StubElement;
+
+public class Util {
+  public void calcParent(StubBase stub) { // using raw type 'StubBase', this is important!
+    final StubElement parent = stub.getParentStub();
+  }
+}
+
diff --git a/java/java-tests/testData/compileServer/incremental/membersChange/replaceMethodWithBridge/src/stubs/ObjectStubBase.java b/java/java-tests/testData/compileServer/incremental/membersChange/replaceMethodWithBridge/src/stubs/ObjectStubBase.java
new file mode 100644 (file)
index 0000000..75f9eb5
--- /dev/null
@@ -0,0 +1,9 @@
+package stubs;
+
+public class ObjectStubBase<T extends Stub> implements Stub {
+  protected T myParent;
+
+  public T getParentStub() {
+    return myParent;
+  }
+}
diff --git a/java/java-tests/testData/compileServer/incremental/membersChange/replaceMethodWithBridge/src/stubs/Stub.java b/java/java-tests/testData/compileServer/incremental/membersChange/replaceMethodWithBridge/src/stubs/Stub.java
new file mode 100644 (file)
index 0000000..14fa5cd
--- /dev/null
@@ -0,0 +1,5 @@
+package stubs;
+
+public interface Stub {
+  Stub getParentStub();
+}
diff --git a/java/java-tests/testData/compileServer/incremental/membersChange/replaceMethodWithBridge/src/stubs/StubBase.java b/java/java-tests/testData/compileServer/incremental/membersChange/replaceMethodWithBridge/src/stubs/StubBase.java
new file mode 100644 (file)
index 0000000..31f8f63
--- /dev/null
@@ -0,0 +1,7 @@
+package stubs;
+
+public class StubBase<T> extends ObjectStubBase<StubElement> implements StubElement{
+  public StubElement getParentStub() {
+    return myParent;
+  }
+}
diff --git a/java/java-tests/testData/compileServer/incremental/membersChange/replaceMethodWithBridge/src/stubs/StubBase.java.new b/java/java-tests/testData/compileServer/incremental/membersChange/replaceMethodWithBridge/src/stubs/StubBase.java.new
new file mode 100644 (file)
index 0000000..d857892
--- /dev/null
@@ -0,0 +1,4 @@
+package stubs;
+
+public class StubBase<T> extends ObjectStubBase<StubElement> implements StubElement{
+}
diff --git a/java/java-tests/testData/compileServer/incremental/membersChange/replaceMethodWithBridge/src/stubs/StubElement.java b/java/java-tests/testData/compileServer/incremental/membersChange/replaceMethodWithBridge/src/stubs/StubElement.java
new file mode 100644 (file)
index 0000000..19cf103
--- /dev/null
@@ -0,0 +1,5 @@
+package stubs;
+
+public interface StubElement extends Stub{
+  StubElement getParentStub();
+}
diff --git a/java/java-tests/testData/junit/configurations/mock JUnit/junit/framework/TestCase.class b/java/java-tests/testData/junit/configurations/mock JUnit/junit/framework/TestCase.class
deleted file mode 100644 (file)
index bdd44ce..0000000
Binary files a/java/java-tests/testData/junit/configurations/mock JUnit/junit/framework/TestCase.class and /dev/null differ
diff --git a/java/java-tests/testData/junit/configurations/mock JUnit/junit/framework/TestCase.java b/java/java-tests/testData/junit/configurations/mock JUnit/junit/framework/TestCase.java
deleted file mode 100644 (file)
index eaa745c..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-package junit.framework;
-public class TestCase {}
diff --git a/java/java-tests/testData/junit/configurations/mock JUnit/junit/framework/ThirdPartyClass.class b/java/java-tests/testData/junit/configurations/mock JUnit/junit/framework/ThirdPartyClass.class
deleted file mode 100644 (file)
index 1c51d38..0000000
Binary files a/java/java-tests/testData/junit/configurations/mock JUnit/junit/framework/ThirdPartyClass.class and /dev/null differ
diff --git a/java/java-tests/testData/junit/configurations/mock JUnit/junit/framework/ThirdPartyClass.java b/java/java-tests/testData/junit/configurations/mock JUnit/junit/framework/ThirdPartyClass.java
deleted file mode 100644 (file)
index d4f54aa..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-package junit.framework;
-public class ThirdPartyClass extends TestCase {}
diff --git a/java/java-tests/testData/junit/configurations/mock JUnit/org/junit/Test.class b/java/java-tests/testData/junit/configurations/mock JUnit/org/junit/Test.class
deleted file mode 100644 (file)
index 7123197..0000000
Binary files a/java/java-tests/testData/junit/configurations/mock JUnit/org/junit/Test.class and /dev/null differ
diff --git a/java/java-tests/testData/junit/configurations/mock JUnit/org/junit/Test.java b/java/java-tests/testData/junit/configurations/mock JUnit/org/junit/Test.java
deleted file mode 100644 (file)
index 66c78b4..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-package org.junit;
-public @interface Test {}
\ No newline at end of file
diff --git a/java/java-tests/testData/junit/configurations/mock JUnit/org/junit/runner/RunWith.class b/java/java-tests/testData/junit/configurations/mock JUnit/org/junit/runner/RunWith.class
deleted file mode 100644 (file)
index e059434..0000000
Binary files a/java/java-tests/testData/junit/configurations/mock JUnit/org/junit/runner/RunWith.class and /dev/null differ
diff --git a/java/java-tests/testData/junit/configurations/mock JUnit/org/junit/runner/RunWith.java b/java/java-tests/testData/junit/configurations/mock JUnit/org/junit/runner/RunWith.java
deleted file mode 100644 (file)
index b4b9e99..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-package org.junit.runner;
-@interface RunWith {
-    Class<? extends Runner> value();
-}
index 4669cc0058d0a4d40a3ce743c5bf094d8b271c17..c6c632bf68b8c6cf413d44c07940dafc372d315d 100644 (file)
@@ -1,6 +1,4 @@
 package test1;
 
-import junit.framework.ThirdPartyClass;
-
-public class DerivedTest extends ThirdPartyClass {
+public class DerivedTest extends ThirdPartyTest {
 }
\ No newline at end of file
diff --git a/java/java-tests/testData/junit/configurations/module1/test1/ThirdPartyTest.java b/java/java-tests/testData/junit/configurations/module1/test1/ThirdPartyTest.java
new file mode 100644 (file)
index 0000000..863666c
--- /dev/null
@@ -0,0 +1,3 @@
+package test1;
+import junit.framework.*;
+public class ThirdPartyTest extends TestCase {}
\ No newline at end of file
diff --git a/java/java-tests/testData/junit/configurations/module1/test1/nested/TestWithJunit4.java b/java/java-tests/testData/junit/configurations/module1/test1/nested/TestWithJunit4.java
new file mode 100644 (file)
index 0000000..39aa54c
--- /dev/null
@@ -0,0 +1,9 @@
+package test1.nested;
+
+@org.junit.runner.RunWith(org.junit.runners.Parameterized.class)
+public class TestWithJunit4 {
+  @org.junit.Test
+  public void test1() {}
+  
+  public static class InnerNoTests {}
+}
\ No newline at end of file
index d359ccced74ac177df69b0820e6898c745cb0b86..73e6a1264f4d6f2fb1003b2fdb630c6f82ea5d01 100644 (file)
@@ -361,4 +361,27 @@ public class ParameterInfoTest extends LightCodeInsightFixtureTestCase {
     myFixture.checkResultByFile(getTestName(false) + "_after.java");
   }
 
+  public void _testHighlightCurrentParameterAfterTypingFirstArgumentOfThree() {
+    myFixture.configureByFile(getTestName(false) + ".java");
+
+    MethodParameterInfoHandler handler = new MethodParameterInfoHandler();
+    CreateParameterInfoContext context = new MockCreateParameterInfoContext(getEditor(), getFile());
+    PsiExpressionList argList = handler.findElementForParameterInfo(context);
+    assertNotNull(argList);
+    Object[] items = context.getItemsToShow();
+    assertSize(2, items);
+
+    MockUpdateParameterInfoContext updateContext = updateParameterInfo(handler, argList, items);
+    assertTrue(updateContext.isUIComponentEnabled(0));
+    assertTrue(updateContext.isUIComponentEnabled(1));
+    assertEquals(0, updateContext.getCurrentParameter());
+
+    myFixture.type("1, ");
+    PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
+    handler.updateParameterInfo(argList, updateContext);
+    assertFalse(updateContext.isUIComponentEnabled(0));
+    assertTrue(updateContext.isUIComponentEnabled(1));
+    assertEquals(1, updateContext.getCurrentParameter());
+  }
+
 }
\ No newline at end of file
index c08662c140cad9ab67a8a4528b5090b743092437..7c8f80226583f2185767e95691b91132cdfd3d9a 100644 (file)
@@ -1773,13 +1773,10 @@ class Foo {
 
   void "test autopopup after package completion"() {
     myFixture.addClass("package foo.bar.goo; class Foo {}")
-    myFixture.configureByText "a.java", "class Foo { { foo.b<caret> } }"
-    def items = myFixture.completeBasic()
-    joinCompletion()
-    if (items != null) { // completion took a bit longer, and the single item wasn't inserted automatically 
-      assert myFixture.lookupElementStrings == ['bar']
-      myFixture.type('\n')
-    }
+    myFixture.configureByText "a.java", "class Foo { { foo.<caret> } }"
+    type 'b'
+    assert myFixture.lookupElementStrings == ['bar']
+    myFixture.type('\n')
     assert myFixture.editor.document.text.contains('foo.bar. ')
     joinAutopopup()
     joinCompletion()
index 74e2d3c5a4bcccc0c2089349d0d8fdf83aeb0574..2e1d68297c2a2ec953909a24a2e8a8774768577e 100644 (file)
@@ -23,6 +23,7 @@ import com.intellij.execution.actions.ConfigurationFromContext;
 import com.intellij.execution.actions.RunConfigurationProducer;
 import com.intellij.execution.configurations.RunConfiguration;
 import com.intellij.execution.junit.JUnitConfiguration;
+import com.intellij.execution.junit.JUnitUtil;
 import com.intellij.execution.testframework.AbstractJavaTestConfigurationProducer;
 import com.intellij.openapi.actionSystem.CommonDataKeys;
 import com.intellij.openapi.actionSystem.LangDataKeys;
@@ -37,6 +38,7 @@ import com.intellij.openapi.roots.ModuleRootManager;
 import com.intellij.openapi.roots.ModuleRootModificationUtil;
 import com.intellij.openapi.vfs.LocalFileSystem;
 import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.project.IntelliJProjectConfiguration;
 import com.intellij.psi.JavaPsiFacade;
 import com.intellij.psi.PsiClass;
 import com.intellij.psi.PsiElement;
@@ -51,7 +53,6 @@ import java.util.List;
 public abstract class BaseConfigurationTestCase extends IdeaTestCase {
   protected TempFiles myTempFiles;
   private final List<Module> myModulesToDispose = new ArrayList<>();
-  protected static final String MOCK_JUNIT = "mock JUnit";
 
   @Override
   protected void setUp() throws Exception {
@@ -83,13 +84,11 @@ public abstract class BaseConfigurationTestCase extends IdeaTestCase {
       PsiTestUtil.addContentRoot(module, module1Content);
     }
 
-    VirtualFile mockJUnit = findFile(MOCK_JUNIT);
-    ModuleRootModificationUtil.addModuleLibrary(module, mockJUnit.getUrl());
+    IntelliJProjectConfiguration.LibraryRoots junit4Library = IntelliJProjectConfiguration.getProjectLibrary("JUnit4");
+    ModuleRootModificationUtil.addModuleLibrary(module, "JUnit4", junit4Library.getClassesUrls(), junit4Library.getSourcesUrls());
     ModuleRootModificationUtil.setModuleSdk(module, ModuleRootManager.getInstance(myModule).getSdk());
     GlobalSearchScope scope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module);
-    VirtualFile testCase = mockJUnit.findFileByRelativePath("junit/framework/TestCase.java");
-    assertNotNull(testCase);
-    assertTrue(scope.contains(testCase));
+    assertNotNull(JavaPsiFacade.getInstance(getProject()).findClass(JUnitUtil.TEST_CASE_CLASS, scope));
     Module missingModule = createTempModule();
     addDependency(module, missingModule);
     ModuleManager.getInstance(myProject).disposeModule(missingModule);
index ae13e0c2725862261103fd70fcf81061871bff9f..fa87631dbd208cfb4faf94de689d4cf9abaa8dd4 100644 (file)
@@ -13,7 +13,10 @@ import com.intellij.execution.junit.AllInPackageConfigurationProducer;
 import com.intellij.execution.junit.JUnitConfiguration;
 import com.intellij.execution.junit.JUnitConfigurationType;
 import com.intellij.execution.testframework.AbstractJavaTestConfigurationProducer;
+import com.intellij.openapi.vfs.JarFileSystem;
+import com.intellij.openapi.vfs.LocalFileSystem;
 import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.project.IntelliJProjectConfiguration;
 import com.intellij.psi.*;
 import com.intellij.refactoring.PackageWrapper;
 import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesProcessor;
@@ -22,10 +25,11 @@ import com.intellij.refactoring.move.moveMembers.MockMoveMembersOptions;
 import com.intellij.refactoring.move.moveMembers.MoveMembersProcessor;
 import com.intellij.refactoring.rename.RenameProcessor;
 import com.intellij.testFramework.MapDataContext;
-import java.util.HashSet;
 import org.jetbrains.annotations.NotNull;
 
+import java.io.File;
 import java.io.IOException;
+import java.util.HashSet;
 
 public class ConfigurationRefactoringsTest extends BaseConfigurationTestCase {
   private static final String APPLICATION_CODE = "public class Application {" +
@@ -194,7 +198,12 @@ public class ConfigurationRefactoringsTest extends BaseConfigurationTestCase {
   private void initModule() {
     mySource.initModule();
     mySource.copyJdkFrom(myModule);
-    mySource.addLibrary(findFile(MOCK_JUNIT));
+    IntelliJProjectConfiguration.LibraryRoots junit4Library = IntelliJProjectConfiguration.getProjectLibrary("JUnit4");
+    for (File file : junit4Library.getClasses()) {
+      VirtualFile libFile = LocalFileSystem.getInstance().findFileByIoFile(file);
+      assertNotNull(libFile);
+      mySource.addLibrary(JarFileSystem.getInstance().getJarRootForLocalFile(libFile));
+    }
   }
 
   private void move(final PsiElement psiElement, String packageName) {
index 3b5464eb3be7b72cd1d57bda1139c62b310ab6e0..3981a9d918fc16fa69831d090e930d061ce780aa 100644 (file)
@@ -38,6 +38,7 @@ import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vfs.JarFileSystem;
 import com.intellij.openapi.vfs.LocalFileSystem;
 import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.project.IntelliJProjectConfiguration;
 import com.intellij.psi.*;
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.rt.ant.execution.SegmentedOutputStream;
@@ -158,7 +159,7 @@ public class ConfigurationsTest extends BaseConfigurationTestCase {
     PsiClass psiClass = findTestA(module1);
     PsiClass psiClass2 = findTestA(getModule2());
     PsiClass derivedTest = findClass(module1, "test1.DerivedTest");
-    PsiClass baseTestCase = findClass("junit.framework.ThirdPartyClass", module1AndLibraries);
+    PsiClass baseTestCase = findClass("test1.ThirdPartyTest", module1AndLibraries);
     PsiClass testB = findClass(getModule3(), "test1.TestB");
     assertNotNull(testCase);
     assertNotNull(derivedTest);
@@ -177,6 +178,8 @@ public class ConfigurationsTest extends BaseConfigurationTestCase {
         psiClass2.getQualifiedName(),
         derivedTest.getQualifiedName(), RT_INNER_TEST_NAME,
         "test1.nested.TestA",
+        "test1.nested.TestWithJunit4",
+        "test1.ThirdPartyTest",
         testB.getQualifiedName()},
       lines);
   }
@@ -259,7 +262,10 @@ public class ConfigurationsTest extends BaseConfigurationTestCase {
     CHECK.singleOccurence(classPath, getOutput(module2, true));
     CHECK.singleOccurence(classPath, getOutput(module3, false));
     CHECK.singleOccurence(classPath, getOutput(module3, true));
-    CHECK.singleOccurence(classPath, getFSPath(findFile(MOCK_JUNIT)));
+    IntelliJProjectConfiguration.LibraryRoots junit4Library = IntelliJProjectConfiguration.getProjectLibrary("JUnit4");
+    for (File file : junit4Library.getClasses()) {
+      CHECK.singleOccurence(classPath, file.getPath());
+    }
   }
 
   public void testExternalizeJUnitConfiguration() {
@@ -489,7 +495,10 @@ public class ConfigurationsTest extends BaseConfigurationTestCase {
         CompilerTester tester = new CompilerTester(project, Arrays.asList(ModuleManager.getInstance(project).getModules()));
         try {
           List<CompilerMessage> messages = tester.make();
-          assertFalse(messages.stream().anyMatch(message -> message.getCategory() == CompilerMessageCategory.ERROR));
+          assertFalse(messages.stream().filter(message -> message.getCategory() == CompilerMessageCategory.ERROR)
+                              .map(message -> message.getMessage())
+                              .findFirst().orElse("Compiles fine"),
+                      messages.stream().anyMatch(message -> message.getCategory() == CompilerMessageCategory.ERROR));
           task.startSearch();
         }
         finally {
index 344916a42e3d0cc7eeca4fc82c1694d4ef95ffbb..3a81b8c00407cf552623f80ddc7ef502a42def18 100644 (file)
@@ -1,18 +1,4 @@
-/*
- * Copyright 2000-2017 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.
- */
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.java.refactoring;
 
 import com.intellij.JavaTestUtil;
@@ -432,7 +418,9 @@ public class SafeDeleteTest extends MultiFileTestCase {
     final PsiClass aClass = myJavaFacade.findClass(qClassName, GlobalSearchScope.allScope(getProject()));
     assertNotNull("Class " + qClassName + " not found", aClass);
     configureByExistingFile(aClass.getContainingFile().getVirtualFile());
-
+    if (myEditor.getCaretModel().getOffset() == 0) {
+      myEditor.getCaretModel().moveToOffset(aClass.getTextOffset());
+    }
     performAction();
   }
 
similarity index 99%
rename from java/java-tests/testSrc/com/intellij/java/psi/PsiModificationTrackerTest.java
rename to java/java-tests/testSrc/com/intellij/psi/impl/PsiModificationTrackerTest.java
index 295cadfd8f78e866b8fbf90d759695a27fbc621b..00efef76d9ffb9f601f81811152fbce3cb843454 100644 (file)
@@ -1,5 +1,5 @@
 // Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
-package com.intellij.java.psi;
+package com.intellij.psi.impl;
 
 import com.intellij.codeInsight.CodeInsightTestCase;
 import com.intellij.ide.highlighter.JavaFileType;
@@ -18,8 +18,6 @@ import com.intellij.openapi.vfs.*;
 import com.intellij.pom.java.LanguageLevel;
 import com.intellij.project.ProjectKt;
 import com.intellij.psi.*;
-import com.intellij.psi.impl.DocumentCommitThread;
-import com.intellij.psi.impl.PsiManagerEx;
 import com.intellij.psi.impl.file.impl.FileManagerImpl;
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.psi.util.PsiModificationTracker;
@@ -427,7 +425,7 @@ public class PsiModificationTrackerTest extends CodeInsightTestCase {
 
   public void testNoIncrementOnWorkspaceFileChange() {
     FixtureRuleKt.runInLoadComponentStateMode(myProject, () -> {
-      ProjectKt.getStateStore(myProject).save(new SmartList<>(), false);
+      ProjectKt.getStateStore(myProject).save(new SmartList<>(), true);
 
       PsiModificationTracker tracker = getTracker();
       long mc = tracker.getModificationCount();
@@ -505,10 +503,10 @@ public class PsiModificationTrackerTest extends CodeInsightTestCase {
     WriteCommandAction.runWriteCommandAction(getProject(), () -> {
       TextRange methodRange = anon.getMethods()[0].getTextRange();
       getEditor().getDocument().deleteString(methodRange.getStartOffset(), methodRange.getEndOffset());
-      
+
       int gooIndex = file.getText().indexOf("goo");
       getEditor().getDocument().deleteString(gooIndex, gooIndex + 3);
-      
+
       PsiDocumentManager.getInstance(myProject).commitDocument(getEditor().getDocument());
     });
 
@@ -544,7 +542,7 @@ public class PsiModificationTrackerTest extends CodeInsightTestCase {
 
     PsiUtilCore.ensureValid(method);
     Arrays.stream(method.findSuperMethods()).forEach(PsiUtilCore::ensureValid);
-    
+
     assertFalse(javaCount == getTracker().getJavaStructureModificationCount());
   }
 
@@ -552,5 +550,4 @@ public class PsiModificationTrackerTest extends CodeInsightTestCase {
   private PsiModificationTracker getTracker() {
     return PsiManager.getInstance(getProject()).getModificationTracker();
   }
-
 }
index bbdd6d6b900b83dada2f0143e7dce86a33e22867..1840d40415b539d4f3bb74ec618cc20d66533085 100644 (file)
@@ -327,7 +327,7 @@ public class Mappings {
             final MethodRepr memberMethod = (MethodRepr)member;
             return memberMethod.name == m.name && Arrays.equals(memberMethod.myArgumentTypes, m.myArgumentTypes);
           }
-          return member.name == m.name;
+          return false;
         }
       }, className);
     }
@@ -1482,11 +1482,17 @@ public class Mappings {
             }
           }
           else if ((d.base() & Difference.ACCESS) != 0) {
-            if ((d.addedModifiers() & Opcodes.ACC_STATIC) != 0 ||
-                (d.removedModifiers() & Opcodes.ACC_STATIC) != 0 ||
-                (d.addedModifiers() & Opcodes.ACC_PRIVATE) != 0) {
+            if ((d.addedModifiers() & (Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_BRIDGE)) != 0 ||
+                (d.removedModifiers() & Opcodes.ACC_STATIC) != 0) {
+
+              // When synthetic or bridge flags are added, this effectively means that explicitly written in the code
+              // method with the same signature and return type has been removed and a bridge method has been generated instead.
+              // In some cases (e.g. using raw types) the presence of such synthetic methods in the bytecode is ignored by the compiler
+              // so that the code that called such method via raw type reference might not compile anymore => to be on the safe side
+              // we should recompile all places where the method was used
+
               if (!affected) {
-                debug("Added static or private specifier or removed static specifier --- affecting method usages");
+                debug("Added {static | private | synthetic | bridge} specifier or removed static specifier --- affecting method usages");
                 myFuture.affectMethodUsages(m, propagated, m.createUsage(myContext, it.name), usages, state.myDependants);
                 state.myAffectedUsages.addAll(usages);
                 affected = true;
index 4aa6801eb93374ee6697312715b578047d29f973..e5d75175ef907627b19076905c44447712838448 100644 (file)
@@ -210,4 +210,8 @@ public class MemberChangeTest extends IncrementalTestCase {
   public void testAddVarargMethod() {
     doTest();
   }
+
+  public void testReplaceMethodWithBridge() {
+    doTest();
+  }
 }
index 2047d374685cb33feaf955f38edd3bafb89fd7be..04d842e665335fc701fd1ff7f1c7fab1e14d79e6 100644 (file)
@@ -38,14 +38,16 @@ class WinExeInstallerBuilder {
   }
 
   private void generateInstallationConfigFileForSilentMode() {
-    File silentConfigFile = new File (customizer.silentInstallationConfig == null ?
+    String silentConfigTemplate = (customizer.silentInstallationConfig == null ?
                           "$buildContext.paths.communityHome/platform/build-scripts/resources/win/nsis/silent.config" :
                           customizer.silentInstallationConfig)
-    if (! silentConfigFile.exists()) {
+    if (! new File(silentConfigTemplate).exists()) {
       buildContext.messages.error(
-        "Silent config file for Windows installer won't be generated. The template doesn't exist: '${silentConfig}'")
+        "Silent config file for Windows installer won't be generated. The template doesn't exist: $silentConfigTemplate")
     }
     else {
+      buildContext.ant.copy(file: "$silentConfigTemplate", todir: "${buildContext.paths.artifacts}")
+      File silentConfigFile = new File ("${buildContext.paths.artifacts}/silent.config")
       def extensionsList = customizer.fileAssociations
       String associations = "\n\n; List of associations. To create an association change value to 1.\n"
       if (! extensionsList.isEmpty()) {
@@ -55,7 +57,6 @@ class WinExeInstallerBuilder {
         associations = "\n\n; There are no associations for the product.\n"
       }
       silentConfigFile.append(associations)
-      buildContext.ant.copy(file: silentConfigFile, todir: "${buildContext.paths.artifacts}")
     }
   }
 
index 4c4f1c34f7c001a334dd4ef464cc530dae939c11..7bb9b4c62478c9371c903ec8fc8f9415e3842d60 100644 (file)
@@ -13,7 +13,7 @@ $mountName = $ARGV[2];
     &makeEntries(".DS_Store", Iloc_xy => [ 610, 170 ]),
     &makeEntries(".fseventsd", Iloc_xy => [ 660, 170 ]),
     &makeEntries(".Trashes", Iloc_xy => [ 710, 170 ]),
-    &makeEntries(" ", Iloc_xy => [ 335, 120 ]),
+    &makeEntries("Applications", Iloc_xy => [ 340, 167 ]),
     &makeEntries(".",
         BKGD_alias => NewAliasMinimal("/Volumes/$mountName/.background/$bg_pic"),
         ICVO => 1,
@@ -23,6 +23,6 @@ $mountName = $ARGV[2];
         icvo => pack('A4 n A4 A4 n*', "icv4", 100, "none", "botm", 0, 0, 0, 0, 0, 1, 0, 100, 1),
         icvt => 12
     ),
-    &makeEntries("$name.app", Iloc_xy => [ 110, 120 ])
+    &makeEntries("$name.app", Iloc_xy => [ 110, 167 ])
 );
 
index 3b91e1811aa0c9938e1ca2c3a2281b7742d56311..daba1841e2f86080c1d4d9b2035a1cc89850df60 100644 (file)
@@ -28,7 +28,7 @@ chmod a+x ${EXPLODED}/"$BUILD_NAME"/Contents/bin/fs*
 
 mkdir ${EXPLODED}/.background
 mv ${BG_PIC} ${EXPLODED}/.background
-ln -s /Applications ${EXPLODED}/" "
+ln -s /Applications ${EXPLODED}/"Applications"
 # allocate space for .DS_Store
 dd if=/dev/zero of=${EXPLODED}/DSStorePlaceHolder bs=1024 count=512
 stat ${EXPLODED}/DSStorePlaceHolder
index 300646fe0c882e9ead3a35487b37b3d59154b32f..c844e64bdff6c3c8039f3427df590f42417f19ce 100644 (file)
@@ -1,18 +1,4 @@
-/*
- * 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.
- */
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.configurationStore
 
 import com.intellij.configurationStore.StateStorageManager.ExternalizationSession
@@ -373,7 +359,7 @@ abstract class ComponentStoreImpl : IComponentStore {
         }
 
         val storage = storageManager.getStateStorage(storageSpec)
-        val stateGetter = createStateGetter(isUseLoadedStateAsExisting(storage), storage, component, name, stateClass,
+        val stateGetter = createStateGetter(isUseLoadedStateAsExistingForComponent(storage, name), storage, component, name, stateClass,
                                             reloadData = reloadData)
         var state = stateGetter.getState(defaultState)
         if (state == null) {
@@ -407,13 +393,12 @@ abstract class ComponentStoreImpl : IComponentStore {
     return true
   }
 
-  // todo "ProjectModuleManager" investigate why after loadState we get empty state on getState, test CMakeWorkspaceContentRootsTest
   // todo fix FacetManager
   // use.loaded.state.as.existing used in upsource
-  private fun isUseLoadedStateAsExisting(storage: StateStorage, name: String): Boolean {
+  private fun isUseLoadedStateAsExistingForComponent(storage: StateStorage, name: String): Boolean {
     return isUseLoadedStateAsExisting(storage) &&
            name != "AntConfiguration" &&
-           name != "ProjectModuleManager" &&
+           name != "ProjectModuleManager" /* why after loadState we get empty state on getState, test CMakeWorkspaceContentRootsTest */ &&
            name != "FacetManager" &&
            name != "ProjectRunConfigurationManager" && /* ProjectRunConfigurationManager is used only for IPR, avoid relatively cost call getState */
            name != "NewModuleRootManager" /* will be changed only on actual user change, so, to speed up module loading, skip it */ &&
index c888b1cc6d41570548ce4d285a3de852dc6e4702..ca81eacd37d75f4ed761d06f186829745f04525c 100644 (file)
@@ -1,18 +1,4 @@
-/*
- * 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.
- */
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.configurationStore
 
 import com.intellij.configurationStore.schemeManager.createDir
@@ -118,33 +104,33 @@ open class DirectoryBasedStorage(private val dir: Path,
     override fun setSerializedState(componentName: String, element: Element?) {
       storage.componentName = componentName
 
-      if (element.isEmpty()) {
+      val stateAndFileNameList = if (element.isEmpty()) emptyList() else storage.splitter.splitState(element!!)
+      if (stateAndFileNameList.isEmpty()) {
         if (copiedStorageData != null) {
           copiedStorageData!!.clear()
         }
         else if (!originalStates.isEmpty()) {
-          copiedStorageData = THashMap<String, Any>()
+          copiedStorageData = THashMap()
         }
+        return
       }
-      else {
-        val stateAndFileNameList = storage.splitter.splitState(element!!)
-        val existingFiles = THashSet<String>(stateAndFileNameList.size)
-        for (pair in stateAndFileNameList) {
-          doSetState(pair.second, pair.first)
-          existingFiles.add(pair.second)
-        }
 
-        for (key in originalStates.keys()) {
-          if (existingFiles.contains(key)) {
-            continue
-          }
+      val existingFiles = THashSet<String>(stateAndFileNameList.size)
+      for (pair in stateAndFileNameList) {
+        doSetState(pair.second, pair.first)
+        existingFiles.add(pair.second)
+      }
 
-          if (copiedStorageData == null) {
-            copiedStorageData = originalStates.toMutableMap()
-          }
-          someFileRemoved = true
-          copiedStorageData!!.remove(key)
+      for (key in originalStates.keys()) {
+        if (existingFiles.contains(key)) {
+          continue
+        }
+
+        if (copiedStorageData == null) {
+          copiedStorageData = originalStates.toMutableMap()
         }
+        someFileRemoved = true
+        copiedStorageData!!.remove(key)
       }
     }
 
@@ -241,9 +227,6 @@ open class DirectoryBasedStorage(private val dir: Path,
   }
 }
 
-/**
- * @return pair.first - file contents (null if file does not exist), pair.second - file line separators
- */
 private fun getOrDetectLineSeparator(file: VirtualFile): LineSeparator? {
   if (!file.exists()) {
     return null
index bc4e57700026976607b1f37686a9e2d1b3c045d8..64ee82d9ad5d05697793f086429bd222ca23c474 100644 (file)
@@ -1,18 +1,4 @@
-/*
- * 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.
- */
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.configurationStore
 
 import com.intellij.openapi.application.ApplicationManager
@@ -21,11 +7,11 @@ import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream
 import com.intellij.openapi.util.text.StringUtil
 import com.intellij.util.ArrayUtil
 import com.intellij.util.SystemProperties
+import com.intellij.util.isEmpty
 import gnu.trove.THashMap
 import org.iq80.snappy.SnappyFramedInputStream
 import org.iq80.snappy.SnappyFramedOutputStream
 import org.jdom.Element
-import org.jdom.JDOMInterner
 import java.io.ByteArrayInputStream
 import java.util.*
 import java.util.concurrent.atomic.AtomicReferenceArray
@@ -158,7 +144,7 @@ class StateMap private constructor(private val names: Array<String>, private val
       return null
     }
 
-    val prev = states.getAndUpdate(index, { state -> if (archive && state is Element) archiveState(state).toByteArray() else state });
+    val prev = states.getAndUpdate(index, { state -> if (archive && state is Element) archiveState(state).toByteArray() else state })
     return prev as? Element
   }
 
@@ -174,7 +160,7 @@ class StateMap private constructor(private val names: Array<String>, private val
 
 fun setStateAndCloneIfNeed(key: String, newState: Element?, oldStates: StateMap, newLiveStates: MutableMap<String, Element>? = null): MutableMap<String, Any>? {
   val oldState = oldStates.get(key)
-  if (newState == null || JDOMUtil.isEmpty(newState)) {
+  if (newState == null || newState.isEmpty()) {
     if (oldState == null) {
       return null
     }
@@ -207,7 +193,7 @@ internal fun updateState(states: MutableMap<String, Any>, key: String, newState:
     states.remove(key)
     return true
   }
-  var newStateInterned = JDOMUtil.internElement(newState)
+  val newStateInterned = JDOMUtil.internElement(newState)
   newLiveStates?.put(key, newStateInterned)
 
   val oldState = states.get(key)
index 27c40c26a4634b575757fb58c44e0899e3b1ff72..943ecae95e824f9e5189be0ce9edd7ad30bcb6c8 100644 (file)
@@ -1,18 +1,4 @@
-/*
- * 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.
- */
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.configurationStore
 
 import com.intellij.openapi.components.RoamingType
@@ -223,6 +209,7 @@ private fun save(states: StateMap, rootElementName: String?, newLiveStates: Map<
     // name attribute should be first
     val elementAttributes = element.attributes
     var nameAttribute = element.getAttribute(FileStorageCoreUtil.NAME)
+    @Suppress("SuspiciousEqualsCombination")
     if (nameAttribute != null && nameAttribute === elementAttributes.get(0) && componentName == nameAttribute.value) {
       // all is OK
     }
index a1c7aaacb6ffb8916e2440e5552b15feb7070fd6..6d111190bdbf1cd8fb530bca4b19061314acccd2 100644 (file)
@@ -1,3 +1,4 @@
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.configurationStore
 
 import com.intellij.ide.util.PropertiesComponent
@@ -75,8 +76,8 @@ class DoNotSaveDefaultsTest {
       })
     }
 
-    // <property name="file.gist.reindex.count" value="54" />
     val propertyComponent = PropertiesComponent.getInstance()
+    // <property name="file.gist.reindex.count" value="54" />
     propertyComponent.unsetValue("file.gist.reindex.count")
     // <property name="CommitChangeListDialog.DETAILS_SPLITTER_PROPORTION_2" value="1.0" />
     propertyComponent.unsetValue("CommitChangeListDialog.DETAILS_SPLITTER_PROPORTION_2")
index fd762c848067693653f71f26f332767665e8cc3c..b72cd518842ffed4a1144779cecdb6ebfe67a0f9 100644 (file)
@@ -290,7 +290,7 @@ public class PomModelImpl extends UserDataHolderBase implements PomModel {
 
   @Nullable
   private Runnable reparseFile(@NotNull final PsiFile file, @NotNull FileElement treeElement, @NotNull CharSequence newText) {
-    TextRange changedPsiRange = DocumentCommitThread.getChangedPsiRange(file, treeElement, newText);
+    TextRange changedPsiRange = ChangedPsiRangeUtil.getChangedPsiRange(file, treeElement, newText);
     if (changedPsiRange == null) return null;
 
     Runnable reparseLeaf = tryReparseOneLeaf(treeElement, newText, changedPsiRange);
diff --git a/platform/core-impl/src/com/intellij/psi/impl/ChangedPsiRangeUtil.java b/platform/core-impl/src/com/intellij/psi/impl/ChangedPsiRangeUtil.java
new file mode 100644 (file)
index 0000000..257ed28
--- /dev/null
@@ -0,0 +1,110 @@
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package com.intellij.psi.impl;
+
+import com.intellij.lang.ASTNode;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.event.DocumentEvent;
+import com.intellij.openapi.util.ProperTextRange;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.impl.source.tree.FileElement;
+import com.intellij.psi.impl.source.tree.ForeignLeafPsiElement;
+import com.intellij.psi.impl.source.tree.TreeUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+public class ChangedPsiRangeUtil {
+  private static int getLeafMatchingLength(CharSequence leafText, CharSequence pattern, int patternIndex, int finalPatternIndex, int direction) {
+    int leafIndex = direction == 1 ? 0 : leafText.length() - 1;
+    int finalLeafIndex = direction == 1 ? leafText.length() - 1 : 0;
+    int result = 0;
+    while (leafText.charAt(leafIndex) == pattern.charAt(patternIndex)) {
+      result++;
+      if (leafIndex == finalLeafIndex || patternIndex == finalPatternIndex) {
+        break;
+      }
+      leafIndex += direction;
+      patternIndex += direction;
+    }
+    return result;
+  }
+
+  private static int getMatchingLength(@NotNull FileElement treeElement, @NotNull CharSequence text, boolean fromStart) {
+    int patternIndex = fromStart ? 0 : text.length() - 1;
+    int finalPatternIndex = fromStart ? text.length() - 1 : 0;
+    int direction = fromStart ? 1 : -1;
+    ASTNode leaf = fromStart ? TreeUtil.findFirstLeaf(treeElement, false) : TreeUtil.findLastLeaf(treeElement, false);
+    int result = 0;
+    while (leaf != null && (fromStart ? patternIndex <= finalPatternIndex : patternIndex >= finalPatternIndex)) {
+      if (!(leaf instanceof ForeignLeafPsiElement)) {
+        CharSequence chars = leaf.getChars();
+        if (chars.length() > 0) {
+          int matchingLength = getLeafMatchingLength(chars, text, patternIndex, finalPatternIndex, direction);
+          result += matchingLength;
+          if (matchingLength != chars.length()) {
+            break;
+          }
+          patternIndex += fromStart ? matchingLength : -matchingLength;
+        }
+      }
+      leaf = fromStart ? TreeUtil.nextLeaf(leaf, false) : TreeUtil.prevLeaf(leaf, false);
+    }
+    return result;
+  }
+
+  @Nullable
+  public static TextRange getChangedPsiRange(@NotNull PsiFile file, @NotNull FileElement treeElement, @NotNull CharSequence newDocumentText) {
+    int psiLength = treeElement.getTextLength();
+    if (!file.getViewProvider().supportsIncrementalReparse(file.getLanguage())) {
+      return new TextRange(0, psiLength);
+    }
+
+    int commonPrefixLength = getMatchingLength(treeElement, newDocumentText, true);
+    if (commonPrefixLength == newDocumentText.length() && newDocumentText.length() == psiLength) {
+      return null;
+    }
+
+    int commonSuffixLength = Math.min(getMatchingLength(treeElement, newDocumentText, false), psiLength - commonPrefixLength);
+    return new TextRange(commonPrefixLength, psiLength - commonSuffixLength);
+  }
+
+  @Nullable
+  static ProperTextRange getChangedPsiRange(@NotNull PsiFile file,
+                                            @NotNull Document document,
+                                            @NotNull CharSequence oldDocumentText,
+                                            @NotNull CharSequence newDocumentText) {
+    int psiLength = oldDocumentText.length();
+    if (!file.getViewProvider().supportsIncrementalReparse(file.getLanguage())) {
+      return new ProperTextRange(0, psiLength);
+    }
+    List<DocumentEvent> events = ((PsiDocumentManagerBase)PsiDocumentManager.getInstance(file.getProject())).getEventsSinceCommit(
+      document);
+    int prefix = Integer.MAX_VALUE;
+    int suffix = Integer.MAX_VALUE;
+    int lengthBeforeEvent = psiLength;
+    for (DocumentEvent event : events) {
+      prefix = Math.min(prefix, event.getOffset());
+      suffix = Math.min(suffix, lengthBeforeEvent - event.getOffset() - event.getOldLength());
+      lengthBeforeEvent = lengthBeforeEvent - event.getOldLength() + event.getNewLength();
+    }
+    if ((prefix == psiLength || suffix == psiLength) && newDocumentText.length() == psiLength) {
+      return null;
+    }
+    //Important! delete+insert sequence can give some of same chars back, lets grow affixes to include them.
+    int shortestLength = Math.min(psiLength, newDocumentText.length());
+    while (prefix < shortestLength &&
+           oldDocumentText.charAt(prefix) == newDocumentText.charAt(prefix)) {
+      prefix++;
+    }
+    while (suffix < shortestLength - prefix &&
+           oldDocumentText.charAt(psiLength - suffix - 1) == newDocumentText.charAt(newDocumentText.length() - suffix - 1)) {
+      suffix++;
+    }
+    int end = Math.max(prefix, psiLength - suffix);
+    if (end == prefix && newDocumentText.length() == oldDocumentText.length()) return null;
+    return ProperTextRange.create(prefix, end);
+  }
+}
index 299950966baca4eafe38c0ca2b2845655e1deaf3..682965c777ead5b8aec2331472b455c9170336ce 100644 (file)
@@ -11,7 +11,6 @@ import com.intellij.openapi.application.ex.ApplicationEx;
 import com.intellij.openapi.components.ServiceManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.event.DocumentEvent;
 import com.intellij.openapi.editor.ex.DocumentEx;
 import com.intellij.openapi.progress.ProcessCanceledException;
 import com.intellij.openapi.progress.ProgressIndicator;
@@ -21,20 +20,11 @@ import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.*;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.pom.PomManager;
-import com.intellij.pom.PomModel;
-import com.intellij.pom.event.PomModelEvent;
-import com.intellij.pom.impl.PomTransactionBase;
-import com.intellij.pom.tree.TreeAspect;
-import com.intellij.pom.tree.TreeAspectEvent;
 import com.intellij.psi.*;
-import com.intellij.psi.codeStyle.CodeStyleManager;
 import com.intellij.psi.impl.source.PsiFileImpl;
 import com.intellij.psi.impl.source.text.BlockSupportImpl;
 import com.intellij.psi.impl.source.text.DiffLog;
 import com.intellij.psi.impl.source.tree.FileElement;
-import com.intellij.psi.impl.source.tree.ForeignLeafPsiElement;
-import com.intellij.psi.impl.source.tree.TreeUtil;
 import com.intellij.psi.text.BlockSupport;
 import com.intellij.util.ExceptionUtil;
 import com.intellij.util.SmartList;
@@ -48,12 +38,7 @@ import org.jetbrains.annotations.Nullable;
 import org.jetbrains.annotations.TestOnly;
 import org.jetbrains.ide.PooledThreadExecutor;
 
-import javax.swing.*;
-import java.text.SimpleDateFormat;
-import java.util.Collections;
-import java.util.Date;
 import java.util.List;
-import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.TimeUnit;
@@ -74,10 +59,10 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
   private CommitTask currentTask; // guarded by lock
   private boolean myEnabled; // true if we can do commits. set to false temporarily during the write action.  guarded by lock
 
-  public static DocumentCommitThread getInstance() {
+  static DocumentCommitThread getInstance() {
     return (DocumentCommitThread)ServiceManager.getService(DocumentCommitProcessor.class);
   }
-  public DocumentCommitThread(final ApplicationEx application) {
+  DocumentCommitThread(final ApplicationEx application) {
     myApplication = application;
     // install listener in EDT to avoid missing events in case we are inside write action right now
     application.invokeLater(() -> {
@@ -145,10 +130,10 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
     assert !isDisposed : "already disposed";
 
     if (!project.isInitialized()) return;
-    PsiFile psiFile = PsiDocumentManager.getInstance(project).getCachedPsiFile(document);
+    PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
+    PsiFile psiFile = documentManager.getCachedPsiFile(document);
     if (psiFile == null || psiFile instanceof PsiCompiledElement) return;
-    doQueue(project, document, getAllFileNodes(psiFile), reason, context,
-            PsiDocumentManager.getInstance(project).getLastCommittedText(document));
+    doQueue(project, document, getAllFileNodes(psiFile), reason, context, documentManager.getLastCommittedText(document));
   }
 
   private void doQueue(@NotNull Project project,
@@ -159,8 +144,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
                        @NotNull CharSequence lastCommittedText) {
     synchronized (lock) {
       if (!project.isInitialized()) return;  // check the project is disposed under lock.
-      CommitTask newTask = createNewTaskAndCancelSimilar(project, document, oldFileNodes, reason, context,
-                                                         lastCommittedText);
+      CommitTask newTask = createNewTaskAndCancelSimilar(project, document, oldFileNodes, reason, context, lastCommittedText);
 
       documentsToCommit.offer(newTask);
       log(project, "Queued", newTask, reason);
@@ -180,8 +164,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
       for (Pair<PsiFileImpl, FileASTNode> pair : oldFileNodes) {
         assert pair.first.getProject() == project;
       }
-      CommitTask newTask = new CommitTask(project, document, oldFileNodes, createProgressIndicator(), reason, context,
-                                          lastCommittedText);
+      CommitTask newTask = new CommitTask(project, document, oldFileNodes, createProgressIndicator(), reason, context, lastCommittedText);
       cancelAndRemoveFromDocsToCommit(newTask, reason);
       cancelAndRemoveCurrentTask(newTask, reason);
       cancelAndRemoveFromDocsToApplyInEDT(newTask, reason);
@@ -190,59 +173,8 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
     }
   }
 
-  @SuppressWarnings({"NonConstantStringShouldBeStringBuffer", "StringConcatenationInLoop"})
-  public void log(Project project, @NonNls String msg, @Nullable CommitTask task, @NonNls Object... args) {
-    if (true) return;
-
-    String indent = new SimpleDateFormat("hh:mm:ss:SSSS").format(new Date()) +
-      (SwingUtilities.isEventDispatchThread() ?        "-(EDT) " :
-                                                       "-(" + Thread.currentThread()+ " ");
-    @NonNls
-    String s = indent + msg + (task == null ? " - " : "; task: " + task);
-
-    for (Object arg : args) {
-      if (!StringUtil.isEmpty(String.valueOf(arg))) {
-        s += "; "+arg;
-        if (arg instanceof Document) {
-          Document document = (Document)arg;
-          s+= " (\""+StringUtil.first(document.getImmutableCharSequence(), 40, true).toString().replaceAll("\n", " ")+"\")";
-        }
-      }
-    }
-    if (task != null) {
-      if (task.indicator.isCanceled()) {
-        s += "; indicator: " + task.indicator;
-      }
-      Document document = task.getDocument();
-      boolean stillUncommitted = !task.project.isDisposed() &&
-                                 ((PsiDocumentManagerBase)PsiDocumentManager.getInstance(task.project)).isInUncommittedSet(document);
-      if (stillUncommitted) {
-        s += "; still uncommitted";
-      }
-
-      Set<Document> uncommitted = project == null || project.isDisposed() ? Collections.emptySet() :
-                                  ((PsiDocumentManagerBase)PsiDocumentManager.getInstance(project)).myUncommittedDocuments;
-      if (!uncommitted.isEmpty()) {
-        s+= "; uncommitted: "+uncommitted;
-      }
-    }
-    synchronized (lock) {
-      int size = documentsToCommit.size();
-      if (size != 0) {
-        s += " (" + size + " documents still in queue: ";
-        int i = 0;
-        for (CommitTask commitTask : documentsToCommit) {
-          s += commitTask + "; ";
-          if (++i > 4) {
-            s += " ... ";
-            break;
-          }
-        }
-        s += ")";
-      }
-    }
-
-    LOG.debug(s);
+  @SuppressWarnings("unused")
+  private void log(Project project, @NonNls String msg, @Nullable CommitTask task, @NonNls Object... args) {
   }
 
 
@@ -270,7 +202,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
   }
 
   @TestOnly
-  public void clearQueue() {
+  void clearQueue() {
     synchronized (lock) {
       cancelAll();
       wakeUpQueue();
@@ -279,7 +211,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
 
   private void cancelAndRemoveCurrentTask(@NotNull CommitTask newTask, @NotNull Object reason) {
     CommitTask currentTask = this.currentTask;
-    if (currentTask != null && currentTask.equals(newTask)) {
+    if (newTask.equals(currentTask)) {
       cancelAndRemoveFromDocsToCommit(currentTask, reason);
       cancel(reason);
     }
@@ -323,44 +255,36 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
   // returns true if queue changed
   private boolean pollQueue() {
     assert !myApplication.isDispatchThread() : Thread.currentThread();
-    boolean success = false;
-    Document document = null;
-    Project project = null;
-    CommitTask task = null;
-    Object failureReason = null;
-    try {
-      ProgressIndicator indicator;
-      synchronized (lock) {
-        if (!myEnabled || (task = documentsToCommit.poll()) == null) {
-          return false;
-        }
+    CommitTask task;
+    synchronized (lock) {
+      if (!myEnabled || (task = documentsToCommit.poll()) == null) {
+        return false;
+      }
 
-        document = task.getDocument();
-        indicator = task.indicator;
-        project = task.project;
+      Document document = task.getDocument();
+      Project project = task.project;
 
-        if (project.isDisposed() || !((PsiDocumentManagerBase)PsiDocumentManager.getInstance(project)).isInUncommittedSet(document)) {
-          log(project, "Abandon and proceed to next", task);
-          return true;
-        }
+      if (project.isDisposed() || !((PsiDocumentManagerBase)PsiDocumentManager.getInstance(project)).isInUncommittedSet(document)) {
+        log(project, "Abandon and proceed to next", task);
+        return true;
+      }
 
-        if (indicator.isCanceled()) {
-          return true; // document has been marked as removed, e.g. by synchronous commit
-        }
+      if (task.isCanceled()) {
+        return true; // document has been marked as removed, e.g. by synchronous commit
+      }
 
-        startNewTask(task, "Pulled new task");
+      startNewTask(task, "Pulled new task");
 
-        // transfer to documentsToApplyInEDT
-        documentsToApplyInEDT.add(task);
-      }
+      documentsToApplyInEDT.add(task);
+    }
 
-      if (indicator.isCanceled()) {
-        success = false;
-      }
-      else {
+    boolean success = false;
+    Object failureReason = null;
+    try {
+      if (!task.isCanceled()) {
         final CommitTask commitTask = task;
         final Ref<Pair<Runnable, Object>> result = new Ref<>();
-        ProgressManager.getInstance().executeProcessUnderProgress(() -> result.set(commitUnderProgress(commitTask, false)), indicator);
+        ProgressManager.getInstance().executeProcessUnderProgress(() -> result.set(commitUnderProgress(commitTask, false)), task.indicator);
         final Runnable finishRunnable = result.get().first;
         success = finishRunnable != null;
         failureReason = result.get().second;
@@ -368,7 +292,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
         if (success) {
           assert !myApplication.isDispatchThread();
           TransactionGuardImpl guard = (TransactionGuardImpl)TransactionGuard.getInstance();
-          guard.submitTransaction(project, task.myCreationContext, finishRunnable);
+          guard.submitTransaction(task.project, task.myCreationContext, finishRunnable);
         }
       }
     }
@@ -382,22 +306,19 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
       failureReason = ExceptionUtil.getThrowableText(e);
     }
 
-    if (!success && task != null) {
-      final Project finalProject = project;
-      final Document finalDocument = document;
+    if (!success) {
+      Project project = task.project;
+      Document document = task.document;
       Object finalFailureReason = failureReason;
-      CommitTask finalTask = task;
       ReadAction.run(() -> {
-        if (finalProject.isDisposed()) return;
-        PsiDocumentManager documentManager = PsiDocumentManager.getInstance(finalProject);
-        if (documentManager.isCommitted(finalDocument)) return; // sync commit hasn't intervened
-        CharSequence lastCommittedText = documentManager.getLastCommittedText(finalDocument);
-        PsiFile file = documentManager.getPsiFile(finalDocument);
+        if (project.isDisposed()) return;
+        PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
+        if (documentManager.isCommitted(document)) return; // sync commit hasn't intervened
+        CharSequence lastCommittedText = documentManager.getLastCommittedText(document);
+        PsiFile file = documentManager.getPsiFile(document);
         List<Pair<PsiFileImpl, FileASTNode>> oldFileNodes = file == null ? null : getAllFileNodes(file);
         if (oldFileNodes != null) {
-          doQueue(finalProject, finalDocument, oldFileNodes, "re-added on failure: " + finalFailureReason,
-                  finalTask.myCreationContext,
-                  lastCommittedText);
+          doQueue(project, document, oldFileNodes, "re-added on failure: " + finalFailureReason, task.myCreationContext, lastCommittedText);
         }
       });
     }
@@ -436,7 +357,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
 
     documentLock.lock();
     try {
-      assert !task.indicator.isCanceled();
+      assert !task.isCanceled();
       Pair<Runnable, Object> result = commitUnderProgress(task, true);
       Runnable finish = result.first;
       log(project, "Committed sync", task, finish, task.indicator);
@@ -464,7 +385,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
   }
 
   @NotNull
-  protected ProgressIndicator createProgressIndicator() {
+  private static ProgressIndicator createProgressIndicator() {
     return new StandardProgressIndicatorBase();
   }
 
@@ -482,7 +403,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
   @NotNull
   private Pair<Runnable, Object> commitUnderProgress(@NotNull final CommitTask task, final boolean synchronously) {
     if (synchronously) {
-      assert !task.indicator.isCanceled();
+      assert !task.isCanceled();
     }
 
     final Document document = task.getDocument();
@@ -520,10 +441,12 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
           PsiFileImpl file = pair.first;
           if (file.isValid()) {
             FileASTNode oldFileNode = pair.second;
-            ProperTextRange changedPsiRange = getChangedPsiRange(file, task, document.getImmutableCharSequence());
+            ProperTextRange changedPsiRange = ChangedPsiRangeUtil
+              .getChangedPsiRange(file, task.document, task.myLastCommittedText, document.getImmutableCharSequence()
+            );
             if (changedPsiRange != null) {
               BooleanRunnable finishProcessor = doCommit(task, file, oldFileNode, changedPsiRange, reparseInjectedProcessors);
-              ContainerUtil.addIfNotNull(finishProcessors, finishProcessor);
+              finishProcessors.add(finishProcessor);
               changedRange.set(changedRange.get() == null ? changedPsiRange : changedRange.get().union(changedPsiRange));
             }
           }
@@ -549,7 +472,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
       return new Pair<>(null, "Could not start read action");
     }
 
-    boolean canceled = task.indicator.isCanceled();
+    boolean canceled = task.isCanceled();
     assert !synchronously || !canceled;
     if (canceled) {
       return new Pair<>(null, "Indicator was canceled");
@@ -629,7 +552,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
   }
 
   @TestOnly
-  public void waitForAllCommits() throws ExecutionException, InterruptedException, TimeoutException {
+  void waitForAllCommits() throws ExecutionException, InterruptedException, TimeoutException {
     ApplicationManager.getApplication().assertIsDispatchThread();
     assert !ApplicationManager.getApplication().isWriteAccessAllowed();
 
@@ -674,7 +597,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
     public String toString() {
       Document document = getDocument();
       String docInfo = document + " (\"" + StringUtil.first(document.getImmutableCharSequence(), 40, true).toString().replaceAll("\n", " ") + "\")";
-      String indicatorInfo = indicator.isCanceled() ? " (Canceled: " + ((UserDataHolder)indicator).getUserData(CANCEL_REASON) + ")" : "";
+      String indicatorInfo = isCanceled() ? " (Canceled: " + ((UserDataHolder)indicator).getUserData(CANCEL_REASON) + ")" : "";
       String reasonInfo = " Reason: " + reason + (isStillValid() ? ""
                                                                  : "; changed: old seq=" + modificationSequence + ", new seq=" +
                                                                     ((DocumentEx)document).getModificationSequence());
@@ -704,7 +627,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
     }
 
     private void cancel(@NotNull Object reason, @NotNull DocumentCommitThread commitProcessor) {
-      if (!indicator.isCanceled()) {
+      if (!isCanceled()) {
         commitProcessor.log(project, "indicator cancel", this);
 
         indicator.cancel();
@@ -721,15 +644,19 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
     Document getDocument() {
       return document;
     }
+
+    private boolean isCanceled() {
+      return indicator.isCanceled();
+    }
   }
 
   // returns runnable to execute under write action in AWT to finish the commit, updates "outChangedRange"
-  @Nullable
-  public BooleanRunnable doCommit(@NotNull final CommitTask task,
-                                  @NotNull final PsiFile file,
-                                  @NotNull final FileASTNode oldFileNode,
-                                  @NotNull ProperTextRange changedPsiRange,
-                                  @NotNull List<BooleanRunnable> outReparseInjectedProcessors) {
+  @NotNull
+  private static BooleanRunnable doCommit(@NotNull final CommitTask task,
+                                          @NotNull final PsiFile file,
+                                          @NotNull final FileASTNode oldFileNode,
+                                          @NotNull ProperTextRange changedPsiRange,
+                                          @NotNull List<BooleanRunnable> outReparseInjectedProcessors) {
     Document document = task.getDocument();
     final CharSequence newDocumentText = document.getImmutableCharSequence();
 
@@ -739,7 +666,6 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
       file.putUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY, data);
     }
 
-    BlockSupportImpl blockSupport = (BlockSupportImpl)BlockSupport.getInstance(file.getProject());
     Trinity<DiffLog, ASTNode, ASTNode> result =
       BlockSupportImpl.reparse(file, oldFileNode, changedPsiRange, newDocumentText, task.indicator, task.myLastCommittedText);
     DiffLog diffLog = result.getFirst();
@@ -773,7 +699,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
                   "; free-threaded=" + AbstractFileViewProvider.isFreeThreaded(viewProvider));
       }
 
-      doActualPsiChange(file, diffLog);
+      diffLog.doActualPsiChange(file);
 
       assertAfterCommit(document1, file, (FileElement)oldFileNode);
 
@@ -781,124 +707,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
     };
   }
 
-  private static int getLeafMatchingLength(CharSequence leafText, CharSequence pattern, int patternIndex, int finalPatternIndex, int direction) {
-    int leafIndex = direction == 1 ? 0 : leafText.length() - 1;
-    int finalLeafIndex = direction == 1 ? leafText.length() - 1 : 0;
-    int result = 0;
-    while (leafText.charAt(leafIndex) == pattern.charAt(patternIndex)) {
-      result++;
-      if (leafIndex == finalLeafIndex || patternIndex == finalPatternIndex) {
-        break;
-      }
-      leafIndex += direction;
-      patternIndex += direction;
-    }
-    return result;
-  }
-
-  private static int getMatchingLength(@NotNull FileElement treeElement, @NotNull CharSequence text, boolean fromStart) {
-    int patternIndex = fromStart ? 0 : text.length() - 1;
-    int finalPatternIndex = fromStart ? text.length() - 1 : 0;
-    int direction = fromStart ? 1 : -1;
-    ASTNode leaf = fromStart ? TreeUtil.findFirstLeaf(treeElement, false) : TreeUtil.findLastLeaf(treeElement, false);
-    int result = 0;
-    while (leaf != null && (fromStart ? patternIndex <= finalPatternIndex : patternIndex >= finalPatternIndex)) {
-      if (!(leaf instanceof ForeignLeafPsiElement)) {
-        CharSequence chars = leaf.getChars();
-        if (chars.length() > 0) {
-          int matchingLength = getLeafMatchingLength(chars, text, patternIndex, finalPatternIndex, direction);
-          result += matchingLength;
-          if (matchingLength != chars.length()) {
-            break;
-          }
-          patternIndex += fromStart ? matchingLength : -matchingLength;
-        }
-      }
-      leaf = fromStart ? TreeUtil.nextLeaf(leaf, false) : TreeUtil.prevLeaf(leaf, false);
-    }
-    return result;
-  }
-
-  @Nullable
-  public static TextRange getChangedPsiRange(@NotNull PsiFile file, @NotNull FileElement treeElement, @NotNull CharSequence newDocumentText) {
-    int psiLength = treeElement.getTextLength();
-    if (!file.getViewProvider().supportsIncrementalReparse(file.getLanguage())) {
-      return new TextRange(0, psiLength);
-    }
-
-    int commonPrefixLength = getMatchingLength(treeElement, newDocumentText, true);
-    if (commonPrefixLength == newDocumentText.length() && newDocumentText.length() == psiLength) {
-      return null;
-    }
-
-    int commonSuffixLength = Math.min(getMatchingLength(treeElement, newDocumentText, false), psiLength - commonPrefixLength);
-    return new TextRange(commonPrefixLength, psiLength - commonSuffixLength);
-  }
-
-  @Nullable
-  private static ProperTextRange getChangedPsiRange(@NotNull PsiFile file,
-                                                    @NotNull CommitTask task,
-                                                    @NotNull CharSequence newDocumentText) {
-    CharSequence oldDocumentText = task.myLastCommittedText;
-    int psiLength = oldDocumentText.length();
-    if (!file.getViewProvider().supportsIncrementalReparse(file.getLanguage())) {
-      return new ProperTextRange(0, psiLength);
-    }
-    List<DocumentEvent> events = ((PsiDocumentManagerBase)PsiDocumentManager.getInstance(file.getProject())).getEventsSinceCommit(task.document);
-    int prefix = Integer.MAX_VALUE;
-    int suffix = Integer.MAX_VALUE;
-    int lengthBeforeEvent = psiLength;
-    for (DocumentEvent event : events) {
-      prefix = Math.min(prefix, event.getOffset());
-      suffix = Math.min(suffix, lengthBeforeEvent - event.getOffset() - event.getOldLength());
-      lengthBeforeEvent = lengthBeforeEvent - event.getOldLength() + event.getNewLength();
-    }
-    if ((prefix == psiLength || suffix == psiLength) && newDocumentText.length() == psiLength) {
-      return null;
-    }
-    //Important! delete+insert sequence can give some of same chars back, lets grow affixes to include them.
-    int shortestLength = Math.min(psiLength, newDocumentText.length());
-    while (prefix < shortestLength &&
-           oldDocumentText.charAt(prefix) == newDocumentText.charAt(prefix)) {
-      prefix++;
-    }
-    while (suffix < shortestLength - prefix &&
-           oldDocumentText.charAt(psiLength - suffix - 1) == newDocumentText.charAt(newDocumentText.length() - suffix - 1)) {
-      suffix++;
-    }
-    int end = Math.max(prefix, psiLength - suffix);
-    if (end == prefix && newDocumentText.length() == oldDocumentText.length()) return null;
-    return ProperTextRange.create(prefix, end);
-  }
-
-  public static void doActualPsiChange(@NotNull PsiFile file, @NotNull DiffLog diffLog) {
-    CodeStyleManager.getInstance(file.getProject()).performActionWithFormatterDisabled((Runnable)() -> {
-      FileViewProvider viewProvider = file.getViewProvider();
-      synchronized (((AbstractFileViewProvider)viewProvider).getFilePsiLock()) {
-        viewProvider.beforeContentsSynchronized();
-
-        final Document document = viewProvider.getDocument();
-        PsiDocumentManagerBase documentManager = (PsiDocumentManagerBase)PsiDocumentManager.getInstance(file.getProject());
-        PsiToDocumentSynchronizer.DocumentChangeTransaction transaction = documentManager.getSynchronizer().getTransaction(document);
-
-        if (transaction == null) {
-          final PomModel model = PomManager.getModel(file.getProject());
-
-          model.runTransaction(new PomTransactionBase(file, model.getModelAspect(TreeAspect.class)) {
-            @Override
-            public PomModelEvent runInner() {
-              return new TreeAspectEvent(model, diffLog.performActualPsiChange(file));
-            }
-          });
-        }
-        else {
-          diffLog.performActualPsiChange(file);
-        }
-      }
-    });
-  }
-
-  private void assertAfterCommit(@NotNull Document document, @NotNull final PsiFile file, @NotNull FileElement oldFileNode) {
+  private static void assertAfterCommit(@NotNull Document document, @NotNull final PsiFile file, @NotNull FileElement oldFileNode) {
     if (oldFileNode.getTextLength() != document.getTextLength()) {
       final String documentText = document.getText();
       String fileText = file.getText();
@@ -916,7 +725,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
         BlockSupport blockSupport = BlockSupport.getInstance(file.getProject());
         final DiffLog diffLog = blockSupport.reparseRange(file, file.getNode(), new TextRange(0, documentText.length()), documentText, createProgressIndicator(),
                                                           oldFileNode.getText());
-        doActualPsiChange(file, diffLog);
+        diffLog.doActualPsiChange(file);
 
         if (oldFileNode.getTextLength() != document.getTextLength()) {
           LOG.error("PSI is broken beyond repair in: " + file);
index 4e520e1c1a0252814cafef53838b0391b2266175..aa30c985e04cc5e7509a1d8175a0a535d7a25dce 100644 (file)
@@ -1011,7 +1011,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
         ProgressIndicator indicator = ProgressIndicatorProvider.getGlobalProgressIndicator();
         if (indicator == null) indicator = new EmptyProgressIndicator();
         DiffLog log = BlockSupportImpl.makeFullParse(file, node, text, indicator, text).getFirst();
-        DocumentCommitThread.doActualPsiChange(file, log);
+        log.doActualPsiChange(file);
         file.getViewProvider().contentsSynchronized();
       });
     }
index 008a846cef2c2eeb396e1c81b9032a909a1a0bf3..9f2cd98cca46f2d36f59a7ebd502a52be7465441 100644 (file)
@@ -1,18 +1,4 @@
-/*
- * Copyright 2000-2016 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.
- */
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.psi.impl.file;
 
 import com.intellij.ide.util.PsiNavigationSupport;
@@ -191,6 +177,10 @@ public class PsiDirectoryImpl extends PsiElementBase implements PsiDirectory, Qu
 
     for (VirtualFile vFile : myFile.getChildren()) {
       ProgressManager.checkCanceled();
+      if (!vFile.isValid()) {
+        LOG.warn("got invalid child file: " + vFile);
+        continue;
+      }
       boolean isDir = vFile.isDirectory();
       if (processor instanceof PsiFileSystemItemProcessor && !((PsiFileSystemItemProcessor)processor).acceptItem(vFile.getName(), isDir)) {
         continue;
index 53eebbf218b219d7e760b2b065e944c8a3059083..efaf1a310ba50c1cd9e47b43378f8f07608fa4f0 100644 (file)
 package com.intellij.psi.impl.source.text;
 
 import com.intellij.lang.ASTNode;
+import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.progress.ProgressIndicatorProvider;
 import com.intellij.pom.PomManager;
+import com.intellij.pom.PomModel;
+import com.intellij.pom.event.PomModelEvent;
+import com.intellij.pom.impl.PomTransactionBase;
 import com.intellij.pom.tree.TreeAspect;
+import com.intellij.pom.tree.TreeAspectEvent;
 import com.intellij.pom.tree.events.impl.TreeChangeEventImpl;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.impl.DebugUtil;
-import com.intellij.psi.impl.PsiManagerEx;
-import com.intellij.psi.impl.PsiManagerImpl;
-import com.intellij.psi.impl.PsiTreeChangeEventImpl;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.CodeStyleManager;
+import com.intellij.psi.impl.*;
 import com.intellij.psi.impl.source.PsiFileImpl;
 import com.intellij.psi.impl.source.tree.CompositeElement;
 import com.intellij.psi.impl.source.tree.FileElement;
@@ -263,4 +265,31 @@ public class DiffLog implements DiffTreeChangeBuilder<ASTNode,ASTNode> {
       myOldRoot.replaceAllChildrenToChildrenOf(myNewRoot);
     }
   }
+
+  public void doActualPsiChange(@NotNull PsiFile file) {
+    CodeStyleManager.getInstance(file.getProject()).performActionWithFormatterDisabled((Runnable)() -> {
+      FileViewProvider viewProvider = file.getViewProvider();
+      synchronized (((AbstractFileViewProvider)viewProvider).getFilePsiLock()) {
+        viewProvider.beforeContentsSynchronized();
+
+        final Document document = viewProvider.getDocument();
+        PsiDocumentManagerBase documentManager = (PsiDocumentManagerBase)PsiDocumentManager.getInstance(file.getProject());
+        PsiToDocumentSynchronizer.DocumentChangeTransaction transaction = documentManager.getSynchronizer().getTransaction(document);
+
+        if (transaction == null) {
+          final PomModel model = PomManager.getModel(file.getProject());
+
+          model.runTransaction(new PomTransactionBase(file, model.getModelAspect(TreeAspect.class)) {
+            @Override
+            public PomModelEvent runInner() {
+              return new TreeAspectEvent(model, performActualPsiChange(file));
+            }
+          });
+        }
+        else {
+          performActualPsiChange(file);
+        }
+      }
+    });
+  }
 }
index a8ac645c0d5962581e80498a751b36c15f04a982..77f98a887f54f5243b068ac9a100de6efb870389 100644 (file)
@@ -32,9 +32,9 @@ import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.ref.DebugReflectionUtil;
 import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
 
 import java.util.Collections;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -52,12 +52,13 @@ class CachedValueLeakChecker {
     if (!ourCheckedKeys.add(key.toString())) return; // store strings because keys are created afresh in each (test) project
 
     if (!SystemInfo.IS_AT_LEAST_JAVA9) {
-      findReferencedPsi(provider, userDataHolder, 5);
+      findReferencedPsi(provider, key, userDataHolder, 5);
     }
   }
 
   private static synchronized void findReferencedPsi(@NotNull final Object root,
-                                                     @Nullable final UserDataHolder toIgnore,
+                                                     @NotNull Key key,
+                                                     @NotNull final UserDataHolder toIgnore,
                                                      int depth) {
     Condition<Object> shouldExamineValue = value -> {
       if (value == toIgnore) return false;
@@ -75,7 +76,8 @@ class CachedValueLeakChecker {
       }
       return true;
     };
-    DebugReflectionUtil.walkObjects(depth, Collections.singletonList(root), PsiElement.class, shouldExamineValue, (value, backLink) -> {
+    Map<Object, String> roots = Collections.singletonMap(root, "CachedValueProvider "+key);
+    DebugReflectionUtil.walkObjects(depth, roots, PsiElement.class, shouldExamineValue, (value, backLink) -> {
       if (value instanceof PsiElement) {
         LOG.error(
           "Incorrect CachedValue use. Provider references PSI, causing memory leaks and possible invalid element access, provider=" +
index a9f7536f55c5f1b0d401de1de0dd2cd0e8e60cb2..0c23aa4c7cda724868bb763464bb84599daeeee2 100644 (file)
@@ -23,8 +23,8 @@ import com.intellij.openapi.externalSystem.view.ExternalProjectsViewImpl;
 import com.intellij.openapi.externalSystem.view.ExternalProjectsViewState;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.ExternalStorageConfigurationManager;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.project.ProjectFileStoreOptionManager;
 import com.intellij.openapi.roots.ModuleRootManager;
 import com.intellij.openapi.roots.impl.ModuleRootManagerImpl;
 import com.intellij.openapi.util.Disposer;
@@ -48,7 +48,7 @@ import static com.intellij.openapi.externalSystem.model.ProjectKeys.TASK;
  * @since 10/23/2014
  */
 @State(name = "ExternalProjectsManager", storages = @Storage(StoragePathMacros.WORKSPACE_FILE))
-public class ExternalProjectsManagerImpl implements ExternalProjectsManager, PersistentStateComponent<ExternalProjectsState>, Disposable, ProjectFileStoreOptionManager {
+public class ExternalProjectsManagerImpl implements ExternalProjectsManager, PersistentStateComponent<ExternalProjectsState>, Disposable {
   private static final Logger LOG = Logger.getInstance(ExternalProjectsManager.class);
 
   private final AtomicBoolean isInitializationFinished = new AtomicBoolean();
@@ -79,13 +79,16 @@ public class ExternalProjectsManagerImpl implements ExternalProjectsManager, Per
     return (ExternalProjectsManagerImpl)service;
   }
 
-  @Override
-  public boolean isStoredExternally() {
-    return myState.storeExternally;
+  @Nullable
+  public static Project setupCreatedProject(@Nullable Project project) {
+    if (project != null) {
+      getInstance(project).setStoreExternally(true);
+    }
+    return project;
   }
 
   public void setStoreExternally(boolean value) {
-    myState.storeExternally = value;
+    ExternalStorageConfigurationManager.getInstance(myProject).setEnabled(value);
     // force re-save
     try {
       for (Module module : ModuleManager.getInstance(myProject).getModules()) {
@@ -285,6 +288,11 @@ public class ExternalProjectsManagerImpl implements ExternalProjectsManager, Per
   @Override
   public void loadState(@NotNull ExternalProjectsState state) {
     myState = state;
+    // migrate to new
+    if (myState.storeExternally) {
+      myState.storeExternally = false;
+      ExternalStorageConfigurationManager.getInstance(myProject).setEnabled(true);
+    }
   }
 
   @Override
index 2ddcf7c7c1c130a2245cf1b044e06c7d9017f2bd..4c540fc312cfa44b056cb925698b99b5b134773d 100644 (file)
@@ -2,12 +2,8 @@
 package com.intellij.openapi.externalSystem.service.project.manage;
 
 import com.intellij.openapi.externalSystem.view.ExternalProjectsViewState;
-import com.intellij.openapi.project.ProjectUtilCore;
 import com.intellij.util.containers.FactoryMap;
-import com.intellij.util.xmlb.annotations.Attribute;
-import com.intellij.util.xmlb.annotations.MapAnnotation;
-import com.intellij.util.xmlb.annotations.Property;
-import com.intellij.util.xmlb.annotations.Tag;
+import com.intellij.util.xmlb.annotations.*;
 
 import java.util.LinkedHashMap;
 import java.util.Map;
@@ -20,8 +16,7 @@ public class ExternalProjectsState {
   private final Map<String, State> myExternalSystemsState = FactoryMap.create(key -> new State());
 
   @Property(surroundWithTag = false)
-  @MapAnnotation(surroundWithTag = false, surroundValueWithTag = false, surroundKeyWithTag = false,
-    keyAttributeName = "id", entryTagName = "system")
+  @XMap(keyAttributeName = "id", entryTagName = "system")
   public Map<String, State> getExternalSystemsState() {
     return myExternalSystemsState;
   }
@@ -31,7 +26,7 @@ public class ExternalProjectsState {
   }
 
   @Attribute
-  public boolean storeExternally = ProjectUtilCore.isUseExternalStorage();
+  public boolean storeExternally = false;
 
   @Tag("state")
   public static class State {
index 4d0cbd53abf219c0ab21cb5f2deba846dd92348d..3bbead973c3472f590a77f37fba27911421f29af 100644 (file)
@@ -1,22 +1,7 @@
-/*
- * Copyright 2000-2013 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.openapi.externalSystem.service.project.wizard;
 
 import com.intellij.ide.util.projectWizard.ModuleBuilder;
-import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
 import com.intellij.openapi.externalSystem.model.ProjectSystemId;
 import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
@@ -33,9 +18,6 @@ import javax.swing.*;
  * @since 6/26/13 10:39 AM
  */
 public abstract class AbstractExternalModuleBuilder<S extends ExternalProjectSettings> extends ModuleBuilder {
-
-  private static final Logger LOG = Logger.getInstance(AbstractExternalModuleBuilder.class);
-
   @NotNull private final Icon myIcon;
   @NotNull private final ProjectSystemId myExternalSystemId;
   @NotNull private final S myExternalProjectSettings;
index 950c2a4863bee3227f6c04860691f365ccd6afc4..abff2b50313a1bc37f9b721a9f7506303f0237c2 100644 (file)
@@ -51,6 +51,7 @@ public class CodeStyle {
    */
   @NotNull
   public static CodeStyleSettings getSettings(@NotNull Project project) {
+    //noinspection deprecation
     return CodeStyleSettingsManager.getInstance(project).getCurrentSettings();
   }
 
@@ -64,6 +65,7 @@ public class CodeStyle {
   public static CodeStyleSettings getSettings(@NotNull PsiFile file) {
     if (file.isValid()) {
       Project project = file.getProject();
+      //noinspection deprecation
       return CodeStyleSettingsManager.getInstance(project).getCurrentSettings();
     }
     return getDefaultSettings();
index 27f24f9d15cc0effea1ea2683a39dcca23009f5b..8c9ecdef09e754c79f197082f7f0639319b22aa1 100644 (file)
@@ -79,7 +79,7 @@ public abstract class SettingsConnectionService {
           }
         }
         catch (JDOMException e) {
-          LOG.error(e);
+          LOG.info(e);
         }
         return settings;
       }, Collections.<String, String>emptyMap(), LOG);
@@ -93,7 +93,7 @@ public abstract class SettingsConnectionService {
 
   @Nullable
   protected String getSettingValue(@NotNull String attributeValue) {
-    if (myAttributesMap == null) {
+    if (myAttributesMap == null || myAttributesMap.isEmpty()) {
       myAttributesMap = readSettings(getAttributeNames());
     }
     return myAttributesMap != null ? myAttributesMap.get(attributeValue) : null;
index 74611cd75135a381208638a3fc0caf7f1d1c2677..5747b47921a343c0e1d45abec360a685200eee7d 100644 (file)
@@ -36,6 +36,7 @@ public final class AttributesDescriptor extends AbstractKeyDescriptor<TextAttrib
     super(displayName, key);
   }
 
+  @SuppressWarnings("RedundantMethodOverride") // binary compatibility
   @NotNull
   @Override
   public TextAttributesKey getKey() {
index ed17a37a9709a7172846a10992840fe2d00edf6d..18d3a38c185aeab0352690984b87f4d3b024e932 100644 (file)
@@ -55,6 +55,7 @@ public final class ColorDescriptor extends AbstractKeyDescriptor<ColorKey> {
     return myKind;
   }
 
+  @SuppressWarnings("RedundantMethodOverride") // binary compatibility
   @NotNull
   @Override
   public ColorKey getKey() {
index 0041236d818b2c0e07103854b9d352b068205e85..f0e605e89ac3bdf10e444213e282e2447f269362 100644 (file)
@@ -49,7 +49,11 @@ public class CodeStyleSettingsManager implements PersistentStateComponent<Elemen
   public volatile String PREFERRED_PROJECT_CODE_STYLE;
   private volatile CodeStyleSettings myTemporarySettings;
 
+  /**
+   * @deprecated see comments for {@link #getSettings(Project)}
+   */
   @SuppressWarnings("deprecation")
+  @Deprecated
   public static CodeStyleSettingsManager getInstance(@Nullable Project project) {
     if (project == null || project.isDefault()) return getInstance();
     ProjectCodeStyleSettingsManager projectSettingsManager = ServiceManager.getService(project, ProjectCodeStyleSettingsManager.class);
index d108a12541f53aaa26f6b384cc548cdbb336c410..293547a623d049579d193129b3136194d5542932 100644 (file)
@@ -1,18 +1,4 @@
-/*
- * Copyright 2000-2017 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.
- */
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 
 package com.intellij.psi.codeStyle;
 
@@ -194,8 +180,7 @@ public class ProjectCodeStyleSettingsManager extends CodeStyleSettingsManager {
     return "PER_PROJECT_SETTINGS".equals(fieldName);
   }
 
-  public static final class StateSplitter extends MainConfigurationStateSplitter {
-
+  static final class StateSplitter extends MainConfigurationStateSplitter {
     @NotNull
     @Override
     protected String getComponentStateFileName() {
index 7f555e0dac0461f3815f95d24eed67b7738e4aa3..ba715020a2021d62cc336e169aa630436fb07271 100644 (file)
@@ -59,6 +59,7 @@ import java.util.Set;
  */
 
 public abstract class TabbedLanguageCodeStylePanel extends CodeStyleAbstractPanel {
+  @SuppressWarnings("unused")
   private static final Logger LOG = Logger.getInstance(TabbedLanguageCodeStylePanel.class);
 
   private CodeStyleAbstractPanel myActiveTab;
@@ -355,16 +356,14 @@ public abstract class TabbedLanguageCodeStylePanel extends CodeStyleAbstractPane
         result.add(codeStyle);
       }
     }
-    return result.toArray(new PredefinedCodeStyle[0]);
+    return result.toArray(PredefinedCodeStyle.EMPTY_ARRAY);
   }
 
 
   private void applyLanguageSettings(Language lang) {
     final Project currProject = ProjectUtil.guessCurrentProject(getPanel());
-    CodeStyleSettings rootSettings = CodeStyleSettingsManager.getSettings(currProject);
+    CodeStyleSettings rootSettings = CodeStyle.getSettings(currProject);
     CodeStyleSettings targetSettings = getSettings();
-    if (rootSettings.getCommonSettings(lang) == null || targetSettings.getCommonSettings(getDefaultLanguage()) == null) 
-      return;
 
     applyLanguageSettings(lang, rootSettings, targetSettings);
     reset(targetSettings);
index 58efe8555b271a7f8098ac4e630d35268593bec1..238b7766646dc61b43e6e151184936e8afeaf426 100644 (file)
@@ -69,6 +69,7 @@ import org.jetbrains.annotations.Nullable;
 import org.jetbrains.annotations.TestOnly;
 
 import java.util.List;
+import java.util.Objects;
 
 @SuppressWarnings("deprecation")
 public class CodeCompletionHandlerBase {
@@ -152,11 +153,6 @@ public class CodeCompletionHandlerBase {
 
     CompletionPhase phase = CompletionServiceImpl.getCompletionPhase();
     boolean repeated = phase.indicator != null && phase.indicator.isRepeatedInvocation(completionType, editor);
-    /*
-    if (repeated && isAutocompleteCommonPrefixOnInvocation() && phase.fillInCommonPrefix()) {
-      return;
-    }
-    */
 
     final int newTime = phase.newCompletionStarted(time, repeated);
     if (invokedExplicitly) {
@@ -288,7 +284,7 @@ public class CodeCompletionHandlerBase {
     final Editor editor = initContext.getEditor();
     CompletionAssertions.checkEditorValid(editor);
 
-    CompletionContext context = createCompletionContext(initContext.getFile(), hostCopyOffsets);
+    OffsetsInFile finalOffsets = toInjectedIfAny(initContext.getFile(), hostCopyOffsets);
     LookupImpl lookup = obtainLookup(editor, initContext.getProject());
 
     CompletionPhase phase = CompletionServiceImpl.getCompletionPhase();
@@ -301,16 +297,19 @@ public class CodeCompletionHandlerBase {
       CompletionServiceImpl.assertPhase(CompletionPhase.NoCompletion.getClass());
     }
 
+    CompletionThreadingBase threading = ApplicationManager.getApplication().isWriteAccessAllowed() ? new SyncCompletion() : new AsyncCompletion();
     CompletionProgressIndicator indicator = new CompletionProgressIndicator(editor, initContext.getCaret(),
-                                                                            invocationCount, context, this,
-                                                                            initContext.getOffsetMap(), hostOffsets, hasModifiers, lookup);
+                                                                            invocationCount, this,
+                                                                            initContext.getOffsetMap(), hostOffsets, hasModifiers, lookup,
+                                                                            threading);
     Disposer.register(indicator, hostCopyOffsets.getOffsets());
-    Disposer.register(indicator, context.getOffsetMap());
+    Disposer.register(indicator, finalOffsets.getOffsets());
     Disposer.register(indicator, translator);
 
     CompletionServiceImpl.setCompletionPhase(synchronous ? new CompletionPhase.Synchronous(indicator) : new CompletionPhase.BgCalculation(indicator));
-
-    indicator.startCompletion(initContext);
+    
+    threading.startThread(indicator, () -> AsyncCompletion.tryReadOrCancel(indicator, () -> 
+      indicator.runContributors(initContext, finalOffsets)));
 
     if (!synchronous) {
       return;
@@ -342,11 +341,12 @@ public class CodeCompletionHandlerBase {
     }
   }
 
-  private AutoCompletionDecision shouldAutoComplete(final CompletionProgressIndicator indicator, List<LookupElement> items) {
+  private AutoCompletionDecision shouldAutoComplete(CompletionProgressIndicator indicator,
+                                                    List<LookupElement> items, 
+                                                    CompletionParameters parameters) {
     if (!invokedExplicitly) {
       return AutoCompletionDecision.SHOW_LOOKUP;
     }
-    final CompletionParameters parameters = indicator.getParameters();
     final LookupElement item = items.get(0);
     if (items.size() == 1) {
       final AutoCompletionPolicy policy = getAutocompletionPolicy(item);
@@ -386,12 +386,13 @@ public class CodeCompletionHandlerBase {
 
   protected void completionFinished(final CompletionProgressIndicator indicator, boolean hasModifiers) {
     final List<LookupElement> items = indicator.getLookup().getItems();
+    CompletionParameters parameters = Objects.requireNonNull(indicator.getParameters());
     if (items.isEmpty()) {
       LookupManager.getInstance(indicator.getProject()).hideActiveLookup();
 
       Caret nextCaret = getNextCaretToProcess(indicator.getEditor());
       if (nextCaret != null) {
-        invokeCompletion(indicator.getProject(), indicator.getEditor(), indicator.getParameters().getInvocationCount(), hasModifiers, false, nextCaret);
+        invokeCompletion(indicator.getProject(), indicator.getEditor(), parameters.getInvocationCount(), hasModifiers, false, nextCaret);
       }
       else {
         indicator.handleEmptyLookup(true);
@@ -404,7 +405,7 @@ public class CodeCompletionHandlerBase {
     LOG.assertTrue(!indicator.isCanceled(), "canceled");
 
     try {
-      final AutoCompletionDecision decision = shouldAutoComplete(indicator, items);
+      AutoCompletionDecision decision = shouldAutoComplete(indicator, items, parameters);
       if (decision == AutoCompletionDecision.SHOW_LOOKUP) {
         CompletionServiceImpl.setCompletionPhase(new CompletionPhase.ItemsCalculated(indicator));
         indicator.getLookup().setCalculating(false);
@@ -497,11 +498,10 @@ public class CodeCompletionHandlerBase {
            !CompletionAssertions.isEditorValid(initContext.getEditor());
   }
 
-  private static CompletionContext createCompletionContext(PsiFile originalFile, OffsetsInFile hostCopyOffsets) {
+  private static OffsetsInFile toInjectedIfAny(PsiFile originalFile, OffsetsInFile hostCopyOffsets) {
     CompletionAssertions.assertHostInfo(hostCopyOffsets.getFile(), hostCopyOffsets.getOffsets());
 
     int hostStartOffset = hostCopyOffsets.getOffsets().getOffset(CompletionInitializationContext.START_OFFSET);
-    OffsetsInFile result = hostCopyOffsets;
     OffsetsInFile translatedOffsets = hostCopyOffsets.toInjectedIfAny(hostStartOffset);
     if (translatedOffsets != hostCopyOffsets) {
       PsiFile injected = translatedOffsets.getFile();
@@ -512,11 +512,11 @@ public class CodeCompletionHandlerBase {
       CompletionAssertions.assertInjectedOffsets(hostStartOffset, injected, documentWindow);
 
       if (injected.getTextRange().contains(translatedOffsets.getOffsets().getOffset(CompletionInitializationContext.START_OFFSET))) {
-        result = translatedOffsets;
+        return translatedOffsets;
       }
     }
 
-    return new CompletionContext(result.getFile(), result.getOffsets());
+    return hostCopyOffsets;
   }
 
   protected void lookupItemSelected(final CompletionProgressIndicator indicator, @NotNull final LookupElement item, final char completionChar,
@@ -583,7 +583,7 @@ public class CodeCompletionHandlerBase {
       });
       context = lastContext.get();
     } else {
-      context = insertItem(indicator, item, completionChar, items, update, editor, indicator.getParameters().getOriginalFile(), caretOffset,
+      context = insertItem(indicator, item, completionChar, items, update, editor, PsiUtilBase.getPsiFileInEditor(editor, indicator.getProject()), caretOffset,
                            idEndOffset, indicator.getOffsetMap());
     }
     if (context.shouldAddCompletionChar()) {
@@ -672,7 +672,7 @@ public class CodeCompletionHandlerBase {
       Language language = PsiUtilBase.getLanguageInEditor(editor, indicator.getProject());
       if (language != null) {
         for (SmartEnterProcessor processor : SmartEnterProcessors.INSTANCE.allForLanguage(language)) {
-          if (processor.processAfterCompletion(editor, indicator.getParameters().getOriginalFile())) break;
+          if (processor.processAfterCompletion(editor, context.getFile())) break;
         }
       }
     }
@@ -787,6 +787,7 @@ public class CodeCompletionHandlerBase {
     return null;
   }
 
+  @SuppressWarnings("unused") // for Rider
   @TestOnly
   public static void setAutoInsertTimeout(int timeout) {
     ourAutoInsertItemTimeout = timeout;
index 1079e8c201792af04e0c33f2e9783c3e81100365..1221ecd2638925f1e2170992bd8eaa0bba6d44d1 100644 (file)
@@ -37,6 +37,7 @@ import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiFile;
 import com.intellij.psi.impl.DebugUtil;
 import com.intellij.psi.util.PsiUtilCore;
+import org.jetbrains.annotations.Contract;
 
 import java.util.List;
 
@@ -124,14 +125,15 @@ class CompletionAssertions {
     }
   }
 
-  static void assertCompletionPositionPsiConsistent(CompletionContext newContext,
+  @Contract("_,_,_,null->fail")
+  static void assertCompletionPositionPsiConsistent(OffsetsInFile offsets,
                                                     int offset,
-                                                    PsiFile fileCopy,
                                                     PsiFile originalFile, PsiElement insertedElement) {
+    PsiFile fileCopy = offsets.getFile();
     if (insertedElement == null) {
       throw new LogEventException("No element at insertion offset",
                                                                    "offset=" +
-                                                                   newContext.getStartOffset() +
+                                                                   offset +
                                                                    "\n" +
                                                                    DebugUtil.currentStackTrace(),
                                                                    createFileTextAttachment(fileCopy, originalFile),
index 3b7ee7fe7d76c095b341555dcf0cc632ca5b7c2c..6bcb24cfd52d6951bf087fb49c56d144ea64b04b 100644 (file)
@@ -60,8 +60,7 @@ public class CompletionLookupArranger extends LookupArranger {
   private final int myLimit = Registry.intValue("ide.completion.variant.limit");
   private boolean myOverflow;
 
-  private final CompletionLocation myLocation;
-  private final CompletionParameters myParameters;
+  @Nullable private CompletionLocation myLocation;
   private final CompletionProgressIndicator myProcess;
   @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"})
   private final Map<CompletionSorterImpl, Classifier<LookupElement>> myClassifiers = new LinkedHashMap<>();
@@ -69,10 +68,8 @@ public class CompletionLookupArranger extends LookupArranger {
   private final CompletionFinalSorter myFinalSorter = CompletionFinalSorter.newSorter();
   private int myPrefixChanges;
 
-  public CompletionLookupArranger(final CompletionParameters parameters, CompletionProgressIndicator process) {
-    myParameters = parameters;
+  CompletionLookupArranger(CompletionProgressIndicator process) {
     myProcess = process;
-    myLocation = new CompletionLocation(parameters);
   }
 
   private MultiMap<CompletionSorterImpl, LookupElement> groupItemsBySorter(Iterable<LookupElement> source) {
@@ -350,7 +347,7 @@ public class CompletionLookupArranger extends LookupArranger {
     }
     //noinspection unchecked
     Iterable<LookupElement> result = ContainerUtil.concat(byClassifier.toArray(new Iterable[0]));
-    return myFinalSorter.sort(result, myParameters);
+    return myFinalSorter.sort(result, Objects.requireNonNull(myProcess.getParameters()));
   }
   
   private ProcessingContext createContext() {
@@ -363,7 +360,7 @@ public class CompletionLookupArranger extends LookupArranger {
 
   @Override
   public LookupArranger createEmptyCopy() {
-    return new CompletionLookupArranger(myParameters, myProcess);
+    return new CompletionLookupArranger(myProcess);
   }
 
   private int getItemToSelect(LookupImpl lookup, List<LookupElement> items, boolean onExplicitAction, @Nullable LookupElement mostRelevant) {
@@ -449,8 +446,12 @@ public class CompletionLookupArranger extends LookupArranger {
   }
 
   private boolean shouldSkip(CompletionPreselectSkipper[] skippers, LookupElement element) {
+    CompletionLocation location = myLocation;
+    if (location == null) {
+      location = new CompletionLocation(Objects.requireNonNull(myProcess.getParameters()));
+    }
     for (final CompletionPreselectSkipper skipper : skippers) {
-      if (skipper.skipElement(element, myLocation)) {
+      if (skipper.skipElement(element, location)) {
         if (LOG.isDebugEnabled()) {
           LOG.debug("Skipped element " + element + " by " + skipper);
         }
index 25da336adcf8bf206191a5a96f64ea383fb37b72..c1b2416510dc2e2a39bf9e0f697910bd078e2ffc 100644 (file)
@@ -57,10 +57,6 @@ public abstract class CompletionPhase implements Disposable {
 
   public abstract int newCompletionStarted(int time, boolean repeated);
 
-  public boolean fillInCommonPrefix() {
-    return false;
-  }
-
   public static class CommittingDocuments extends CompletionPhase {
     boolean replaced;
     private final ActionTracker myTracker;
@@ -166,15 +162,6 @@ public abstract class CompletionPhase implements Disposable {
       indicator.restorePrefix(() -> indicator.getLookup().restorePrefix());
       return indicator.nextInvocationCount(time, repeated);
     }
-
-    @Override
-    public boolean fillInCommonPrefix() {
-      if (indicator.isAutopopupCompletion()) {
-        return false;
-      }
-
-      return indicator.fillInCommonPrefix(true);
-    }
   }
 
   public static abstract class ZombiePhase extends CompletionPhase {
index ee80e2f7a8f9501945cc236e15ddd72176229436..7a16d522d5277a506f74c06ee44c2120bb3704a2 100644 (file)
@@ -34,7 +34,6 @@ import com.intellij.injected.editor.EditorWindow;
 import com.intellij.openapi.Disposable;
 import com.intellij.openapi.actionSystem.IdeActions;
 import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.Result;
 import com.intellij.openapi.command.CommandProcessor;
 import com.intellij.openapi.command.WriteCommandAction;
 import com.intellij.openapi.diagnostic.Logger;
@@ -92,9 +91,11 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
   private final Editor myEditor;
   @NotNull
   private final Caret myCaret;
-  private final CompletionParameters myParameters;
+  @Nullable private CompletionParameters myParameters;
   private final CodeCompletionHandlerBase myHandler;
   private final CompletionLookupArranger myArranger;
+  private final CompletionType myCompletionType;
+  private final int myInvocationCount;
   private OffsetsInFile myHostOffsets;
   private final LookupImpl myLookup;
   private final Alarm mySuppressTimeoutAlarm = new Alarm(this);
@@ -131,23 +132,25 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
   private final Queue<Runnable> myAdvertiserChanges = new ConcurrentLinkedQueue<>();
   private final List<CompletionResult> myDelayedMiddleMatches = ContainerUtil.newArrayList();
   private final int myStartCaret;
-  private CompletionThreadingBase myStrategy;
+  private final CompletionThreadingBase myThreading;
 
-  CompletionProgressIndicator(Editor editor, @NotNull Caret caret, int invocationCount, CompletionContext context,
+  CompletionProgressIndicator(Editor editor, @NotNull Caret caret, int invocationCount,
                               CodeCompletionHandlerBase handler, OffsetMap offsetMap, OffsetsInFile hostOffsets,
-                              boolean hasModifiers, LookupImpl lookup) {
+                              boolean hasModifiers, LookupImpl lookup, CompletionThreadingBase threading) {
     myEditor = editor;
     myCaret = caret;
     myHandler = handler;
+    myCompletionType = handler.completionType;
+    myInvocationCount = invocationCount;
     myOffsetMap = offsetMap;
     myHostOffsets = hostOffsets;
     myLookup = lookup;
     myStartCaret = myEditor.getCaretModel().getOffset();
-    myParameters = createCompletionParameters(invocationCount, context, editor);
+    myThreading = threading;
 
     myAdvertiserChanges.offer(() -> myLookup.getAdvertiser().clearAdvertisements());
 
-    myArranger = new CompletionLookupArranger(myParameters, this);
+    myArranger = new CompletionLookupArranger(this);
     myLookup.setArranger(myArranger);
 
     myLookup.addLookupListener(myLookupListener);
@@ -170,23 +173,23 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
     }
   }
 
-  private CompletionParameters createCompletionParameters(int invocationCount, CompletionContext context, Editor editor) {
-    int offset = context.getStartOffset();
-    PsiFile fileCopy = context.file;
+  private CompletionParameters createCompletionParameters(OffsetsInFile offsets) {
+    int offset = offsets.getOffsets().getOffset(CompletionInitializationContext.START_OFFSET);
+    PsiFile fileCopy = offsets.getFile();
     PsiFile originalFile = fileCopy.getOriginalFile();
-    PsiElement insertedElement = findCompletionPositionLeaf(context, offset, fileCopy, originalFile);
-    insertedElement.putUserData(CompletionContext.COMPLETION_CONTEXT_KEY, context);
-    return new CompletionParameters(insertedElement, originalFile, myHandler.completionType, offset, invocationCount, editor, this);
+    PsiElement insertedElement = findCompletionPositionLeaf(offsets, offset, originalFile);
+    insertedElement.putUserData(CompletionContext.COMPLETION_CONTEXT_KEY, new CompletionContext(fileCopy, offsets.getOffsets()));
+    return new CompletionParameters(insertedElement, originalFile, myCompletionType, offset, myInvocationCount, myEditor, this);
   }
 
   @NotNull
-  private static PsiElement findCompletionPositionLeaf(CompletionContext context, int offset, PsiFile fileCopy, PsiFile originalFile) {
-    PsiElement insertedElement = context.file.findElementAt(offset);
-    CompletionAssertions.assertCompletionPositionPsiConsistent(context, offset, fileCopy, originalFile, insertedElement);
+  private static PsiElement findCompletionPositionLeaf(OffsetsInFile offsets, int offset, PsiFile originalFile) {
+    PsiElement insertedElement = offsets.getFile().findElementAt(offset);
+    CompletionAssertions.assertCompletionPositionPsiConsistent(offsets, offset, originalFile, insertedElement);
     return insertedElement;
   }
 
-  public void itemSelected(@Nullable LookupElement lookupItem, char completionChar) {
+  void itemSelected(@Nullable LookupElement lookupItem, char completionChar) {
     boolean dispose = lookupItem == null;
     finishCompletionProcess(dispose);
     if (dispose) return;
@@ -196,7 +199,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
     myHandler.lookupItemSelected(this, lookupItem, completionChar, myLookup.getItems());
   }
 
-  public OffsetMap getOffsetMap() {
+  OffsetMap getOffsetMap() {
     return myOffsetMap;
   }
 
@@ -204,17 +207,13 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
     return myHostOffsets;
   }
 
-  private int getSelectionEndOffset() {
-    return getOffsetMap().getOffset(CompletionInitializationContext.SELECTION_END_OFFSET);
-  }
-
-  void duringCompletion(CompletionInitializationContext initContext) {
-    if (isAutopopupCompletion() && shouldPreselectFirstSuggestion(myParameters)) {
+  void duringCompletion(CompletionInitializationContext initContext, CompletionParameters parameters) {
+    if (isAutopopupCompletion() && shouldPreselectFirstSuggestion(parameters)) {
       myLookup.setFocusDegree(CodeInsightSettings.getInstance().SELECT_AUTOPOPUP_SUGGESTIONS_BY_CHARS
                               ? LookupImpl.FocusDegree.FOCUSED
                               : LookupImpl.FocusDegree.SEMI_FOCUSED);
     }
-    addDefaultAdvertisements();
+    addDefaultAdvertisements(parameters);
 
     ProgressManager.checkCanceled();
 
@@ -249,23 +248,23 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
   }
   
 
-  private void addDefaultAdvertisements() {
+  private void addDefaultAdvertisements(CompletionParameters parameters) {
     if (DumbService.isDumb(getProject())) {
       addAdvertisement("The results might be incomplete while indexing is in progress", MessageType.WARNING.getPopupBackground());
       return;
     }
     
-    advertiseTabReplacement();
+    advertiseTabReplacement(parameters);
     if (isAutopopupCompletion()) {
-      if (shouldPreselectFirstSuggestion(myParameters) && !CodeInsightSettings.getInstance().SELECT_AUTOPOPUP_SUGGESTIONS_BY_CHARS) {
+      if (shouldPreselectFirstSuggestion(parameters) && !CodeInsightSettings.getInstance().SELECT_AUTOPOPUP_SUGGESTIONS_BY_CHARS) {
         advertiseCtrlDot();
       }
       advertiseCtrlArrows();
     }
   }
 
-  private void advertiseTabReplacement() {
-    if (CompletionUtil.shouldShowFeature(myParameters, CodeCompletionFeatures.EDITING_COMPLETION_REPLACE) &&
+  private void advertiseTabReplacement(CompletionParameters parameters) {
+    if (CompletionUtil.shouldShowFeature(parameters, CodeCompletionFeatures.EDITING_COMPLETION_REPLACE) &&
       myOffsetMap.getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET) != myOffsetMap.getOffset(CompletionInitializationContext.SELECTION_END_OFFSET)) {
       String shortcut = CompletionContributor.getActionShortcut(IdeActions.ACTION_CHOOSE_LOOKUP_ITEM_REPLACE);
       if (StringUtil.isNotEmpty(shortcut)) {
@@ -312,14 +311,14 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
   }
 
 
-  void scheduleAdvertising() {
+  void scheduleAdvertising(CompletionParameters parameters) {
     if (myLookup.isAvailableToUser()) {
       return;
     }
-    for (final CompletionContributor contributor : CompletionContributor.forParameters(myParameters)) {
+    for (CompletionContributor contributor : CompletionContributor.forParameters(parameters)) {
       if (!myLookup.isCalculating() && !myLookup.isVisible()) return;
 
-      @SuppressWarnings("deprecation") String s = contributor.advertise(myParameters);
+      @SuppressWarnings("deprecation") String s = contributor.advertise(parameters);
       if (s != null) {
         addAdvertisement(s, null);
       }
@@ -337,7 +336,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
     contentComponent.addKeyListener(new ModifierTracker(contentComponent));
   }
 
-  public void setMergeCommand() {
+  void setMergeCommand() {
     CommandProcessor.getInstance().setCurrentCommandGroupId(getCompletionCommandName());
   }
 
@@ -345,23 +344,21 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
     return "Completion" + hashCode();
   }
 
-  public boolean showLookup() {
-    return updateLookup(myIsUpdateSuppressed);
+  void showLookup() {
+    updateLookup(myIsUpdateSuppressed);
   }
 
+  // non-null when running generators and adding elements to lookup
+  @Nullable
   public CompletionParameters getParameters() {
     return myParameters;
   }
 
-  public CodeCompletionHandlerBase getHandler() {
-    return myHandler;
-  }
-
   public LookupImpl getLookup() {
     return myLookup;
   }
 
-  public void withSingleUpdate(Runnable action) {
+  void withSingleUpdate(Runnable action) {
     try {
       myIsUpdateSuppressed = true;
       action.run();
@@ -371,9 +368,9 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
     }
   }
 
-  private boolean updateLookup(boolean isUpdateSuppressed) {
+  private void updateLookup(boolean isUpdateSuppressed) {
     ApplicationManager.getApplication().assertIsDispatchThread();
-    if (isOutdated() || !shouldShowLookup() || isUpdateSuppressed) return false;
+    if (isOutdated() || !shouldShowLookup() || isUpdateSuppressed) return;
 
     while (true) {
       Runnable action = myAdvertiserChanges.poll();
@@ -391,7 +388,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
     boolean justShown = false;
     if (!myLookup.isShown()) {
       if (hideAutopopupIfMeaningless()) {
-        return false;
+        return;
       }
 
       if (Registry.is("dump.threads.on.empty.lookup") && myLookup.isCalculating() && myLookup.getItems().isEmpty()) {
@@ -399,7 +396,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
       }
 
       if (!myLookup.showLookup()) {
-        return false;
+        return;
       }
       justShown = true;
     }
@@ -409,7 +406,6 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
     if (justShown) {
       myLookup.ensureSelectionVisible(true);
     }
-    return true;
   }
 
   private boolean shouldShowLookup() {
@@ -424,15 +420,11 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
     return true;
   }
 
-  private boolean isInsideIdentifier() {
-    return getIdentifierEndOffset() != getSelectionEndOffset();
-  }
-
   int getIdentifierEndOffset() {
     return myOffsetMap.getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET);
   }
 
-  void addItem(final CompletionResult item) {
+  void addItem(CompletionResult item) {
     if (!isRunning()) return;
     ProgressManager.checkCanceled();
 
@@ -465,7 +457,8 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
     if (!myLookup.addItem(item.getLookupElement(), item.getPrefixMatcher())) {
       return;
     }
-    myCount++;
+    //noinspection NonAtomicOperationOnVolatileField
+    myCount++; // invoked from a single thread
 
     if (myCount == 1) {
       JobScheduler.getScheduler().schedule(myFreezeSemaphore::up, ourInsertSingleItemTimeSpan, TimeUnit.MILLISECONDS);
@@ -623,41 +616,15 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
     return false;
   }
 
-  public boolean fillInCommonPrefix(final boolean explicit) {
-    if (isInsideIdentifier()) {
-      return false;
-    }
-
-    final Boolean aBoolean = new WriteCommandAction<Boolean>(getProject()) {
-      @Override
-      protected void run(@NotNull Result<Boolean> result) throws Throwable {
-        if (!explicit) {
-          setMergeCommand();
-        }
-        try {
-          result.setResult(myLookup.fillInCommonPrefix(explicit));
-        }
-        catch (Exception e) {
-          LOG.error(e);
-        }
-      }
-    }.execute().getResultObject();
-    return aBoolean.booleanValue();
-  }
-
-  public void restorePrefix(@NotNull final Runnable customRestore) {
-    new WriteCommandAction(getProject()) {
-      @Override
-      protected void run(@NotNull Result result) throws Throwable {
-        setMergeCommand();
-
-        customRestore.run();
-      }
-    }.execute();
+  void restorePrefix(@NotNull Runnable customRestore) {
+    WriteCommandAction.runWriteCommandAction(getProject(), () -> {
+      setMergeCommand();
+      customRestore.run();
+    });
   }
 
-  public int nextInvocationCount(int invocation, boolean reused) {
-    return reused ? Math.max(getParameters().getInvocationCount() + 1, 2) : invocation;
+  int nextInvocationCount(int invocation, boolean reused) {
+    return reused ? Math.max(myInvocationCount + 1, 2) : invocation;
   }
 
   public Editor getEditor() {
@@ -665,12 +632,12 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
   }
 
   @NotNull
-  public Caret getCaret() {
+  Caret getCaret() {
     return myCaret;
   }
 
-  public boolean isRepeatedInvocation(CompletionType completionType, Editor editor) {
-    if (completionType != myParameters.getCompletionType() || editor != myEditor) {
+  boolean isRepeatedInvocation(CompletionType completionType, Editor editor) {
+    if (completionType != myCompletionType || editor != myEditor) {
       return false;
     }
 
@@ -683,7 +650,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
 
   @Override
   public boolean isAutopopupCompletion() {
-    return myParameters.getInvocationCount() == 0;
+    return myInvocationCount == 0;
   }
 
   @NotNull
@@ -724,7 +691,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
     if (ApplicationManager.getApplication().isUnitTestMode() && !CompletionAutoPopupHandler.ourTestingAutopopup) {
       closeAndFinish(false);
       PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
-      new CodeCompletionHandlerBase(myParameters.getCompletionType(), false, false, true).invokeCompletion(getProject(), myEditor, myParameters.getInvocationCount());
+      new CodeCompletionHandlerBase(myCompletionType, false, false, true).invokeCompletion(getProject(), myEditor, myInvocationCount);
       return;
     }
 
@@ -750,8 +717,8 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
     AutoPopupController.runTransactionWithEverythingCommitted(project, () -> {
       if (phase.checkExpired()) return;
 
-      CompletionAutoPopupHandler.invokeCompletion(myParameters.getCompletionType(),
-                                                  isAutopopupCompletion(), project, myEditor, myParameters.getInvocationCount(),
+      CompletionAutoPopupHandler.invokeCompletion(myCompletionType,
+                                                  isAutopopupCompletion(), project, myEditor, myInvocationCount,
                                                   true);
     });
   }
@@ -766,7 +733,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
            System.identityHashCode(this);
   }
 
-  protected void handleEmptyLookup(final boolean awaitSecondInvocation) {
+  void handleEmptyLookup(boolean awaitSecondInvocation) {
     if (isAutopopupCompletion() && ApplicationManager.getApplication().isUnitTestMode()) {
       return;
     }
@@ -778,16 +745,24 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
       return;
     }
 
-    for (final CompletionContributor contributor : CompletionContributor.forParameters(getParameters())) {
-      final String text = contributor.handleEmptyLookup(getParameters(), getEditor());
+    CompletionParameters parameters = getParameters();
+    if (parameters != null && runContributorsOnEmptyLookup(awaitSecondInvocation, parameters)) {
+      return;
+    }
+    CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
+  }
+
+  private boolean runContributorsOnEmptyLookup(boolean awaitSecondInvocation, CompletionParameters parameters) {
+    for (CompletionContributor contributor : CompletionContributor.forParameters(parameters)) {
+      final String text = contributor.handleEmptyLookup(parameters, getEditor());
       if (StringUtil.isNotEmpty(text)) {
         LightweightHint hint = showErrorHint(getProject(), getEditor(), text);
         CompletionServiceImpl.setCompletionPhase(
           awaitSecondInvocation ? new CompletionPhase.NoSuggestionsHint(hint, this) : CompletionPhase.NoCompletion);
-        return;
+        return true;
       }
     }
-    CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
+    return false;
   }
 
   private static LightweightHint showErrorHint(Project project, Editor editor, String text) {
@@ -813,36 +788,30 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
     return true;
   }
 
+  void runContributors(CompletionInitializationContext initContext, OffsetsInFile offsets) {
+    CompletionParameters parameters = createCompletionParameters(offsets);
+    myParameters = parameters;
 
-  void startCompletion(final CompletionInitializationContext initContext) {
-    boolean sync = ApplicationManager.getApplication().isWriteAccessAllowed();
-    myStrategy = sync ? new SyncCompletion() : new AsyncCompletion();
-    myStrategy.startThread(ProgressWrapper.wrap(this), ()-> AsyncCompletion.tryReadOrCancel(this, this::scheduleAdvertising));
-    final WeighingDelegate weigher = myStrategy.delegateWeighing(this);
+    myThreading.startThread(ProgressWrapper.wrap(this), ()-> AsyncCompletion.tryReadOrCancel(this, () -> scheduleAdvertising(parameters)));
+    WeighingDelegate weigher = myThreading.delegateWeighing(this);
 
-    class CalculateItems implements Runnable {
-      @Override
-      public void run() {
-        try {
-          calculateItems(initContext, weigher);
-        }
-        catch (ProcessCanceledException ignore) {
-          cancel(); // some contributor may just throw PCE; if indicator is not canceled everything will hang
-        }
-        catch (Throwable t) {
-          cancel();
-          LOG.error(t);
-        }
-      }
+    try {
+      calculateItems(initContext, weigher, parameters);
+    }
+    catch (ProcessCanceledException ignore) {
+      cancel(); // some contributor may just throw PCE; if indicator is not canceled everything will hang
+    }
+    catch (Throwable t) {
+      cancel();
+      LOG.error(t);
     }
-    myStrategy.startThread(this, ()->AsyncCompletion.tryReadOrCancel(this, new CalculateItems()));
   }
 
-  private void calculateItems(CompletionInitializationContext initContext, WeighingDelegate weigher) {
-    duringCompletion(initContext);
+  private void calculateItems(CompletionInitializationContext initContext, WeighingDelegate weigher, CompletionParameters parameters) {
+    duringCompletion(initContext, parameters);
     ProgressManager.checkCanceled();
 
-    CompletionService.getCompletionService().performCompletion(myParameters, weigher);
+    CompletionService.getCompletionService().performCompletion(parameters, weigher);
     ProgressManager.checkCanceled();
 
     weigher.waitFor();
@@ -851,7 +820,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
 
   @Nullable
   CompletionThreadingBase getCompletionThreading() {
-    return myStrategy;
+    return myThreading;
   }
 
   public void addAdvertisement(@NotNull final String text, @Nullable final Color bgColor) {
@@ -860,6 +829,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
     myQueue.queue(myUpdate);
   }
 
+  @SuppressWarnings("unused") // for Rider
   @TestOnly
   public static void setGroupingTimeSpan(int timeSpan) {
     ourInsertSingleItemTimeSpan = timeSpan;
@@ -871,7 +841,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
     ourShowPopupAfterFirstItemGroupingTime = timeSpan;
   }
 
-  public void makeSureLookupIsShown(int timeout) {
+  void makeSureLookupIsShown(int timeout) {
     mySuppressTimeoutAlarm.addRequest(this::showIfSuppressed, timeout);
   }
 
index df661ae0f6ce75378827f91da18461c165c190d4..89fe36e0025dbad83f53d9579b0a03da85a1f5b3 100644 (file)
@@ -673,6 +673,8 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
   }
 
   private void setDataInternal(SmartPsiElementPointer element, String text, final Rectangle viewRect, final String ref) {
+    if (myManager == null) return;
+
     setElement(element);
     
     highlightLink(-1);
index 691ff62e5676cbd55658a4ab7da1fb3e36f91449..127a8ff200e2742189915274f0a1de89a4da3762 100644 (file)
@@ -1,5 +1,6 @@
 package com.intellij.codeInsight.editorActions.fillParagraph;
 
+import com.intellij.application.options.CodeStyle;
 import com.intellij.formatting.FormatterTagHandler;
 import com.intellij.openapi.command.CommandProcessor;
 import com.intellij.openapi.editor.Document;
@@ -9,7 +10,6 @@ import com.intellij.openapi.util.UnfairTextRange;
 import com.intellij.openapi.util.text.CharFilter;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.*;
-import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
 import com.intellij.psi.impl.source.codeStyle.CodeFormatterFacade;
 import com.intellij.psi.tree.IElementType;
 import org.jetbrains.annotations.NotNull;
@@ -53,11 +53,9 @@ public class ParagraphFillHandler {
     CommandProcessor.getInstance().executeCommand(element.getProject(), () -> {
       document.replaceString(textRange.getStartOffset(), textRange.getEndOffset(),
                              replacementText);
-      final CodeFormatterFacade codeFormatter = new CodeFormatterFacade(
-                                      CodeStyleSettingsManager.getSettings(element.getProject()), element.getLanguage());
-
       final PsiFile file = element.getContainingFile();
-      FormatterTagHandler formatterTagHandler = new FormatterTagHandler(CodeStyleSettingsManager.getSettings(file.getProject()));
+      final CodeFormatterFacade codeFormatter = new CodeFormatterFacade(CodeStyle.getSettings(file), element.getLanguage());
+      FormatterTagHandler formatterTagHandler = new FormatterTagHandler(CodeStyle.getSettings(file));
       List<TextRange> enabledRanges = formatterTagHandler.getEnabledRanges(file.getNode(), TextRange.create(0, document.getTextLength()));
 
       codeFormatter.doWrapLongLinesIfNecessary(editor, element.getProject(), document,
index 305d333c7a176964cd6feefcba89313ee33ef2c7..66d60437fabcb4782ab2842eefc964b34e4910e5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.codeInsight.highlighting;
 
 import com.intellij.find.FindManager;
@@ -25,28 +25,30 @@ public class EscapeHandler extends EditorActionHandler {
 
   @Override
   protected void doExecute(@NotNull Editor editor, Caret caret, DataContext dataContext){
-    editor.setHeaderComponent(null);
+    if (editor.getCaretModel().getCaretCount() == 1) {
+      editor.setHeaderComponent(null);
 
-    Project project = CommonDataKeys.PROJECT.getData(dataContext);
-    if (project != null && editor.getCaretModel().getCaretCount() == 1) {
-      HighlightManagerImpl highlightManager = (HighlightManagerImpl)HighlightManager.getInstance(project);
-      if (highlightManager != null && highlightManager.hideHighlights(editor, HighlightManager.HIDE_BY_ESCAPE | HighlightManager.HIDE_BY_ANY_KEY)) {
-
-        StatusBar statusBar = WindowManager.getInstance().getStatusBar(project);
-        if (statusBar != null) {
-          statusBar.setInfo("");
-        }
-
-        FindManager findManager = FindManager.getInstance(project);
-        if (findManager != null) {
-          FindModel model = findManager.getFindNextModel(editor);
-          if (model != null) {
-            model.setSearchHighlighters(false);
-            findManager.setFindNextModel(model);
+      Project project = CommonDataKeys.PROJECT.getData(dataContext);
+      if (project != null) {
+        HighlightManagerImpl highlightManager = (HighlightManagerImpl)HighlightManager.getInstance(project);
+        if (highlightManager != null && highlightManager.hideHighlights(editor, HighlightManager.HIDE_BY_ESCAPE | HighlightManager.HIDE_BY_ANY_KEY)) {
+  
+          StatusBar statusBar = WindowManager.getInstance().getStatusBar(project);
+          if (statusBar != null) {
+            statusBar.setInfo("");
+          }
+  
+          FindManager findManager = FindManager.getInstance(project);
+          if (findManager != null) {
+            FindModel model = findManager.getFindNextModel(editor);
+            if (model != null) {
+              model.setSearchHighlighters(false);
+              findManager.setFindNextModel(model);
+            }
           }
+  
+          return;
         }
-
-        return;
       }
     }
 
index 4d77cb07b1b28fb4e9804e38deab3a6a7683e10c..c55215fcedc2be9c0849bacc032e24a548263646 100644 (file)
@@ -15,6 +15,7 @@
  */
 package com.intellij.codeInspection;
 
+import com.intellij.application.options.CodeStyle;
 import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.editor.EditorSettings;
@@ -28,7 +29,6 @@ import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiElementVisitor;
 import com.intellij.psi.PsiFile;
 import com.intellij.psi.codeStyle.CodeStyleSettings;
-import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
 import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
 import org.jetbrains.annotations.NotNull;
 
@@ -86,7 +86,7 @@ public class ProblematicWhitespaceInspection extends LocalInspectionTool {
       if (!(fileType instanceof LanguageFileType)) {
         return;
       }
-      final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(file.getProject());
+      final CodeStyleSettings settings = CodeStyle.getSettings(file);
       final CommonCodeStyleSettings.IndentOptions indentOptions = settings.getIndentOptions(fileType);
       final boolean useTabs = indentOptions.USE_TAB_CHARACTER;
       final boolean smartTabs = indentOptions.SMART_TABS;
index 83fb5372bd5875b3004bb1b695e37109d3540eb1..757936e206784be474018d18b2b820dbb8cbf13a 100644 (file)
@@ -2,6 +2,7 @@
 
 package com.intellij.codeInspection.ui.actions;
 
+import com.intellij.application.options.CodeStyle;
 import com.intellij.codeEditor.printing.ExportToHTMLSettings;
 import com.intellij.codeInspection.InspectionApplication;
 import com.intellij.codeInspection.InspectionsBundle;
@@ -11,7 +12,10 @@ import com.intellij.codeInspection.ex.ScopeToolState;
 import com.intellij.codeInspection.ex.Tools;
 import com.intellij.codeInspection.export.ExportToHTMLDialog;
 import com.intellij.codeInspection.export.InspectionTreeHtmlWriter;
-import com.intellij.codeInspection.ui.*;
+import com.intellij.codeInspection.ui.InspectionNode;
+import com.intellij.codeInspection.ui.InspectionResultsView;
+import com.intellij.codeInspection.ui.InspectionToolPresentation;
+import com.intellij.codeInspection.ui.InspectionTreeNode;
 import com.intellij.icons.AllIcons;
 import com.intellij.ide.BrowserUtil;
 import com.intellij.openapi.actionSystem.AnAction;
@@ -29,7 +33,6 @@ import com.intellij.openapi.ui.popup.PopupStep;
 import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
 import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.JDOMUtil;
-import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
 import com.intellij.util.ui.tree.TreeUtil;
 import gnu.trove.THashSet;
 import org.jdom.Document;
@@ -136,7 +139,7 @@ public class ExportHTMLAction extends AnAction implements DumbAware {
             if (problems.getContentSize() != 0) {
               JDOMUtil.writeDocument(new Document(problems),
                                      outputDirectoryName + File.separator + toolWrapper.getShortName() + InspectionApplication.XML_EXTENSION,
-                                     CodeStyleSettingsManager.getSettings(null).getLineSeparator());
+                                     CodeStyle.getDefaultSettings().getLineSeparator());
             }
           }
           catch (IOException e) {
@@ -155,7 +158,7 @@ public class ExportHTMLAction extends AnAction implements DumbAware {
       }
       JDOMUtil.write(element,
                      new File(outputDirectoryName, InspectionApplication.DESCRIPTIONS + InspectionApplication.XML_EXTENSION),
-                     CodeStyleSettingsManager.getSettings(null).getLineSeparator());
+                     CodeStyle.getDefaultSettings().getLineSeparator());
     }
     catch (IOException e) {
       ApplicationManager.getApplication().invokeLater(() -> Messages.showErrorDialog(myView, e.getMessage()));
index 88e919f552828ba378535aaf479addcf160b4fb9..a6a1129cf437c495b240b4ecec688c48a5259da6 100644 (file)
@@ -15,6 +15,7 @@
  */
 package com.intellij.formatting.contextConfiguration;
 
+import com.intellij.application.options.CodeStyle;
 import com.intellij.codeInsight.CodeInsightBundle;
 import com.intellij.codeInsight.intention.IntentionAction;
 import com.intellij.internal.statistic.UsageTrigger;
@@ -34,7 +35,6 @@ import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.PsiFile;
 import com.intellij.psi.codeStyle.CodeStyleSettings;
 import com.intellij.psi.codeStyle.CodeStyleSettingsCodeFragmentFilter;
-import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
 import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider;
 import com.intellij.util.IncorrectOperationException;
 import org.jetbrains.annotations.Nls;
@@ -84,7 +84,7 @@ public class ConfigureCodeStyleOnSelectedFragment implements IntentionAction {
     UsageTrigger.trigger(ID);
     SelectedTextFormatter textFormatter = new SelectedTextFormatter(project, editor, file);
     CodeStyleSettingsToShow settingsToShow = calculateAffectingSettings(editor, file);
-    CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(project);
+    CodeStyleSettings settings = CodeStyle.getSettings(file);
     new FragmentCodeStyleSettingsDialog(editor, textFormatter, file.getLanguage(), settings, settingsToShow).show();
   }
 
index 25367e5f3065a4146677e87ce817b6f678eb1649..3634740c2ca0e66fefb2a754efde43e2ee7e2fd9 100644 (file)
@@ -73,7 +73,6 @@ import com.intellij.ui.treeStructure.filtered.FilteringTreeBuilder;
 import com.intellij.ui.treeStructure.filtered.FilteringTreeStructure;
 import com.intellij.util.*;
 import com.intellij.util.containers.ContainerUtil;
-import java.util.HashSet;
 import com.intellij.util.containers.JBIterable;
 import com.intellij.util.ui.JBUI;
 import com.intellij.util.ui.TextTransferable;
@@ -570,9 +569,10 @@ public class FileStructurePopup implements Disposable, TreeActionsOwner {
         }
       }
     }
-    int checkBoxCount = fileStructureNodeProviders.size() + fileStructureFilters.size();
     JPanel panel = new JPanel(new BorderLayout());
-    JPanel chkPanel = new JPanel(new GridLayout(0, checkBoxCount > 0 && checkBoxCount % 4 == 0 ? checkBoxCount / 2 : 3, 0, 0));
+    JPanel chkPanel = new JPanel();
+    chkPanel.setLayout(new BoxLayout(chkPanel, BoxLayout.X_AXIS));
+    chkPanel.setBorder(JBUI.Borders.empty(0, 10, 1, 0));
 
     Shortcut[] F4 = ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE).getShortcutSet().getShortcuts();
     Shortcut[] ENTER = CustomShortcutSet.fromString("ENTER").getShortcuts();
@@ -852,6 +852,8 @@ public class FileStructurePopup implements Disposable, TreeActionsOwner {
     }
     checkBox.setText(StringUtil.capitalize(StringUtil.trimStart(text.trim(), "Show ")));
     panel.add(checkBox);
+    panel.add(Box.createRigidArea(JBUI.size(16, 0)));
+
     myCheckBoxes.put(action.getClass(), checkBox);
   }
 
diff --git a/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java b/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java
deleted file mode 100644 (file)
index c9b5194..0000000
+++ /dev/null
@@ -1,385 +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.openapi.util;
-
-import com.intellij.ide.CopyProvider;
-import com.intellij.openapi.actionSystem.*;
-import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.ApplicationNamesInfo;
-import com.intellij.openapi.application.PathManager;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.fileChooser.FileChooser;
-import com.intellij.openapi.fileChooser.FileChooserDescriptor;
-import com.intellij.openapi.ide.CopyPasteManager;
-import com.intellij.openapi.project.DumbAware;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.ComboBox;
-import com.intellij.openapi.ui.DialogWrapper;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.ui.JBColor;
-import com.intellij.ui.ListCellRendererWrapper;
-import com.intellij.ui.components.JBLabel;
-import com.intellij.util.JdkBundle;
-import com.intellij.util.JdkBundleList;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.datatransfer.StringSelection;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.Locale;
-
-/**
- * @author denis
- */
-public class SwitchBootJdkAction extends AnAction implements DumbAware {
-  @NotNull private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.SwitchBootJdkAction");
-  @NotNull private static final String productJdkConfigFileName =
-    getExecutable() + (SystemInfo.isWindows ? ((SystemInfo.is64Bit) ? "64.exe.jdk" : ".exe.jdk") : ".jdk");
-
-  @Nullable private static final String pathsSelector = PathManager.getPathsSelector();
-  @NotNull private static final File productJdkConfigDir = new File(pathsSelector != null ?
-                                                                    PathManager.getDefaultConfigPathFor(pathsSelector) :
-                                                                    PathManager.getConfigPath());
-
-  @NotNull private static final File productJdkConfigFile = new File(productJdkConfigDir, productJdkConfigFileName);
-
-  @NotNull private static final File bundledJdkFile = getBundledJDKFile();
-
-
-
-  @NotNull
-  private static File getBundledJDKFile() {
-    return new File(SystemInfo.isMac ? "jdk" : "jre" + (JdkBundle.runtimeBitness == Bitness.x64 ? "64" : ""));
-  }
-
-  @Override
-  public void update(AnActionEvent e) {
-    e.getPresentation().setText("Switch Boot JDK");
-  }
-
-  @Override
-  public void actionPerformed(AnActionEvent event) {
-
-    if (!productJdkConfigDir.exists()) {
-      try {
-        if (!productJdkConfigDir.mkdirs()) {
-          LOG.error("Could not create " + productJdkConfigDir + " productJdkConfigDir");
-          return;
-        }
-        if (!productJdkConfigFile.exists()) {
-          if (!productJdkConfigFile.createNewFile()) {
-            LOG.error("Could not create " + productJdkConfigFileName + " productJdkConfigFile");
-            return;
-          }
-        }
-      }
-      catch (IOException e) {
-        LOG.error(e);
-        return;
-      }
-    }
-
-    SwitchBootJdkDialog dialog = new SwitchBootJdkDialog();
-    if (dialog.showAndGet()) {
-      File selectedJdkBundleFile = dialog.getSelectedFile();
-      if (selectedJdkBundleFile == null) {
-        LOG.error("SwitchBootJdkDialog returns null selection");
-        return;
-      }
-
-      FileWriter fooWriter = null;
-      try {
-        //noinspection IOResourceOpenedButNotSafelyClosed
-        fooWriter = new FileWriter(productJdkConfigFile, false);
-        fooWriter.write(selectedJdkBundleFile.getPath());
-      }
-      catch (IOException e) {
-        LOG.error(e);
-      }
-      finally {
-        try {
-          if (fooWriter != null) {
-            fooWriter.close();
-          }
-        }
-        catch (IOException e) {
-          LOG.error(e);
-        }
-      }
-      ApplicationManager.getApplication().restart();
-    }
-  }
-
-  private static class SwitchBootJdkDialog extends DialogWrapper implements DataProvider, CopyProvider {
-
-    static class JdkBundleItem {
-      @Nullable private JdkBundle myBundle;
-
-      public JdkBundleItem(@Nullable JdkBundle bundle) {
-        myBundle = bundle;
-      }
-
-      @Nullable public JdkBundle getBundle() {
-        return myBundle;
-      }
-    }
-
-    @NotNull private final ComboBox myComboBox;
-
-    private SwitchBootJdkDialog() {
-      super((Project)null, false);
-
-      final JdkBundleList pathsList = findJdkPaths();
-
-      myComboBox = new ComboBox();
-
-      final DefaultComboBoxModel<JdkBundleItem> model = new DefaultComboBoxModel<>();
-
-      for (JdkBundle jdkBundlePath : pathsList.toArrayList()) {
-        //noinspection unchecked
-        model.addElement(new JdkBundleItem(jdkBundlePath));
-      }
-
-      model.addElement(new JdkBundleItem(null));
-
-      //noinspection unchecked
-      myComboBox.setModel(model);
-
-      //noinspection unchecked
-      myComboBox.setRenderer(new ListCellRendererWrapper() {
-        @Override
-        public void customize(JList list, Object value, int index, boolean selected, boolean hasFocus) {
-          JdkBundle jdkBundleDescriptor = ((JdkBundleItem)value).getBundle();
-          if (jdkBundleDescriptor != null) {
-            if (jdkBundleDescriptor.isBoot()) {
-              setForeground(JBColor.DARK_GRAY);
-            }
-            setText(jdkBundleDescriptor.getVisualRepresentation());
-          }
-          else {
-            setText("...");
-          }
-        }
-      });
-
-      myComboBox.addActionListener(new ActionListener() {
-        @Override
-        public void actionPerformed(ActionEvent e) {
-          if (myComboBox.getSelectedItem() == null) {
-            LOG.error("Unexpected nullable selection");
-            return;
-          }
-
-          JdkBundleItem item = (JdkBundleItem)myComboBox.getSelectedItem();
-
-          if (item.getBundle() == null) {
-            FileChooserDescriptor descriptor = new FileChooserDescriptor(false, true, false, false, false, false) {
-              JdkBundle selectedBundle;
-
-              @Override
-              public boolean isFileSelectable(final VirtualFile file) {
-                selectedBundle = null;
-                if (!super.isFileSelectable(file)) return false;
-                // allow selection of JDK of any arch, so that to warn about possible arch mismatch during validation
-                JdkBundle bundle = JdkBundle.createBundle(new File(file.getPath()), false, false, false);
-                if (bundle == null) return false;
-                Version version = bundle.getVersion();
-                selectedBundle = bundle;
-                return version != null && !version.lessThan(JDK8_VERSION.major, JDK8_VERSION.minor, JDK8_VERSION.bugfix);
-              }
-
-              @Override
-              public void validateSelectedFiles(VirtualFile[] files) throws Exception {
-                super.validateSelectedFiles(files);
-                assert files.length == 1;
-                if (selectedBundle == null) {
-                  throw new Exception("Invalid JDK bundle!");
-                }
-                if (selectedBundle.getBitness() != JdkBundle.runtimeBitness) {
-                  //noinspection SpellCheckingInspection
-                  throw new Exception("JDK arch mismatch! Your IDE's arch is " + JdkBundle.runtimeBitness);
-                }
-              }
-            };
-
-            FileChooser.chooseFiles(descriptor, null, null, files -> {
-              if (files.size() > 0) {
-                final File jdkFile = new File(files.get(0).getPath());
-                JdkBundle selectedJdk = pathsList.getBundle(jdkFile.getPath());
-                JdkBundleItem jdkBundleItem;
-                if (selectedJdk == null) {
-                  selectedJdk = JdkBundle.createBundle(jdkFile, false, false);
-                  if (selectedJdk != null) {
-                    pathsList.addBundle(selectedJdk, true);
-                    if (model.getSize() > 0) {
-                      jdkBundleItem = new JdkBundleItem(selectedJdk);
-                      model.insertElementAt(jdkBundleItem, model.getSize() - 1);
-                    }
-                    else {
-                      jdkBundleItem = new JdkBundleItem(selectedJdk);
-                      model.addElement(jdkBundleItem);
-                    }
-                  }
-                  else {
-                    LOG.error("Cannot create bundle for path: " + jdkFile.getPath());
-                    return;
-                  }
-                } else {
-                  jdkBundleItem = new JdkBundleItem(selectedJdk);
-                }
-                myComboBox.setSelectedItem(jdkBundleItem);
-              }
-            });
-          }
-
-          item = (JdkBundleItem)myComboBox.getSelectedItem();
-
-          if (item == null || item.getBundle() == null) {
-            item = model.getElementAt(0);
-            myComboBox.setSelectedItem(item);
-          }
-
-          setOKActionEnabled(item.getBundle() != null && !item.getBundle().isBoot());
-        }
-      });
-      myComboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
-
-      setTitle("Switch IDE Boot JDK");
-      setOKActionEnabled(false); // First item is a boot jdk
-      init();
-    }
-
-    @Nullable
-    @Override
-    protected JComponent createNorthPanel() {
-      return new JBLabel("Select Boot JDK");
-    }
-
-    @Nullable
-    @Override
-    protected JComponent createCenterPanel() {
-      JPanel panel = new JPanel(new BorderLayout());
-      panel.add(myComboBox, BorderLayout.CENTER);
-      ActionToolbarImpl toolbar = (ActionToolbarImpl)ActionManager.getInstance()
-        .createActionToolbar("SwitchBootJDKCopyAction", new DefaultActionGroup(ActionManager.getInstance().getAction(IdeActions.ACTION_COPY)), true);
-      toolbar.setReservePlaceAutoPopupIcon(false);
-      panel.add(toolbar , BorderLayout.EAST);
-      return panel;
-    }
-
-    @Nullable
-    @Override
-    public JComponent getPreferredFocusedComponent() {
-      return myComboBox;
-    }
-
-    @Nullable
-    public File getSelectedFile() {
-      final JdkBundleItem item = (JdkBundleItem)myComboBox.getSelectedItem();
-      if (item == null) return null;
-
-      final JdkBundle bundle = item.getBundle();
-
-      return bundle != null ? bundle.getLocation() : null;
-    }
-
-    @Override
-    public void performCopy(@NotNull DataContext dataContext) {
-      File file = getSelectedFile();
-      if (file == null) return;
-      CopyPasteManager.getInstance().setContents(new StringSelection(file.getAbsolutePath()));
-    }
-
-    @Override
-    public boolean isCopyEnabled(@NotNull DataContext dataContext) {
-      return getSelectedFile() != null;
-    }
-
-    @Override
-    public boolean isCopyVisible(@NotNull DataContext dataContext) {
-      return getSelectedFile() != null;
-    }
-
-    @Nullable
-    @Override
-    public Object getData(String dataId) {
-      if (PlatformDataKeys.COPY_PROVIDER.is(dataId)) return this;
-      return null;
-    }
-  }
-
-  private static final String STANDARD_JDK_LOCATION_ON_MAC_OS_X = "/Library/Java/JavaVirtualMachines/";
-  private static final String [] STANDARD_JVM_LOCATIONS_ON_LINUX = new String[] {
-    "/usr/lib/jvm/", // Ubuntu
-    "/usr/java/"     // Fedora
-  };
-  private static final String STANDARD_JVM_X64_LOCATIONS_ON_WINDOWS = "Program Files/Java";
-
-  private static final String STANDARD_JVM_X86_LOCATIONS_ON_WINDOWS = "Program Files (x86)/Java";
-
-  private static final Version JDK8_VERSION = new Version(1, 8, 0);
-
-  @NotNull
-  public static JdkBundleList findJdkPaths() {
-    JdkBundle bootJdk = JdkBundle.createBoot();
-
-    JdkBundleList jdkBundleList = new JdkBundleList();
-    if (bootJdk != null) {
-      jdkBundleList.addBundle(bootJdk, true);
-    }
-
-    if (new File(PathManager.getHomePath() + File.separator + bundledJdkFile).exists()) {
-      JdkBundle bundledJdk = JdkBundle.createBundle(bundledJdkFile, false, true);
-      if (bundledJdk != null) {
-        jdkBundleList.addBundle(bundledJdk, true);
-      }
-    }
-
-    if (SystemInfo.isMac) {
-      jdkBundleList.addBundlesFromLocation(STANDARD_JDK_LOCATION_ON_MAC_OS_X, JDK8_VERSION, null);
-    }
-    else if (SystemInfo.isLinux) {
-      for (String location : STANDARD_JVM_LOCATIONS_ON_LINUX) {
-        jdkBundleList.addBundlesFromLocation(location, JDK8_VERSION, null);
-      }
-    }
-    else if (SystemInfo.isWindows) {
-      for (File root : File.listRoots()) {
-        if (SystemInfo.is32Bit) {
-          jdkBundleList.addBundlesFromLocation(new File(root, STANDARD_JVM_X86_LOCATIONS_ON_WINDOWS).getAbsolutePath(), JDK8_VERSION, null);
-        }
-        else {
-          jdkBundleList.addBundlesFromLocation(new File(root, STANDARD_JVM_X64_LOCATIONS_ON_WINDOWS).getAbsolutePath(), JDK8_VERSION, null);
-        }
-      }
-    }
-
-    return jdkBundleList;
-  }
-
-  @NotNull
-  private static String getExecutable() {
-    final String executable = System.getProperty("idea.executable");
-    return executable != null ? executable : ApplicationNamesInfo.getInstance().getProductName().toLowerCase(Locale.US);
-  }
-}
index 7149a816cc76c8c317c8edf2552dadf3f92522f1..797467e09d6cc2991cb1037ba7e8fbfc4d98ce5e 100644 (file)
@@ -15,6 +15,7 @@
  */
 package com.intellij.psi.codeStyle.extractor;
 
+import com.intellij.application.options.CodeStyle;
 import com.intellij.lang.Language;
 import com.intellij.lang.LanguageFormatting;
 import com.intellij.openapi.actionSystem.*;
@@ -86,7 +87,7 @@ public class ExtractCodeStyleAction extends AnAction implements DumbAware {
       return;
     }
 
-    final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(project);
+    final CodeStyleSettings settings = CodeStyle.getSettings(file);
 
     final CodeStyleDeriveProcessor genProcessor = new GenProcessor(extractor);
     final PsiFile finalFile = file;
index 26db3a40eeb2f1b7ca5b618aa0dffaaf26535c09..54147aa55d63ca574a5e79178fee20d075577fc0 100644 (file)
@@ -36,7 +36,6 @@ import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.*;
 import com.intellij.psi.impl.BooleanRunnable;
 import com.intellij.psi.impl.DebugUtil;
-import com.intellij.psi.impl.DocumentCommitThread;
 import com.intellij.psi.impl.PsiDocumentManagerBase;
 import com.intellij.psi.impl.smartPointers.Identikit;
 import com.intellij.psi.impl.smartPointers.SelfElementInfo;
@@ -521,7 +520,7 @@ class InjectionRegistrarImpl extends MultiHostRegistrarImpl implements MultiHost
         try {
           final DiffLog diffLog = BlockSupportImpl.mergeTrees((PsiFileImpl)oldFile, oldFileNode, injectedNode, new DaemonProgressIndicator(),
                                                               oldFileNode.getText());
-          DocumentCommitThread.doActualPsiChange(oldFile, diffLog);
+          diffLog.doActualPsiChange(oldFile);
         }
         finally {
           DebugUtil.finishPsiModification();
@@ -549,7 +548,7 @@ class InjectionRegistrarImpl extends MultiHostRegistrarImpl implements MultiHost
    *   (see call to {@link #parseFile(Language, Language, DocumentWindowImpl, VirtualFile, DocumentEx, PsiFile, Project, CharSequence, List, StringBuilder, String)} )
    * - feed two injections, the old and the new created fake to the standard tree diff
    *   (see call to {@link BlockSupportImpl#mergeTrees(PsiFileImpl, ASTNode, ASTNode, ProgressIndicator, CharSequence)} )
-   * - return continuation which performs actual PSI replace, just like {@link DocumentCommitThread#doCommit(DocumentCommitThread.CommitTask, PsiFile, FileASTNode, ProperTextRange, List)} does
+   * - return continuation which performs actual PSI replace, just like {@link com.intellij.psi.impl.DocumentCommitThread#doCommit(com.intellij.psi.impl.DocumentCommitThread.CommitTask, PsiFile, FileASTNode, ProperTextRange, List)} does
    *   {@code null} means we failed to reparse and will have to kill the injection.
    * </pre>
    */
@@ -626,7 +625,7 @@ class InjectionRegistrarImpl extends MultiHostRegistrarImpl implements MultiHost
         oldInjectedPsiViewProvider.performNonPhysically(() -> {
           DebugUtil.startPsiModification("injected tree diff");
           try {
-            DocumentCommitThread.doActualPsiChange(oldInjectedPsi, diffLog);
+            diffLog.doActualPsiChange(oldInjectedPsi);
 
             // create new shreds after commit is complete because otherwise the range markers will be changed in MarkerCache.updateMarkers
             Place newPlace = new Place();
diff --git a/platform/lang-impl/src/com/intellij/util/JdkBundleList.java b/platform/lang-impl/src/com/intellij/util/JdkBundleList.java
deleted file mode 100644 (file)
index 7899f9a..0000000
+++ /dev/null
@@ -1,121 +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.util;
-
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.Pair;
-import com.intellij.openapi.util.Version;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-
-public class JdkBundleList {
-  @NotNull private static final Logger LOG = Logger.getInstance("#com.intellij.util.JdkBundleList");
-
-  private ArrayList<JdkBundle> bundleList = new ArrayList<>();
-  private HashMap<String, JdkBundle> bundleMap = new HashMap<>();
-  private HashMap<String, JdkBundle> nameVersionMap = new HashMap<>();
-
-  public void addBundle(@NotNull JdkBundle bundle, boolean forceOldVersion) {
-    JdkBundle bundleDescr = bundleMap.get(bundle.getLocation().getAbsolutePath());
-    if (bundleDescr == null) {
-      addMostRecent(bundle, forceOldVersion);
-    }
-    else {
-      if (bundle.isBundled()) bundleDescr.setBundled(true); // preserve bundled flag
-      if (bundle.isBoot()) bundleDescr.setBoot(true); // preserve boot flag
-    }
-  }
-
-  public JdkBundle getBundle(@NotNull String path) {
-    return bundleMap.get(path);
-  }
-
-  private void addMostRecent(@NotNull JdkBundle bundleDescriptor, boolean forceOldVersion) {
-    Pair<Version, Integer> versionUpdate = bundleDescriptor.getVersionUpdate();
-    boolean updateVersionMap = versionUpdate != null;
-    if (!bundleList.isEmpty() && updateVersionMap) {
-      JdkBundle latestJdk = nameVersionMap.get(bundleDescriptor.getNameVersion().replaceFirst("\\(.*\\)", ""));
-      if (latestJdk != null) {
-        Pair<Version, Integer> latestVersionUpdate = latestJdk.getVersionUpdate();
-        if (latestVersionUpdate != null) {
-          if (latestVersionUpdate.second >= versionUpdate.second) {
-            if (!forceOldVersion) return; // do not add old non bundled jdk builds unless asked
-
-            updateVersionMap = false; // include bundled version but do not update map
-          }
-          else if (!latestJdk.isBoot() && !latestJdk.isBundled()) { // preserve boot and bundled versions
-            bundleList.remove(latestJdk);
-            nameVersionMap.remove(latestJdk.getNameVersion());
-            bundleMap.remove(latestJdk.getLocation().getAbsolutePath());
-          }
-        }
-      }
-    }
-
-    bundleList.add(bundleDescriptor);
-    bundleMap.put(bundleDescriptor.getLocation().getAbsolutePath(), bundleDescriptor);
-
-    if (updateVersionMap) {
-      nameVersionMap.put(bundleDescriptor.getNameVersion(), bundleDescriptor);
-    }
-  }
-
-  public void addBundlesFromLocation(@NotNull String location, @Nullable Version minVer, @Nullable Version maxVer) {
-    File jvmLocation = new File(location);
-
-    if (!jvmLocation.exists()) {
-      LOG.debug("Standard jvm location does not exists: " + jvmLocation);
-      return;
-    }
-
-    File[] jvms = jvmLocation.listFiles();
-
-    if (jvms == null) {
-      LOG.debug("Cannot get jvm list from: " + jvmLocation);
-      return;
-    }
-
-    for (File jvm : jvms) {
-      JdkBundle jvmBundle = JdkBundle.createBundle(jvm, false, false);
-      if (jvmBundle == null || jvmBundle.getVersionUpdate() == null) continue;
-
-      Version jdkVer = jvmBundle.getVersion();
-      if (jdkVer == null) continue; // Skip unknown
-
-      if (minVer != null && jdkVer.lessThan(minVer.major, minVer.minor, minVer.bugfix)) {
-        continue; // Skip below supported
-      }
-
-      if (maxVer != null && maxVer.lessThan(jdkVer.major, jdkVer.minor, jdkVer.bugfix)) {
-        continue; // Skip above supported
-      }
-
-      addBundle(jvmBundle, false);
-    }
-  }
-
-  public ArrayList<JdkBundle> toArrayList() {
-    return bundleList;
-  }
-
-  public boolean contains(@NotNull String path) {
-    return bundleMap.keySet().contains(path);
-  }
-}
index bb362096024313591594a8bc08b7f56d03ebc52e..515d9c4ef52e6dd9dd6331df15195ea69e35a965 100644 (file)
@@ -1971,25 +1971,27 @@ public class FileBasedIndexImpl extends FileBasedIndex implements BaseComponent,
         myScheduledVfsEventsWorkers.incrementAndGet();
         myVfsEventsExecutor.submit(this::processFilesInReadActionWithYieldingToWriteAction);
 
-        Runnable startDumbMode = () -> {
-          for (Project project : ProjectManager.getInstance().getOpenProjects()) {
-            DumbServiceImpl dumbService = DumbServiceImpl.getInstance(project);
-            DumbModeTask task = FileBasedIndexProjectHandler.createChangedFilesIndexingTask(project);
-
-            if (task != null) {
-              dumbService.queueTask(task);
+        if (Registry.is("try.starting.dumb.mode.where.many.files.changed")) {
+          Runnable startDumbMode = () -> {
+            for (Project project : ProjectManager.getInstance().getOpenProjects()) {
+              DumbServiceImpl dumbService = DumbServiceImpl.getInstance(project);
+              DumbModeTask task = FileBasedIndexProjectHandler.createChangedFilesIndexingTask(project);
+  
+              if (task != null) {
+                dumbService.queueTask(task);
+              }
             }
+          };
+
+          Application app = ApplicationManager.getApplication();
+          if (!app.isHeadlessEnvironment()  /*avoid synchronous ensureUpToDate to prevent deadlock*/ && 
+              app.isDispatchThread() && 
+              !LaterInvocator.isInModalContext()) {
+            startDumbMode.run();
+          }
+          else {
+            app.invokeLater(startDumbMode, ModalityState.NON_MODAL);
           }
-        };
-        
-        Application app = ApplicationManager.getApplication();
-        if (!app.isHeadlessEnvironment()  /*avoid synchronous ensureUpToDate to prevent deadlock*/ && 
-            app.isDispatchThread() && 
-            !LaterInvocator.isInModalContext()) {
-          startDumbMode.run();
-        }
-        else {
-          app.invokeLater(startDumbMode, ModalityState.NON_MODAL);
         }
       }
     }
diff --git a/platform/platform-api/src/com/intellij/ide/actions/ActionsCollector.java b/platform/platform-api/src/com/intellij/ide/actions/ActionsCollector.java
new file mode 100644 (file)
index 0000000..0569a22
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package com.intellij.ide.actions;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.util.xmlb.annotations.MapAnnotation;
+import com.intellij.util.xmlb.annotations.Tag;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public abstract class ActionsCollector {
+  public abstract void record(String actionId);
+
+  public abstract State getState();
+
+  public static ActionsCollector getInstance() {
+    return ServiceManager.getService(ActionsCollector.class);
+  }
+
+  public final static class State {
+    @Tag("counts")
+    @MapAnnotation(surroundWithTag = false, keyAttributeName = "action", valueAttributeName = "count")
+    public Map<String, Integer> myValues = new HashMap<>();
+  }
+}
index 03d16b6d24a405b37b2d7b1baeac54ec9ae13f7b..94b952270440fb4b672f459c2bd027675f001658 100644 (file)
@@ -1,22 +1,9 @@
-/*
- * Copyright 2000-2017 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.
- */
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.openapi.ui;
 
 import com.intellij.CommonBundle;
 import com.intellij.icons.AllIcons;
+import com.intellij.ide.actions.ActionsCollector;
 import com.intellij.ide.ui.UISettings;
 import com.intellij.idea.ActionsBundle;
 import com.intellij.openapi.Disposable;
@@ -1014,6 +1001,7 @@ public abstract class DialogWrapper {
    * @see #doCancelAction
    */
   public void doCancelAction(AWTEvent source) {
+    recordAction("DialogCancelAction", source);
     doCancelAction();
   }
 
@@ -1854,6 +1842,7 @@ public abstract class DialogWrapper {
 
     @Override
     protected void doAction(ActionEvent e) {
+      recordAction("DialogOkAction");
       List<ValidationInfo> infoList = doValidateAll();
       if (!infoList.isEmpty()) {
         ValidationInfo info = infoList.get(0);
@@ -1872,6 +1861,17 @@ public abstract class DialogWrapper {
     }
   }
 
+  private void recordAction(String name) {
+    recordAction(name, EventQueue.getCurrentEvent());
+  }
+
+  private void recordAction(String name, AWTEvent event) {
+    if (event instanceof KeyEvent) {
+      String shortcut = KeymapUtil.getKeystrokeText(KeyStroke.getKeyStrokeForEvent((KeyEvent)event));
+      ActionsCollector.getInstance().record(name + " " + shortcut);
+    }
+  }
+
   protected class CancelAction extends DialogWrapperAction {
     private CancelAction() {
       super(CommonBundle.getCancelButtonText());
index 490ef41a6fbdbac96c3a78f743c8da222f8f5167..c9d5c1ce01cd35549761f4838de7e9e0ee3d58f6 100644 (file)
@@ -409,24 +409,24 @@ public class JBList<E> extends JList<E> implements ComponentWithEmptyText, Compo
 
     boolean addExtraSpace = 0 < visibleRows && visibleRows < modelRows && Registry.is("ide.preferred.scrollable.viewport.extra.space");
     Insets insets = list.getInsets();
+    size.height = insets != null ? insets.top + insets.bottom : 0;
     if (0 < fixedWidth && 0 < fixedHeight) {
       size.width = insets != null ? insets.left + insets.right + fixedWidth : fixedWidth;
-      size.height = fixedHeight * visibleRows;
+      size.height += fixedHeight * visibleRows;
       if (addExtraSpace) size.height += fixedHeight / 2;
     }
     else if (addExtraSpace) {
       Rectangle bounds = list.getCellBounds(visibleRows, visibleRows);
-      size.height = bounds != null ? bounds.y + bounds.height / 2 : 0;
+      if (bounds != null) size.height = bounds.y + bounds.height / 2;
     }
     else if (visibleRows > 0) {
       int lastRow = Math.min(visibleRows, modelRows) - 1;
       Rectangle bounds = list.getCellBounds(lastRow, lastRow);
-      size.height = bounds != null ? bounds.y + bounds.height : 0;
-    }
-    else {
-      size.height = 0;
+      if (bounds != null) {
+        size.height = bounds.y + bounds.height;
+        if (insets != null) size.height += insets.bottom;
+      }
     }
-    if (insets != null) size.height += insets.top + insets.bottom;
     return size;
   }
 }
index d85e98f5d7a586c545c27afb6a3cc3abb8156c43..483c8e080f7a85acfd10c1216f1cac84ed3ddb25 100644 (file)
@@ -2,6 +2,7 @@
 package com.intellij.featureStatistics;
 
 import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent;
+import com.intellij.internal.statistic.eventLog.FeatureUsageEventLogger;
 import com.intellij.openapi.components.PersistentStateComponent;
 import com.intellij.openapi.components.RoamingType;
 import com.intellij.openapi.components.State;
@@ -176,6 +177,7 @@ public class FeatureUsageTrackerImpl extends FeatureUsageTracker implements Pers
      // TODO: LOG.error("Feature '" + featureId +"' must be registered prior triggerFeatureUsed() is called");
     }
     else {
+      FeatureUsageEventLogger.INSTANCE.log(descriptor.getGroupId(), descriptor.getId());
       descriptor.triggerUsed();
     }
   }
index a5955b95d77793674c9fe13dd1d0be2cccf54a12..c25ebad2cc9fe64eea593580270c23e174f7d708 100644 (file)
@@ -1,18 +1,4 @@
-/*
- * Copyright 2000-2017 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.
- */
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.ide;
 
 import com.intellij.concurrency.JobScheduler;
@@ -27,20 +13,19 @@ import com.intellij.notification.impl.NotificationFullContent;
 import com.intellij.openapi.actionSystem.ActionManager;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.ex.ActionUtil;
-import com.intellij.openapi.application.*;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ApplicationNamesInfo;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.application.ReadAction;
 import com.intellij.openapi.components.ApplicationComponent;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.util.Bitness;
-import com.intellij.openapi.util.Ref;
 import com.intellij.openapi.util.SystemInfo;
-import com.intellij.openapi.util.Version;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.util.JdkBundle;
 import com.intellij.util.SystemProperties;
 import com.intellij.util.TimeoutUtil;
-import com.intellij.util.ui.JBUI;
-import com.intellij.util.ui.UIUtil;
+import com.intellij.util.lang.JavaVersion;
 import com.sun.jna.Library;
 import com.sun.jna.Memory;
 import com.sun.jna.Native;
@@ -50,7 +35,6 @@ import org.jetbrains.annotations.Nullable;
 import org.jetbrains.annotations.PropertyKey;
 
 import javax.swing.*;
-import javax.swing.event.HyperlinkEvent;
 import java.io.File;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
@@ -63,8 +47,7 @@ public class SystemHealthMonitor implements ApplicationComponent {
 
   private static final NotificationGroup GROUP = new NotificationGroup("System Health", NotificationDisplayType.STICKY_BALLOON, true);
   private static final String SWITCH_JDK_ACTION = "SwitchBootJdk";
-  private static final int LATEST_JDK8_UPDATE = 144;
-  private static final String LATEST_JDK_RELEASE = "1.8.0u" + LATEST_JDK8_UPDATE;
+  private static final JavaVersion MIN_RECOMMENDED_JDK = JavaVersion.compose(8, 0, 144, 0, false);
 
   private final PropertiesComponent myProperties;
 
@@ -74,39 +57,29 @@ public class SystemHealthMonitor implements ApplicationComponent {
 
   @Override
   public void initComponent() {
-    checkRuntime();
-    checkReservedCodeCacheSize();
-    checkIBus();
-    checkSignalBlocking();
-    startDiskSpaceMonitoring();
+    ApplicationManager.getApplication().executeOnPooledThread(() -> {
+      checkRuntime();
+      checkReservedCodeCacheSize();
+      checkIBus();
+      checkSignalBlocking();
+      startDiskSpaceMonitoring();
+    });
   }
 
   private void checkRuntime() {
-    if (StringUtil.endsWithIgnoreCase(System.getProperty("java.version", ""), "-ea")) {
+    if (JavaVersion.current().ea) {
       showNotification("unsupported.jvm.ea.message", null);
     }
 
-    JdkBundle bundle = JdkBundle.createBoot();
-    if (bundle != null && !bundle.isBundled()) {
-      Version version = bundle.getVersion();
-      Integer updateNumber = bundle.getUpdateNumber();
-      boolean isRuntimeOutdated = version != null && updateNumber != null && version.major == 1 && version.minor == 8 && updateNumber < LATEST_JDK8_UPDATE;
-      if (!SystemInfo.isJetBrainsJvm || isRuntimeOutdated) {
-        String runtimeVersion = version.toCompactString() + "u" + updateNumber;
-        boolean isBundledJdkValid = false;
-
-        final File bundledJDKAbsoluteLocation = JdkBundle.getBundledJDKAbsoluteLocation();
-        if (bundledJDKAbsoluteLocation.exists() && bundle.getBitness() == Bitness.x64) {
-          if (SystemInfo.isMacIntel64) {
-            isBundledJdkValid = true;
-          }
-          else if (SystemInfo.isWindows || SystemInfo.isLinux) {
-            JdkBundle bundledJdk = JdkBundle.createBundle(bundledJDKAbsoluteLocation, false, false);
-            if (bundledJdk != null && bundledJdk.getVersion() != null) {
-              isBundledJdkValid = true; // Version of bundled jdk is available, so the jdk is compatible with underlying OS
-            }
-          }
-        }
+    JdkBundle bootJdk = JdkBundle.createBoot();
+    if (!bootJdk.isBundled()) {
+      boolean outdatedRuntime = bootJdk.getBundleVersion().compareTo(MIN_RECOMMENDED_JDK) < 0;
+      if (!SystemInfo.isJetBrainsJvm || outdatedRuntime) {
+        JdkBundle bundledJdk;
+        boolean validBundledJdk =
+          (SystemInfo.isWindows || SystemInfo.isMac || SystemInfo.isLinux) &&
+          (bundledJdk = JdkBundle.createBundled()) != null &&
+          bundledJdk.isOperational();
 
         NotificationAction switchAction = new NotificationAction("Switch") {
           @Override
@@ -116,12 +89,16 @@ public class SystemHealthMonitor implements ApplicationComponent {
           }
         };
 
-        if (isRuntimeOutdated) {
-          showNotification(isBundledJdkValid ? "outdated.jre.version.message1" : "outdated.jre.version.message2",
-                           isBundledJdkValid ? switchAction : null, runtimeVersion, LATEST_JDK_RELEASE);
+        String current = bootJdk.getBundleVersion().toString();
+        if (!SystemInfo.isJetBrainsJvm) current += " by " + SystemInfo.JAVA_VENDOR;
+        if (outdatedRuntime && validBundledJdk) {
+          showNotification("outdated.jre.version.message1", switchAction, current, MIN_RECOMMENDED_JDK);
         }
-        else if (isBundledJdkValid) {
-          showNotification("bundled.jre.version.message", switchAction, runtimeVersion);
+        else if (outdatedRuntime) {
+          showNotification("outdated.jre.version.message2", null, current, MIN_RECOMMENDED_JDK);
+        }
+        else if (validBundledJdk) {
+          showNotification("bundled.jre.version.message", switchAction, current);
         }
       }
     }
@@ -153,8 +130,7 @@ public class SystemHealthMonitor implements ApplicationComponent {
           if (m.find() && StringUtil.compareVersionNumbers(m.group(1), "1.5.11") < 0) {
             String fix = System.getenv("IBUS_ENABLE_SYNC_MODE");
             if (fix == null || fix.isEmpty() || fix.equals("0") || fix.equalsIgnoreCase("false")) {
-              showNotification("ibus.blocking.warn.message", new BrowseNotificationAction(IdeBundle.message("ibus.blocking.details.action"),
-                                                                                          IdeBundle.message("ibus.blocking.details.url")));
+              showNotification("ibus.blocking.warn.message", detailsAction("https://youtrack.jetbrains.com/issue/IDEA-78860"));
             }
           }
         }
@@ -170,8 +146,7 @@ public class SystemHealthMonitor implements ApplicationComponent {
         if (lib.sigaction(LibC.SIGINT, null, buf) == 0) {
           long handler = Native.POINTER_SIZE == 8 ? buf.getLong(0) : buf.getInt(0);
           if (handler == LibC.SIG_IGN) {
-            showNotification("ide.sigint.ignored.message", new BrowseNotificationAction(IdeBundle.message("ide.sigint.ignored.action"),
-                                                                                        IdeBundle.message("ide.sigint.ignored.url")));
+            showNotification("ide.sigint.ignored.message", detailsAction("https://youtrack.jetbrains.com/issue/IDEA-157989"));
           }
         }
       }
@@ -188,42 +163,32 @@ public class SystemHealthMonitor implements ApplicationComponent {
     LOG.info("issue detected: " + key + (ignored ? " (ignored)" : ""));
     if (ignored) return;
 
-    String message = IdeBundle.message(key, params);
-
-    Application app = ApplicationManager.getApplication();
-    app.getMessageBus().connect(app).subscribe(AppLifecycleListener.TOPIC, new AppLifecycleListener() {
+    Notification notification = new MyNotification(IdeBundle.message(key, params));
+    if (action != null) {
+      notification.addAction(action);
+    }
+    notification.addAction(new NotificationAction(IdeBundle.message("sys.health.acknowledge.action")) {
       @Override
-      public void appFrameCreated(String[] commandLineArgs, @NotNull Ref<Boolean> willOpenProject) {
-        app.invokeLater(() -> {
-          Notification notification = new MyNotification(message);
-          if (action != null) {
-            notification.addAction(action);
-          }
-          notification.addAction(new NotificationAction(IdeBundle.message("sys.health.acknowledge.action")) {
-            @Override
-            public void actionPerformed(@NotNull AnActionEvent e, @NotNull Notification notification) {
-              notification.expire();
-              myProperties.setValue("ignore." + key, "true");
-            }
-          });
-          notification.setImportant(true);
-          Notifications.Bus.notify(notification);
-        });
+      public void actionPerformed(@NotNull AnActionEvent e, @NotNull Notification notification) {
+        notification.expire();
+        myProperties.setValue("ignore." + key, "true");
       }
     });
+    notification.setImportant(true);
+
+    ApplicationManager.getApplication().invokeLater(() -> Notifications.Bus.notify(notification));
   }
 
   private static final class MyNotification extends Notification implements NotificationFullContent {
     public MyNotification(@NotNull String content) {
-      super(GROUP.getDisplayId(), "", content, NotificationType.WARNING, new NotificationListener.Adapter() {
-        @Override
-        protected void hyperlinkActivated(@NotNull Notification notification, @NotNull HyperlinkEvent e) {
-          BrowserUtil.browse(e.getDescription());
-        }
-      });
+      super(GROUP.getDisplayId(), "", content, NotificationType.WARNING);
     }
   }
 
+  private static NotificationAction detailsAction(String url) {
+    return new BrowseNotificationAction(IdeBundle.message("sys.health.details"), url);
+  }
+
   private static void startDiskSpaceMonitoring() {
     if (SystemProperties.getBooleanProperty("idea.no.system.path.space.monitoring", false)) {
       return;
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/SwitchBootJdkAction.java b/platform/platform-impl/src/com/intellij/ide/actions/SwitchBootJdkAction.java
new file mode 100644 (file)
index 0000000..6f278e1
--- /dev/null
@@ -0,0 +1,334 @@
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package com.intellij.ide.actions;
+
+import com.intellij.ide.CopyProvider;
+import com.intellij.notification.Notification;
+import com.intellij.notification.NotificationType;
+import com.intellij.notification.Notifications;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ApplicationNamesInfo;
+import com.intellij.openapi.application.ModalityState;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.fileChooser.FileChooser;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.ide.CopyPasteManager;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.ComboBox;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.util.Bitness;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.ui.JBColor;
+import com.intellij.ui.ListCellRendererWrapper;
+import com.intellij.ui.components.JBLabel;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.JdkBundle;
+import com.intellij.util.JdkBundleList;
+import com.intellij.util.lang.JavaVersion;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.datatransfer.StringSelection;
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import java.util.List;
+import java.util.stream.Stream;
+
+/**
+ * @author denis
+ */
+public class SwitchBootJdkAction extends AnAction implements DumbAware {
+  private static final Logger LOG = Logger.getInstance(SwitchBootJdkAction.class);
+
+  private static final JavaVersion MIN_VERSION = JavaVersion.compose(8), MAX_VERSION = null;
+
+  private static final String WINDOWS_X64_JVM_LOCATION = "Program Files/Java";
+  private static final String WINDOWS_X86_JVM_LOCATION = "Program Files (x86)/Java";
+  private static final String[] MAC_OS_JVM_LOCATIONS = {"/Library/Java/JavaVirtualMachines"};
+  private static final String[] LINUX_JVM_LOCATIONS = {"/usr/lib/jvm", "/usr/java"};
+
+  private static final String CONFIG_FILE_EXT =
+    (!SystemInfo.isWindows ? ".jdk" : SystemInfo.is64Bit ? "64.exe.jdk" : ".exe.jdk");
+
+  @Override
+  public void actionPerformed(@Nullable AnActionEvent e) {
+    Project project = e != null ? e.getProject() : null;
+    new Task.Modal(project, "Looking for Available JDKs", true) {
+      private JdkBundleList myBundleList;
+      private File myConfigFile;
+
+      @Override
+      public void run(@NotNull ProgressIndicator indicator) {
+        myBundleList = findJdkBundles(indicator);
+
+        String selector = PathManager.getPathsSelector();
+        File configDir = new File(selector != null ? PathManager.getDefaultConfigPathFor(selector) : PathManager.getConfigPath());
+        String exeName = System.getProperty("idea.executable");
+        if (exeName == null) exeName = ApplicationNamesInfo.getInstance().getProductName().toLowerCase(Locale.US);
+        myConfigFile = new File(configDir, exeName + CONFIG_FILE_EXT);
+      }
+
+      @Override
+      public void onSuccess() {
+        SwitchBootJdkDialog dialog = new SwitchBootJdkDialog(getProject(), myBundleList, myConfigFile.exists());
+        if (!dialog.showAndGet()) return;
+
+        try {
+          storeSelection(myConfigFile, dialog.getSelectedFile());
+        }
+        catch (IOException ex) {
+          LOG.error(ex);
+          String title = "Failed to store boot JDK selection";
+          String message = ex.getMessage();
+          Notifications.Bus.notify(new Notification(Notifications.SYSTEM_MESSAGES_GROUP_ID, title, message, NotificationType.ERROR), project);
+          return;
+        }
+
+        ApplicationManager.getApplication().invokeLater(() -> ApplicationManager.getApplication().restart(), ModalityState.NON_MODAL);
+      }
+    }.queue();
+  }
+
+  private static JdkBundleList findJdkBundles(@Nullable ProgressIndicator indicator) {
+    JdkBundleList bundleList = new JdkBundleList();
+
+    bundleList.addBundle(JdkBundle.createBoot());
+
+    JdkBundle bundledJdk = JdkBundle.createBundled();
+    if (bundledJdk != null && bundledJdk.isOperational()) {
+      bundleList.addBundle(bundledJdk);
+    }
+
+    String[] locations = ArrayUtil.EMPTY_STRING_ARRAY;
+    if (SystemInfo.isWindows) {
+      String dir = SystemInfo.is32Bit ? WINDOWS_X86_JVM_LOCATION : WINDOWS_X64_JVM_LOCATION;
+      locations = Stream.of(File.listRoots()).map(root -> new File(root, dir).getPath()).toArray(String[]::new);
+    }
+    else if (SystemInfo.isMac) {
+      locations = MAC_OS_JVM_LOCATIONS;
+    }
+    else if (SystemInfo.isLinux) {
+      locations = LINUX_JVM_LOCATIONS;
+    }
+    for (String location : locations) {
+      if (indicator != null) indicator.checkCanceled();
+      bundleList.addBundlesFromLocation(location, MIN_VERSION, MAX_VERSION);
+    }
+
+    return bundleList;
+  }
+
+  private static void storeSelection(File configFile, File selectedBundle) throws IOException {
+    if (selectedBundle != null) {
+      File configDir = configFile.getParentFile();
+      if (!(configDir.isDirectory() || configDir.mkdirs())) {
+        throw new IOException("Cannot create JDK config directory '" + configDir + "'");
+      }
+      try {
+        FileUtil.writeToFile(configFile, selectedBundle.getPath());
+      }
+      catch (IOException e) {
+        throw new IOException("Cannot write JDK config file '" + configFile + "': " + e.getMessage(), e);
+      }
+    }
+    else if (!FileUtil.delete(configFile)) {
+      throw new IOException("Cannot delete JDK config file '" + configFile + "'");
+    }
+  }
+
+  private static class SwitchBootJdkDialog extends DialogWrapper implements DataProvider, CopyProvider {
+    private static class JdkBundleItem {
+      private final JdkBundle bundle;
+      private JdkBundleItem(JdkBundle bundle) { this.bundle = bundle; }
+    }
+
+    private static final JdkBundleItem RESET = new JdkBundleItem(null);
+    private static final JdkBundleItem CREATE = new JdkBundleItem(null);
+
+    private static final Comparator<JdkBundle> BUNDLE_COMPARATOR = (b1, b2) -> {
+      /* boot first, then by version in a descending order */
+      if (b1.isBoot()) return -1;
+      if (b2.isBoot()) return 1;
+      int diff = b2.getBundleVersion().compareTo(b1.getBundleVersion());
+      if (diff != 0) return diff;
+      return b1.getLocation().getPath().compareTo(b2.getLocation().getPath());
+    };
+
+    private final JdkBundleList myPathsList;
+    private final DefaultComboBoxModel<JdkBundleItem> myModel;
+    private final ComboBox<JdkBundleItem> myComboBox;
+
+    private SwitchBootJdkDialog(Project project, JdkBundleList pathsList, boolean customConfig) {
+      super(project, true);
+
+      myPathsList = pathsList;
+
+      myModel = new DefaultComboBoxModel<>();
+      if (customConfig) {
+        myModel.addElement(RESET);
+      }
+      List<JdkBundle> bundles = new ArrayList<>(pathsList.getBundles());
+      bundles.sort(BUNDLE_COMPARATOR);
+      for (JdkBundle bundle : bundles) myModel.addElement(new JdkBundleItem(bundle));
+      myModel.addElement(CREATE);
+
+      myComboBox = new ComboBox<>(myModel);
+      myComboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
+      myComboBox.setRenderer(new JdkBundleItemRenderer());
+      myComboBox.addActionListener(e -> {
+        if (myComboBox.getSelectedItem() == CREATE) chooseBundle();
+        JdkBundleItem item = (JdkBundleItem)myComboBox.getSelectedItem();
+        setOKActionEnabled(item == RESET || item != null && item.bundle != null && !item.bundle.isBoot());
+      });
+
+      setTitle("Switch IDE Boot JDK");
+      setOKButtonText("Save and restart");
+      init();
+    }
+
+    private void chooseBundle() {
+      FileChooserDescriptor descriptor = new FileChooserDescriptor(false, true, false, false, false, false) {
+        private JdkBundle selectedBundle;
+
+        @Override
+        public boolean isFileSelectable(VirtualFile file) {
+          selectedBundle = null;
+          if (super.isFileSelectable(file)) {
+            JdkBundle bundle = JdkBundle.createBundle(new File(file.getPath()));
+            if (bundle != null) {
+              selectedBundle = bundle;
+              return true;
+            }
+          }
+          return false;
+        }
+
+        @Override
+        public void validateSelectedFiles(VirtualFile[] files) throws Exception {
+          super.validateSelectedFiles(files);
+          assert files.length == 1 : Arrays.toString(files);
+          if (selectedBundle == null) {
+            throw new Exception("Not a valid JDK bundle.");
+          }
+          if (selectedBundle.getBundleVersion().compareTo(MIN_VERSION) < 0) {
+            throw new Exception("JDK version mismatch (required: min " + MIN_VERSION + ", selected: " + selectedBundle.getBundleVersion() + ")");
+          }
+          Bitness arch = SystemInfo.is64Bit ? Bitness.x64 : Bitness.x32;
+          if (selectedBundle.getBitness() != arch) {
+            throw new Exception("JDK arch mismatch (required: " + arch + ", selected: " + selectedBundle.getBitness() + ")");
+          }
+        }
+      };
+
+      FileChooser.chooseFiles(descriptor, null, null, files -> {
+        if (files.size() == 1) {
+          File jdkFile = new File(files.get(0).getPath());
+          JdkBundle existing = myPathsList.getBundle(jdkFile.getPath());
+          if (existing != null) {
+            ComboBoxModel<JdkBundleItem> model = myComboBox.getModel();
+            for (int i = 0; i < model.getSize(); i++) {
+              if (model.getElementAt(i).bundle == existing) {
+                myComboBox.setSelectedIndex(i);
+                break;
+              }
+            }
+          }
+          else {
+            JdkBundle bundle = JdkBundle.createBundle(jdkFile);
+            if (bundle != null) {
+              myPathsList.addBundle(bundle);
+              JdkBundleItem item = new JdkBundleItem(bundle);
+              myModel.insertElementAt(item, myModel.getSize() - 1);
+              myComboBox.setSelectedItem(item);
+            }
+            else {
+              LOG.error("Cannot create bundle for path: " + jdkFile.getPath());
+            }
+          }
+        }
+      });
+    }
+
+    @Override
+    protected JComponent createNorthPanel() {
+      return new JBLabel("Select Boot JDK");
+    }
+
+    @Override
+    protected JComponent createCenterPanel() {
+      JPanel panel = new JPanel(new BorderLayout());
+      panel.add(myComboBox, BorderLayout.CENTER);
+      DefaultActionGroup group = new DefaultActionGroup(ActionManager.getInstance().getAction(IdeActions.ACTION_COPY));
+      ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar("SwitchBootJDKCopyAction", group, true);
+      toolbar.setReservePlaceAutoPopupIcon(false);
+      panel.add((Component)toolbar, BorderLayout.EAST);
+      return panel;
+    }
+
+    @Override
+    public JComponent getPreferredFocusedComponent() {
+      return myComboBox;
+    }
+
+    @Nullable
+    public File getSelectedFile() {
+      JdkBundleItem item = (JdkBundleItem)myComboBox.getSelectedItem();
+      return item != null && item.bundle != null ? item.bundle.getLocation() : null;
+    }
+
+    @Override
+    public void performCopy(@NotNull DataContext dataContext) {
+      File file = getSelectedFile();
+      if (file != null) {
+        CopyPasteManager.getInstance().setContents(new StringSelection(file.getAbsolutePath()));
+      }
+    }
+
+    @Override
+    public boolean isCopyEnabled(@NotNull DataContext dataContext) {
+      return getSelectedFile() != null;
+    }
+
+    @Override
+    public boolean isCopyVisible(@NotNull DataContext dataContext) {
+      return getSelectedFile() != null;
+    }
+
+    @Override
+    public Object getData(String dataId) {
+      return PlatformDataKeys.COPY_PROVIDER.is(dataId) ? this : null;
+    }
+
+    private static class JdkBundleItemRenderer extends ListCellRendererWrapper<JdkBundleItem> {
+      @Override
+      public void customize(JList list, JdkBundleItem value, int index, boolean selected, boolean hasFocus) {
+        if (value == RESET) {
+          setText("<reset to default>");
+        }
+        else if (value == CREATE) {
+          setText("...");
+        }
+        else if (value != null) {
+          StringBuilder sb = new StringBuilder();
+          sb.append('[').append(value.bundle.getBundleVersion());
+          if (value.bundle.isBoot()) sb.append(" boot");
+          if (value.bundle.isBundled()) sb.append(" bundled");
+          sb.append("] ").append(value.bundle.getLocation());
+          setText(sb.toString());
+          if (value.bundle.isBoot()) {
+            setForeground(JBColor.GREEN);
+          }
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
index 453b591bb1b1164cf3053de8f26dd1d762f113d3..1796b6e886930045799ea9982bb51834cc04b359 100644 (file)
@@ -66,7 +66,7 @@ public class ToggleFullScreenAction extends DumbAwareAction {
     Component focusOwner = IdeFocusManager.getGlobalInstance().getFocusOwner();
     if (focusOwner != null) {
       Window window = focusOwner instanceof JFrame ? (Window) focusOwner : SwingUtilities.getWindowAncestor(focusOwner);
-      if (!(window instanceof IdeFrameEx)) {
+      if (window != null && !(window instanceof IdeFrameEx)) {
         window = SwingUtilities.getWindowAncestor(window);
       }
       if (window instanceof IdeFrameEx) {
index 83bccd2cbcdbf291f7dd1d63d41e8c82e74bff3f..b64ec6e111861c533178564b36d8ff746c04d9cf 100644 (file)
@@ -1,18 +1,4 @@
-/*
- * Copyright 2000-2016 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.
- */
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.idea;
 
 import com.intellij.ExtensionPoints;
@@ -357,12 +343,12 @@ public class IdeaApplication {
         windowManager.showFrame();
       }
 
-      app.invokeLater(() -> {
-        if (mySplash != null) {
+      if (mySplash != null) {
+        app.invokeLater(() -> {
           mySplash.dispose();
           mySplash = null; // Allow GC collect the splash window
-        }
-      }, ModalityState.any());
+        }, ModalityState.any());
+      }
 
       TransactionGuard.submitTransaction(app, () -> {
         Project projectFromCommandLine = myPerformProjectLoad ? loadProjectFromExternalCommandLine(args) : null;
index 303e6f780fe58cb6ecfae46a4b43b748ee1d5ae2..a4a0cc2ad6eb87dc3d2f044a638dc597f8748f29 100644 (file)
@@ -5,6 +5,7 @@ import com.intellij.internal.statistic.beans.ConvertUsagesUtil;
 import com.intellij.internal.statistic.beans.GroupDescriptor;
 import com.intellij.internal.statistic.beans.UsageDescriptor;
 import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent;
+import com.intellij.internal.statistic.eventLog.FeatureUsageEventLogger;
 import com.intellij.openapi.components.*;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.xmlb.annotations.MapAnnotation;
@@ -33,6 +34,7 @@ public class UsageTrigger implements PersistentStateComponent<UsageTrigger.State
   private State myState = new State();
 
   public static void trigger(@NotNull @NonNls String feature) {
+    FeatureUsageEventLogger.INSTANCE.log("feature-usage-stats", feature);
     getInstance().doTrigger(feature);
   }
 
diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/actions/PersistFUStatisticsSessionAction.java b/platform/platform-impl/src/com/intellij/internal/statistic/actions/PersistFUStatisticsSessionAction.java
new file mode 100755 (executable)
index 0000000..65d09f0
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package com.intellij.internal.statistic.actions;
+
+import com.intellij.internal.statistic.service.fus.collectors.FUStatisticsPersistence;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ModalityState;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.Messages;
+import org.jetbrains.annotations.NotNull;
+
+public class PersistFUStatisticsSessionAction extends AnAction {
+
+  @Override
+  public void actionPerformed(@NotNull AnActionEvent e) {
+    final Project project = e.getProject();
+    if (project == null) {
+      return;
+    }
+
+    ProgressManager.getInstance().run(new Task.Backgroundable(project, "Persisting statistics session data", false) {
+      @Override
+      public void run(@NotNull ProgressIndicator indicator) {
+        String persistedInFile = FUStatisticsPersistence.persistProjectUsages(project);
+
+        String msg = persistedInFile == null ? "Session has NOT been persisted." : "Session has been persisted in file " + FUStatisticsPersistence.getStatisticsSystemCacheDirectory() + "\\" + persistedInFile;
+        ApplicationManager.getApplication().invokeLater(
+          () -> Messages.showMultilineInputDialog(project,  persistedInFile == null ? "ERROR" : "SUCCESSFULLY PERSISTED", "Statistics Session Persistence Result",
+                                                  msg,
+                                                null, null), ModalityState.NON_MODAL, project.getDisposed());
+      }
+    });
+  }
+}
@@ -1,20 +1,21 @@
 // Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.internal.statistic.customUsageCollectors.actions;
 
+import com.intellij.ide.actions.ActionsCollector;
 import com.intellij.internal.statistic.UsagesCollector;
 import com.intellij.internal.statistic.beans.ConvertUsagesUtil;
 import com.intellij.internal.statistic.beans.GroupDescriptor;
 import com.intellij.internal.statistic.beans.UsageDescriptor;
+import com.intellij.internal.statistic.eventLog.FeatureUsageEventLogger;
 import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent;
-import com.intellij.openapi.components.*;
+import com.intellij.openapi.components.PersistentStateComponent;
+import com.intellij.openapi.components.RoamingType;
+import com.intellij.openapi.components.State;
+import com.intellij.openapi.components.Storage;
 import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.xmlb.annotations.MapAnnotation;
-import com.intellij.util.xmlb.annotations.Tag;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import java.util.HashMap;
-import java.util.Map;
 import java.util.Set;
 
 /**
@@ -27,7 +28,7 @@ import java.util.Set;
     @Storage(value = "statistics.actions.xml", roamingType = RoamingType.DISABLED, deprecated = true)
   }
 )
-public class ActionsCollector implements PersistentStateComponent<ActionsCollector.State> {
+public class ActionsCollectorImpl extends ActionsCollector implements PersistentStateComponent<ActionsCollector.State> {
   public void record(String actionId) {
     if (actionId == null) return;
 
@@ -35,6 +36,7 @@ public class ActionsCollector implements PersistentStateComponent<ActionsCollect
     if (state == null) return;
 
     String key = ConvertUsagesUtil.escapeDescriptorName(actionId);
+    FeatureUsageEventLogger.INSTANCE.log("action-stats", key);
     final Integer count = state.myValues.get(key);
     int value = count == null ? 1 : count + 1;
     state.myValues.put(key, value);
@@ -52,16 +54,6 @@ public class ActionsCollector implements PersistentStateComponent<ActionsCollect
     myState = state;
   }
 
-  public static ActionsCollector getInstance() {
-    return ServiceManager.getService(ActionsCollector.class);
-  }
-
-  final static class State {
-    @Tag("counts")
-    @MapAnnotation(surroundWithTag = false, keyAttributeName = "action", valueAttributeName = "count")
-    public Map<String, Integer> myValues = new HashMap<>();
-  }
-
   final static class ActionUsagesCollector extends UsagesCollector {
     private static final GroupDescriptor GROUP = GroupDescriptor.create("Actions", GroupDescriptor.HIGHER_PRIORITY);
 
diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/eventLog/FeatureUsageEventLogger.kt b/platform/platform-impl/src/com/intellij/internal/statistic/eventLog/FeatureUsageEventLogger.kt
new file mode 100644 (file)
index 0000000..904de30
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+ */
+
+package com.intellij.internal.statistic.eventLog
+
+import com.intellij.openapi.application.ApplicationAdapter
+import com.intellij.openapi.application.ApplicationManager
+import com.intellij.openapi.application.PathManager
+import com.intellij.openapi.application.PermanentInstallationID
+import org.apache.log4j.Level
+import org.apache.log4j.Logger
+import org.apache.log4j.PatternLayout
+import org.apache.log4j.RollingFileAppender
+import java.io.File
+import java.io.IOException
+import java.nio.file.Paths
+import java.util.*
+
+object FeatureUsageEventLogger {
+  private val userId = PermanentInstallationID.get().shortedUUID()
+  private val sessionId = UUID.randomUUID().toString().shortedUUID()
+  private val eventLogger = if (ApplicationManager.getApplication().isInternal) createLogger() else null
+
+  private var lastEvent: LogEvent? = null
+  private var count: Int = 1
+
+  init {
+    ApplicationManager.getApplication().addApplicationListener(object : ApplicationAdapter() {
+      override fun applicationExiting() {
+        if (eventLogger != null) {
+          dispose(eventLogger)
+        }
+      }
+    })
+  }
+
+  private fun String.shortedUUID(): String {
+    val start = this.lastIndexOf('-')
+    if (start > 0 && start + 1 < this.length) {
+      return this.substring(start + 1)
+    }
+    return this
+  }
+
+  fun log(recorderId: String, action: String) {
+    if (eventLogger != null) {
+      log(eventLogger, LogEvent(recorderId, userId, sessionId, action))
+    }
+  }
+
+  private fun log(logger: Logger, event: LogEvent) {
+    if (lastEvent != null && lastEvent!!.shouldMerge(event)) {
+      lastEvent!!.endTimestamp = event.endTimestamp
+      count++
+    }
+    else {
+      logLastEvent(logger)
+      lastEvent = event
+    }
+  }
+
+  private fun dispose(logger: Logger) {
+    log(logger, LogEvent("feature-usage-stats", userId, sessionId, "ideaapp.closed"))
+    logLastEvent(logger)
+  }
+
+  private fun logLastEvent(logger: Logger) {
+    if (lastEvent != null) {
+      if (count > 1) {
+        lastEvent!!.data.put("count", count)
+      }
+      logger.info(LogEventSerializer.toString(lastEvent!!))
+    }
+    lastEvent = null
+    count = 1
+  }
+
+  private fun createLogger(): Logger? {
+    val path = Paths.get(PathManager.getSystemPath()).resolve("event-log").resolve("feature-usage.log")
+    val file = File(path.toUri())
+
+    val logger = Logger.getLogger("feature-usage-event-logger")
+    logger.level = Level.INFO
+    logger.additivity = false
+
+    val pattern = PatternLayout("%m\n")
+    try {
+      val fileAppender = RollingFileAppender(pattern, file.absolutePath)
+      fileAppender.setMaxFileSize("200KB")
+      fileAppender.maxBackupIndex = 10
+      logger.addAppender(fileAppender)
+    }
+    catch (e: IOException) {
+      System.err.println("Unable to initialize logging for feature usage: " + e.localizedMessage)
+    }
+    return logger
+  }
+}
diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/eventLog/LogEventSerializer.kt b/platform/platform-impl/src/com/intellij/internal/statistic/eventLog/LogEventSerializer.kt
new file mode 100644 (file)
index 0000000..40cbb77
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+ */
+package com.intellij.internal.statistic.eventLog
+
+import com.google.gson.Gson
+
+object LogEventSerializer {
+  private val bucket = -1
+  private val recorderVersion = 1
+
+  private val gson = Gson()
+
+  fun toString(event: LogEvent): String {
+    return "${event.timestamp}\t${event.recorderId}\t${recorderVersion}\t" +
+           "${event.userUid}\t${event.sessionUid}\t${event.actionType}\t${bucket}\t" +
+           gson.toJson(event.data)
+  }
+}
\ No newline at end of file
diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/eventLog/LogEvents.kt b/platform/platform-impl/src/com/intellij/internal/statistic/eventLog/LogEvents.kt
new file mode 100644 (file)
index 0000000..efebe3b
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+ */
+
+
+package com.intellij.internal.statistic.eventLog
+
+import com.intellij.util.containers.ContainerUtil
+
+open class LogEvent(@Transient var recorderId: String, @Transient var userUid: String, sessionId: String, type: String) {
+    @Transient val timestamp = System.currentTimeMillis()
+    @Transient var endTimestamp = System.currentTimeMillis()
+    @Transient val sessionUid: String = sessionId
+    @Transient val actionType: String = type
+    @Transient val data: MutableMap<String, Any> = ContainerUtil.newHashMap()
+
+    fun shouldMerge(next: LogEvent): Boolean {
+        if (next.timestamp - endTimestamp > 10000) return false
+        if (actionType != next.actionType) return false
+        if (recorderId != next.recorderId) return false
+        if (userUid != next.userUid) return false
+        if (sessionUid != next.sessionUid) return false
+        if (data != next.data) return false
+        return true
+    }
+}
\ No newline at end of file
index 7c30538ba07e5129a8e6bba4d87a40201661dc50..dd0ddec55cfd7210ddb7c914b83697c5ec21d85f 100755 (executable)
@@ -14,7 +14,7 @@ public abstract class ConfigurableStatisticsService<T extends StatisticsConnecti
   public final StatisticsResult send() {
     final String serviceUrl = getConnectionService().getServiceUrl();
     if (serviceUrl == null) {
-      return new StatisticsResult(StatisticsResult.ResultCode.ERROR_IN_CONFIG, "ERROR");
+      return new StatisticsResult(StatisticsResult.ResultCode.ERROR_IN_CONFIG, "ERROR: unknown Statistics Service URL.");
     }
 
     if (!getConnectionService().isTransmissionPermitted()) {
index 6c2acd258f2bef9ac2fd2167b553a67f019f650e..7507e3d5bb46d2d9d2ea05ad02bf27c6c34efa81 100755 (executable)
@@ -1,7 +1,6 @@
 // Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.internal.statistic.service.fus;
 
-import com.google.gson.Gson;
 import com.intellij.internal.statistic.connect.StatServiceException;
 import com.intellij.internal.statistic.service.ConfigurableStatisticsService;
 import com.intellij.internal.statistic.service.fus.beans.FSContent;
@@ -17,56 +16,63 @@ import org.apache.http.client.HttpClient;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.HttpClientBuilder;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.IOException;
 
 public class FUStatisticsService extends ConfigurableStatisticsService<FUStatisticsSettingsService> {
   private static final Logger LOG = Logger.getInstance("com.intellij.internal.statistic.service.whiteList.FUStatisticsService");
 
-  private static final FUStatisticsSettingsService myConnections = FUStatisticsSettingsService.getInstance();
+  private static final FUStatisticsSettingsService mySettingsService = FUStatisticsSettingsService.getInstance();
   private static final FUStatisticsAggregator myAggregator = FUStatisticsAggregator.create();
 
   @Override
   protected String sendData() {
-
-    String serviceUrl = myConnections.getServiceUrl();
+    String serviceUrl = mySettingsService.getServiceUrl();
     if (serviceUrl == null) return null;
 
-    FSContent gsonContent = myAggregator.getUsageCollectorsData(myConnections.getApprovedGroups());
-
+    FSContent gsonContent = myAggregator.getUsageCollectorsData(mySettingsService.getApprovedGroups());
     if (gsonContent == null) return null;
+
     try {
-      Gson gson = new Gson();
-      HttpClient httpClient = HttpClientBuilder.create().build();
-      String content = gson.toJson(gsonContent);
+      String content = gsonContent.asJsonString();
+      HttpResponse response = postStatistics(serviceUrl, content);
 
-      HttpPost post = new HttpPost(serviceUrl);
-      StringEntity postingString = new StringEntity(content);
-      post.setEntity(postingString);
-      post.setHeader("Content-type", "application/json");
-      HttpResponse response = httpClient.execute(post);
       if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
-        throw new StatServiceException("Error during data sending... Code: " + response.getStatusLine().getStatusCode());
+        String responseMessage = getResponseMessage(response);
+        LOG.info(responseMessage);
+        throw new StatServiceException("Error during data sending. \n " + responseMessage);
       }
-
       FUStatisticsPersistence.clearSessionPersistence(System.currentTimeMillis());
+      if (LOG.isDebugEnabled()) LOG.debug(getResponseMessage(response));
 
-      if (LOG.isDebugEnabled()) {
-        HttpEntity entity = response.getEntity();
-        if (entity != null) {
-          LOG.debug(StreamUtil.readText(entity.getContent(), CharsetToolkit.UTF8));
-        }
-      }
       return content;
+    }  catch (Exception e) {
+      LOG.info(e);
+      throw new StatServiceException("Error during data sending.", e);
     }
-    catch (StatServiceException e) {
-      throw e;
-    }
-    catch (Exception e) {
-      throw new StatServiceException("Error during data sending...", e);
+  }
+
+  private static HttpResponse postStatistics(String serviceUrl, String content) throws IOException {
+    HttpClient httpClient = HttpClientBuilder.create().build();
+    HttpPost post = new HttpPost(serviceUrl);
+    StringEntity postingString = new StringEntity(content);
+    post.setEntity(postingString);
+    post.setHeader("Content-type", "application/json");
+    return httpClient.execute(post);
+  }
+
+  @NotNull
+  private static String getResponseMessage(HttpResponse response) throws IOException {
+    HttpEntity entity = response.getEntity();
+    if (entity != null) {
+      return StreamUtil.readText(entity.getContent(), CharsetToolkit.UTF8);
     }
+    return Integer.toString(response.getStatusLine().getStatusCode());
   }
 
   @Override
   public FUStatisticsSettingsService getConnectionService() {
-    return myConnections;
+    return mySettingsService;
   }
 }
index 39df733732b198007a6200477fcc574149168ca5..d3f9cfaf75de82a7945242df95e3bff02b990679 100644 (file)
@@ -37,7 +37,7 @@ public class FUStatisticsWhiteListGroupsService {
                             .readString(null);
     }
     catch (IOException e) {
-      LOG.error(e);
+      LOG.info(e);
     }
     if (content == null) return Collections.emptySet();
 
@@ -46,7 +46,7 @@ public class FUStatisticsWhiteListGroupsService {
       groups = new GsonBuilder().create().fromJson(content, WLGroups.class);
     }
     catch (Exception e) {
-      LOG.error(e);
+      LOG.info(e);
     }
 
     return groups == null ? Collections.emptySet() :
index e1966cb0eb5dd3db5d155de0195a7e19946c4587..04aa6f7b8a95501c123f92d984068fd92944348f 100644 (file)
@@ -36,12 +36,12 @@ public class FUStatisticsPersistence {
   // 3.  method requests actual "approved" usages collectors (see FUStatisticsWhiteListGroupsService) to be invoked.
   //     if FUStatisticsWhiteListGroupsService is OFFLINE the data will NOT collected.
   // 4. collected data are persisted in system cache. one file for one project session. the session is pair: project + IJ build number
-  public static void persistProjectUsages(@NotNull Project project) {
+  public static String persistProjectUsages(@NotNull Project project) {
     Set<String> groups = FUStatisticsSettingsService.getInstance().getApprovedGroups();
-    if (groups.isEmpty()) return;
+    if (groups.isEmpty()) return null;
     FUStatisticsAggregator aggregator = FUStatisticsAggregator.create();
     Map<String, Set<UsageDescriptor>> usages = aggregator.getProjectUsages(project, groups);
-    if (usages.isEmpty()) return;
+    if (usages.isEmpty()) return null;
 
     FUSession fuSession = FUSession.create(project);
 
@@ -56,8 +56,9 @@ public class FUStatisticsPersistence {
     try {
       FileUtil.writeToFile(new File(directory, "/" + fileName), gsonContent);
     } catch (IOException e) {
-      LOG.error(e);
+      LOG.info(e);
     }
+    return fileName;
   }
 
   @NotNull
@@ -74,7 +75,7 @@ public class FUStatisticsPersistence {
               mergeContent(persistedSessions, FileUtil.loadFile(child));
             }
             catch (IOException e) {
-              LOG.error(e);
+              LOG.info(e);
             }
           }
         }
@@ -99,7 +100,7 @@ public class FUStatisticsPersistence {
               child.delete();
             }
           } catch (IOException e) {
-            LOG.error(e);
+            LOG.info(e);
           }
         }
       }
@@ -112,7 +113,7 @@ public class FUStatisticsPersistence {
   }
 
   @Nullable
-  private static File getStatisticsSystemCacheDirectory() {
+  public static File getStatisticsSystemCacheDirectory() {
     return Paths.get(PathManager.getSystemPath()).resolve(FUS_CACHE_PATH).toFile();
   }
 
@@ -126,7 +127,7 @@ public class FUStatisticsPersistence {
         allSessions.addAll(sessions);
       }
     }  catch (Exception e) {
-      LOG.error(e);
+      LOG.info(e);
     }
   }
 
index 3859aa224bcd8976c6a5f345b67fd4248ba1edaf..1e63cd988e14cf210b4c499b352a2633278e4082 100644 (file)
@@ -1,18 +1,4 @@
-/*
- * Copyright 2000-2017 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.
- */
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.openapi.actionSystem.impl;
 
 import com.intellij.AbstractBundle;
@@ -25,7 +11,7 @@ import com.intellij.ide.plugins.PluginManager;
 import com.intellij.ide.plugins.PluginManagerCore;
 import com.intellij.idea.IdeaLogger;
 import com.intellij.internal.statistic.customUsageCollectors.actions.ActionIdProvider;
-import com.intellij.internal.statistic.customUsageCollectors.actions.ActionsCollector;
+import com.intellij.internal.statistic.customUsageCollectors.actions.ActionsCollectorImpl;
 import com.intellij.openapi.Disposable;
 import com.intellij.openapi.actionSystem.*;
 import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
@@ -1176,7 +1162,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Disposab
       }
       //noinspection AssignmentToStaticFieldFromInstanceMethod
       IdeaLogger.ourLastActionId = myLastPreformedActionId;
-      ActionsCollector.getInstance().record(myLastPreformedActionId);
+      ActionsCollectorImpl.getInstance().record(myLastPreformedActionId);
     }
     for (AnActionListener listener : myActionListeners) {
       listener.beforeActionPerformed(action, dataContext, event);
index b570a420488f9d172662cdff6752203bb3bfe263..ecbece6d49c599342c6eb4c9be89b6ba0ff53676 100644 (file)
@@ -226,11 +226,13 @@ public class EncodingManagerImpl extends EncodingManager implements PersistentSt
   @Override
   @Nullable
   public Charset getEncoding(@Nullable VirtualFile virtualFile, boolean useParentDefaults) {
-    Project project = guessProject(virtualFile);
-    if (project == null) return null;
-    EncodingProjectManager encodingManager = EncodingProjectManager.getInstance(project);
-    if (encodingManager == null) return null; //tests
-    return encodingManager.getEncoding(virtualFile, useParentDefaults);
+    return ReadAction.compute(() -> {
+      Project project = guessProject(virtualFile);
+      if (project == null) return null;
+      EncodingProjectManager encodingManager = EncodingProjectManager.getInstance(project);
+      if (encodingManager == null) return null; //tests
+      return encodingManager.getEncoding(virtualFile, useParentDefaults);
+    });
   }
 
   public void clearDocumentQueue() {
index 73be9d05b6c0b6865e7f7c4d1bf03f91b5d3e9bb..1c8faf8e07484097f9fd6f2058e64cbe53130843 100644 (file)
@@ -15,7 +15,6 @@
  */
 package com.intellij.openapi.wm.impl.content;
 
-import com.intellij.openapi.wm.ToolWindow;
 import com.intellij.ui.Gray;
 import com.intellij.ui.content.Content;
 import com.intellij.util.ui.JBUI;
@@ -84,25 +83,24 @@ public class ContentComboLabel extends BaseLabel {
     return myUi == null || myUi.myWindow.isActive();
   }
 
+  @Override
+  public Dimension getMinimumSize() {
+    Dimension size = super.getMinimumSize();
+    if (!isMinimumSizeSet()) {
+      size.width = isToDrawCombo() ? myComboIcon.getIconWidth() : 0;
+      Icon icon = getIcon();
+      if (icon != null) size.width += icon.getIconWidth() + getIconTextGap();
+      Insets insets = getInsets();
+      if (insets != null) size.width += insets.left + insets.right;
+    }
+    return size;
+  }
+
   @Override
   public Dimension getPreferredSize() {
     Dimension size = super.getPreferredSize();
     if (!isPreferredSizeSet() && isToDrawCombo()) {
-      int gap = getIconTextGap();
-      Content content = getContent();
-      if (content != null) {
-        Font font = getFont();
-        String text = content.getDisplayName();
-        size.width = font == null || text == null || text.isEmpty() ? 0 : getFontMetrics(font).stringWidth(text);
-        if (Boolean.TRUE.equals(content.getUserData(ToolWindow.SHOW_CONTENT_ICON))) {
-          Icon icon = content.getIcon();
-          if (icon != null) size.width += gap + icon.getIconWidth();
-        }
-      }
-      if (size.width > 0) size.width += gap;
       size.width += myComboIcon.getIconWidth();
-      Insets insets = getInsets();
-      if (insets != null) size.width += insets.left + insets.right;
     }
     return size;
   }
index 635f8ebd8f30a2e7d9947c4a6fca6e54c1463410..017e32a9aaa05d49a4c9c413a5446fb503594287 100644 (file)
@@ -1,12 +1,10 @@
-/*
- * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
- */
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.openapi.wm.impl.status;
 
 import com.intellij.icons.AllIcons;
 import com.intellij.ide.PowerSaveMode;
+import com.intellij.ide.actions.ActionsCollector;
 import com.intellij.idea.ActionsBundle;
-import com.intellij.internal.statistic.customUsageCollectors.actions.ActionsCollector;
 import com.intellij.notification.EventLog;
 import com.intellij.openapi.Disposable;
 import com.intellij.openapi.actionSystem.ActionGroup;
index 14676abe939430f57723f7fbd78a12759cab6a2a..a2c4e201c9084e0375fd9145f9444e4ae2f6400d 100644 (file)
-/*
- * Copyright 2000-2017 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.
- */
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.util;
 
 import com.intellij.execution.ExecutionException;
 import com.intellij.execution.configurations.GeneralCommandLine;
+import com.intellij.execution.process.ProcessOutput;
 import com.intellij.execution.util.ExecUtil;
 import com.intellij.openapi.application.PathManager;
 import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.projectRoots.JdkUtil;
 import com.intellij.openapi.util.Bitness;
-import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.SystemInfo;
 import com.intellij.openapi.util.Version;
-import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.lang.JavaVersion;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.java.JdkVersionDetector;
+import org.jetbrains.jps.model.java.JdkVersionDetector.JdkVersionInfo;
 
 import java.io.File;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 public class JdkBundle {
-  @NotNull private static final Logger LOG = Logger.getInstance("#com.intellij.util.JdkBundle");
-
-  @NotNull
-  private static final Map<Pattern, Function<Matcher, Pair<Version, Integer>>> PROP_TO_VERSION_PATTERNS = ContainerUtil.newLinkedHashMap(
-    Pair.create(Pattern.compile("1\\.([\\d]+)\\.([\\d]+)_([\\d]+).*", Pattern.MULTILINE), matcher -> Pair.create(new Version(1, StringUtil.parseInt(matcher.group(1),0), StringUtil.parseInt(matcher.group(2),0)), StringUtil.parseInt(matcher.group(3),0))),
-    Pair.create(Pattern.compile("9\\.([\\d]+)\\.([\\d]+)_([\\d]+).*", Pattern.MULTILINE), matcher -> Pair.create(new Version(9, StringUtil.parseInt(matcher.group(1),0), StringUtil.parseInt(matcher.group(2),0)), StringUtil.parseInt(matcher.group(3),0))),
-    Pair.create(Pattern.compile("9-ea.*", Pattern.MULTILINE), matcher -> Pair.create(new Version(9, 0, 0), 0)),
-    Pair.create(Pattern.compile("9-internal.*", Pattern.MULTILINE), matcher -> Pair.create(new Version(9, 0, 0), 0)),
-    Pair.create(Pattern.compile("1\\.([\\d]+)\\.([\\d]+)_([\\d]+).*", Pattern.MULTILINE), matcher -> Pair.create(new Version(1, StringUtil.parseInt(matcher.group(1),0), StringUtil.parseInt(matcher.group(2),0)), StringUtil.parseInt(matcher.group(3),0))),
-    Pair.create(Pattern.compile("9-ea.*", Pattern.MULTILINE), matcher -> Pair.create(new Version(9, 0, 0), 0)),
-    Pair.create(Pattern.compile("([\\d]+)\\.([\\d]+)\\.?([\\d]*).*", Pattern.MULTILINE), matcher -> Pair.create(new Version(StringUtil.parseInt(matcher.group(1),0), StringUtil.parseInt(matcher.group(2),0), StringUtil.parseInt(matcher.group(3),0)), 0))
-  );
-
-  @NotNull
-  private static final Map<Pattern, Function<Matcher, Pair<Version, Integer>>> LINE_TO_VERSION_PATTERNS = ContainerUtil.newLinkedHashMap(
-    Pair.create(Pattern.compile("^java version \"1\\.([\\d]+)\\.([\\d]+)_([\\d]+).*\".*", Patte