diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.java index ead67d06880b..5aaeef0a53d5 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.java @@ -26,6 +26,7 @@ import com.intellij.ide.util.projectWizard.ModuleBuilder; import com.intellij.ide.util.projectWizard.ProjectBuilder; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.ModifiableModuleModel; import com.intellij.openapi.module.Module; @@ -54,7 +55,6 @@ import com.intellij.packaging.artifacts.Artifact; import com.intellij.packaging.artifacts.ModifiableArtifactModel; import com.intellij.projectImport.ProjectImportBuilder; import com.intellij.util.containers.ContainerUtil; -import java.util.HashMap; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -461,20 +461,22 @@ public class ModulesConfigurator implements ModulesProvider, ModuleEditor.Change if (result != Messages.YES) { return false; } - for (ModuleEditor editor : selectedEditors) { - myModuleEditors.remove(editor.getModule()); + WriteAction.run(() -> { + for (ModuleEditor editor : selectedEditors) { + myModuleEditors.remove(editor.getModule()); - final Module moduleToRemove = editor.getModule(); - // remove all dependencies on the module which is about to be removed - List modifiableRootModels = new ArrayList<>(); - for (final ModuleEditor moduleEditor : myModuleEditors.values()) { - final ModifiableRootModel modifiableRootModel = moduleEditor.getModifiableRootModelProxy(); - ContainerUtil.addIfNotNull(modifiableRootModels, modifiableRootModel); + final Module moduleToRemove = editor.getModule(); + // remove all dependencies on the module which is about to be removed + List modifiableRootModels = new ArrayList<>(); + for (final ModuleEditor moduleEditor : myModuleEditors.values()) { + final ModifiableRootModel modifiableRootModel = moduleEditor.getModifiableRootModelProxy(); + ContainerUtil.addIfNotNull(modifiableRootModels, modifiableRootModel); + } + + ModuleDeleteProvider.removeModule(moduleToRemove, modifiableRootModels, myModuleModel); + Disposer.dispose(editor); } - - ModuleDeleteProvider.removeModule(moduleToRemove, modifiableRootModels, myModuleModel); - Disposer.dispose(editor); - } + }); processModuleCountChanged(); return true; diff --git a/java/java-analysis-impl/src/com/intellij/refactoring/util/duplicates/ExtractedParameter.java b/java/java-analysis-impl/src/com/intellij/refactoring/util/duplicates/ExtractedParameter.java index 0a147154cdfa..26d9bbb67bc2 100644 --- a/java/java-analysis-impl/src/com/intellij/refactoring/util/duplicates/ExtractedParameter.java +++ b/java/java-analysis-impl/src/com/intellij/refactoring/util/duplicates/ExtractedParameter.java @@ -83,6 +83,7 @@ public class ExtractedParameter { if (myType instanceof PsiEllipsisType) { type = ((PsiEllipsisType)myType).toArrayType(); } + type = GenericsUtil.getVariableTypeByExpressionType(type); return type.getCanonicalText(); } diff --git a/java/java-impl/src/META-INF/JavaPlugin.xml b/java/java-impl/src/META-INF/JavaPlugin.xml index 432edb24fdbc..72b30bc467fb 100644 --- a/java/java-impl/src/META-INF/JavaPlugin.xml +++ b/java/java-impl/src/META-INF/JavaPlugin.xml @@ -410,6 +410,7 @@ bundle="messages.JavadocBundle"/> + diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaWordBoundaryFilter.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaWordBoundaryFilter.java new file mode 100644 index 000000000000..7c0fdf190bc7 --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaWordBoundaryFilter.java @@ -0,0 +1,15 @@ +// 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.editorActions; + +import com.intellij.openapi.editor.actions.WordBoundaryFilter; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.NotNull; + +public class JavaWordBoundaryFilter extends WordBoundaryFilter { + @Override + public boolean isWordBoundary(@NotNull IElementType previousTokenType, @NotNull IElementType tokenType) { + if (previousTokenType == JavaTokenType.GT && tokenType == JavaTokenType.EQ) return false; + return super.isWordBoundary(previousTokenType, tokenType); + } +} diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/AbstractExtractDialog.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/AbstractExtractDialog.java index c29422c47220..a5778c926994 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/AbstractExtractDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/AbstractExtractDialog.java @@ -36,4 +36,6 @@ public interface AbstractExtractDialog { boolean isOK(); default boolean isPreviewUsages() {return false;} + + default boolean showInTransaction() {return false;} } \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java index 69a6cef6b2d5..da8ea042b46d 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java @@ -697,4 +697,9 @@ public class ExtractMethodDialog extends RefactoringDialog implements AbstractEx public PsiType getReturnType() { return mySelector != null ? mySelector.getSelectedType() : myReturnType; } + + @Override + public boolean showInTransaction() { + return true; + } } diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java index 1566859ad581..14109821a9d0 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java @@ -16,6 +16,7 @@ import com.intellij.ide.DataManager; import com.intellij.ide.util.PropertiesComponent; import com.intellij.ide.util.PsiClassListCellRenderer; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.TransactionGuard; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; @@ -26,10 +27,7 @@ import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.Pass; -import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.WindowManager; @@ -577,10 +575,21 @@ public class ExtractMethodProcessor implements MatchProvider { public boolean showDialog(final boolean direct) { AbstractExtractDialog dialog = createExtractMethodDialog(direct); - dialog.show(); - if (!dialog.isOK()) return false; - apply(dialog); - return true; + Ref result = Ref.create(Boolean.FALSE); + Runnable showAndApply = () -> { + dialog.show(); + if (dialog.isOK()) { + apply(dialog); + result.set(Boolean.TRUE); + } + }; + if (dialog.showInTransaction()) { + TransactionGuard.getInstance().submitTransactionAndWait(showAndApply); + } + else { + showAndApply.run(); + } + return result.get(); } protected void apply(final AbstractExtractDialog dialog) { diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/JUnitRunConfigurationProperties.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/JUnitRunConfigurationProperties.groovy index dd2226cd76ab..cae8e15ccc26 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/JUnitRunConfigurationProperties.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/JUnitRunConfigurationProperties.groovy @@ -59,6 +59,11 @@ class JUnitRunConfigurationProperties { testClassPatterns = [] } + String forkMode = first(configuration.fork_mode)?.@value + if (forkMode != null && forkMode != "none") { + messages.error("Cannot run $file.name configuration: fork mode '$forkMode' is not supported") + } + List requiredArtifacts = first(configuration.method)?.option?. find { it.@name == "BuildArtifacts" && it.@enabled == "true" }?. diff --git a/platform/build-scripts/tests/testResources/org/jetbrains/intellij/build/runConfigurations/test_method_fork_mode.xml b/platform/build-scripts/tests/testResources/org/jetbrains/intellij/build/runConfigurations/test_method_fork_mode.xml new file mode 100644 index 000000000000..7f76a84608ca --- /dev/null +++ b/platform/build-scripts/tests/testResources/org/jetbrains/intellij/build/runConfigurations/test_method_fork_mode.xml @@ -0,0 +1,16 @@ + + + + + + + \ No newline at end of file diff --git a/platform/build-scripts/tests/testSrc/org/jetbrains/intellij/build/JUnitRunConfigurationPropertiesTest.kt b/platform/build-scripts/tests/testSrc/org/jetbrains/intellij/build/JUnitRunConfigurationPropertiesTest.kt index cafde3de0795..c296348aeb19 100644 --- a/platform/build-scripts/tests/testSrc/org/jetbrains/intellij/build/JUnitRunConfigurationPropertiesTest.kt +++ b/platform/build-scripts/tests/testSrc/org/jetbrains/intellij/build/JUnitRunConfigurationPropertiesTest.kt @@ -4,6 +4,7 @@ package org.jetbrains.intellij.build import com.intellij.util.io.URLUtil +import junit.framework.AssertionFailedError import org.jetbrains.intellij.build.impl.JUnitRunConfigurationProperties import org.junit.Assert.assertEquals import org.junit.Test @@ -40,6 +41,11 @@ class JUnitRunConfigurationPropertiesTest { assertEquals(emptyList(), properties.requiredArtifacts) } + @Test(expected = AssertionFailedError::class) + fun `load test with method fork mode`() { + loadRunConfiguration("test_method_fork_mode.xml") + } + private fun loadRunConfiguration(fileName: String): JUnitRunConfigurationProperties { val url = JUnitRunConfigurationPropertiesTest::class.java.getResource("runConfigurations/$fileName") return JUnitRunConfigurationProperties.loadRunConfiguration(URLUtil.urlToFile(url), MockBuildMessages()) diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/actions/LanguageWordBoundaryFilter.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/actions/LanguageWordBoundaryFilter.java new file mode 100644 index 000000000000..de0e9bccb94a --- /dev/null +++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/actions/LanguageWordBoundaryFilter.java @@ -0,0 +1,12 @@ +// 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.editor.actions; + +import com.intellij.lang.LanguageExtension; + +public class LanguageWordBoundaryFilter extends LanguageExtension { + public static final LanguageWordBoundaryFilter INSTANCE = new LanguageWordBoundaryFilter(); + + private LanguageWordBoundaryFilter() { + super("com.intellij.wordBoundaryFilter", new WordBoundaryFilter()); + } +} diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/actions/WordBoundaryFilter.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/actions/WordBoundaryFilter.java new file mode 100644 index 000000000000..e4bad4d45a81 --- /dev/null +++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/actions/WordBoundaryFilter.java @@ -0,0 +1,29 @@ +// 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.editor.actions; + +import com.intellij.openapi.editor.highlighter.EditorHighlighter; +import com.intellij.openapi.editor.highlighter.HighlighterIterator; +import com.intellij.openapi.util.Comparing; +import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.NotNull; + +/** + * Defines boundaries between language tokens which should be used as stops for next/prev-word caret movements. + *

+ * Currently it can be specified as a language-level extension (see {@link LanguageWordBoundaryFilter}). + */ +public class WordBoundaryFilter { + /** + * Given types of two distinct subsequent tokens returned by {@link HighlighterIterator#getTokenType()}, says whether a boundary + * between them should be recognized by 'Move Caret to Prev/Next Word' actions. + *

+ * Default implementation assumes a word boundary between any two distinct tokens. Override this method to adjust the logic to the + * specifics of particular programming language. + * + * @see HighlighterIterator + * @see EditorHighlighter + */ + public boolean isWordBoundary(@NotNull IElementType previousTokenType, @NotNull IElementType tokenType) { + return !Comparing.equal(previousTokenType, tokenType); + } +} diff --git a/platform/icons/src/providers/mariadb.png b/platform/icons/src/providers/mariadb.png index 9db86f6e87cb..38e47fb8d486 100644 Binary files a/platform/icons/src/providers/mariadb.png and b/platform/icons/src/providers/mariadb.png differ diff --git a/platform/icons/src/providers/mariadb@2x.png b/platform/icons/src/providers/mariadb@2x.png index ad2bef6d5dc4..25b652ab50da 100644 Binary files a/platform/icons/src/providers/mariadb@2x.png and b/platform/icons/src/providers/mariadb@2x.png differ diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java index 2ae270612cdb..2a15e7249a78 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java @@ -18,7 +18,7 @@ import com.intellij.codeInspection.SuppressIntentionActionFromFix; import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.featureStatistics.FeatureUsageTrackerImpl; import com.intellij.injected.editor.EditorWindow; -import com.intellij.internal.statistic.customUsageCollectors.actions.IntentionsCollector; +import com.intellij.internal.statistic.collectors.fus.actions.persistence.IntentionsCollector; import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.TransactionGuard; diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java index dd66211779b3..8ae73a1b6341 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java @@ -31,7 +31,7 @@ import com.intellij.ide.ui.search.OptionDescription; import com.intellij.ide.util.PropertiesComponent; import com.intellij.ide.util.gotoByName.*; import com.intellij.ide.util.treeView.smartTree.TreeElement; -import com.intellij.internal.statistic.customUsageCollectors.ui.ToolbarClicksCollector; +import com.intellij.internal.statistic.collectors.fus.ui.persistence.ToolbarClicksCollector; import com.intellij.lang.Language; import com.intellij.lang.LanguagePsiElementExternalizer; import com.intellij.navigation.ItemPresentation; diff --git a/platform/lang-impl/src/com/intellij/openapi/fileTypes/FileTypeUsagesCollector.java b/platform/lang-impl/src/com/intellij/openapi/fileTypes/FileTypeUsagesCollector.java deleted file mode 100644 index 41f27ece8df7..000000000000 --- a/platform/lang-impl/src/com/intellij/openapi/fileTypes/FileTypeUsagesCollector.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2000-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.openapi.fileTypes; - -import com.intellij.internal.statistic.AbstractProjectsUsagesCollector; -import com.intellij.internal.statistic.CollectUsagesException; -import com.intellij.internal.statistic.beans.GroupDescriptor; -import com.intellij.internal.statistic.beans.UsageDescriptor; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.project.Project; -import com.intellij.project.ProjectKt; -import com.intellij.psi.search.FileTypeIndex; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.util.NotNullFunction; -import com.intellij.util.containers.ContainerUtil; -import org.jetbrains.annotations.NotNull; - -import java.util.HashSet; -import java.util.Set; - -/** - * @author Nikolay Matveev - */ -public class FileTypeUsagesCollector extends AbstractProjectsUsagesCollector { - private static final String GROUP_ID = "file-type"; - - @NotNull - @Override - public GroupDescriptor getGroupId() { - return GroupDescriptor.create(GROUP_ID); - } - - @NotNull - @Override - public Set getProjectUsages(@NotNull final Project project) throws CollectUsagesException { - final Set usedFileTypes = new HashSet<>(); - final FileTypeManager fileTypeManager = FileTypeManager.getInstance(); - if (fileTypeManager == null) { - throw new CollectUsagesException("Cannot get instance of FileTypeManager"); - } - final FileType[] registeredFileTypes = fileTypeManager.getRegisteredFileTypes(); - for (final FileType fileType : registeredFileTypes) { - if (project.isDisposed()) { - throw new CollectUsagesException("Project is disposed"); - } - ApplicationManager.getApplication().runReadAction(() -> { - FileTypeIndex.processFiles(fileType, file -> { - //skip files from .idea directory otherwise 99% of projects would have XML and PLAIN_TEXT file types - if (!ProjectKt.getStateStore(project).isProjectFile(file)) { - usedFileTypes.add(fileType); - return false; - } - return true; - }, GlobalSearchScope.projectScope(project)); - }); - } - return ContainerUtil.map2Set(usedFileTypes, (NotNullFunction)fileType -> new UsageDescriptor(fileType.getName(), 1)); - } -} diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/NonPhysicalReferenceSearcher.java b/platform/lang-impl/src/com/intellij/psi/impl/search/NonPhysicalReferenceSearcher.java index f513bb9874ee..b33d7940a882 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/search/NonPhysicalReferenceSearcher.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/search/NonPhysicalReferenceSearcher.java @@ -51,9 +51,8 @@ public class NonPhysicalReferenceSearcher extends QueryExecutorBase EP_NAME = ExtensionPointName.create("com.intellij.statistics.usagesCollector"); diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ProductivityUsageCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ProductivityUsageCollector.java new file mode 100644 index 000000000000..b7d30e855cd4 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ProductivityUsageCollector.java @@ -0,0 +1,41 @@ +// 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.collectors.fus; + +import com.intellij.featureStatistics.FeatureDescriptor; +import com.intellij.featureStatistics.ProductivityFeaturesRegistry; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.service.fus.collectors.ApplicationUsagesCollector; +import com.intellij.internal.statistic.service.fus.collectors.FUStatisticsDifferenceSender; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +public class ProductivityUsageCollector extends ApplicationUsagesCollector implements FUStatisticsDifferenceSender { + + private static final String GROUP_ID = "statistics.productivity"; + @NotNull + @Override + public String getGroupId() { + return GROUP_ID; + } + + @NotNull + @Override + public Set getUsages() { + Set usages = ContainerUtil.newHashSet(); + + final ProductivityFeaturesRegistry registry = ProductivityFeaturesRegistry.getInstance(); + for (String featureId : registry.getFeatureIds()) { + final FeatureDescriptor featureDescriptor = registry.getFeatureDescriptor(featureId); + if (featureDescriptor != null) { + int count = featureDescriptor.getUsageCount(); + if (count > 0) { + usages.add(new UsageDescriptor(featureId, count)); + } + } + } + + return usages; + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/ActionUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/ActionUsagesCollector.java new file mode 100644 index 000000000000..f7f309577aad --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/ActionUsagesCollector.java @@ -0,0 +1,27 @@ +// 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.collectors.fus.actions; + +import com.intellij.ide.actions.ActionsCollector; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.service.fus.collectors.ApplicationUsagesCollector; +import com.intellij.internal.statistic.service.fus.collectors.FUStatisticsDifferenceSender; +import com.intellij.internal.statistic.service.fus.collectors.UsageDescriptorKeyValidator; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +public final class ActionUsagesCollector extends ApplicationUsagesCollector implements FUStatisticsDifferenceSender { + + @NotNull + public Set getUsages() { + ActionsCollector.State state = ActionsCollector.getInstance().getState(); + assert state != null; + return ContainerUtil.map2Set(state.myValues.entrySet(), e -> new UsageDescriptor(UsageDescriptorKeyValidator.ensureProperKey(e.getKey()), e.getValue())); + } + + @NotNull + public String getGroupId() { + return "statistics.actions.performed"; + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/IntentionUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/IntentionUsagesCollector.java new file mode 100644 index 000000000000..556c87069853 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/IntentionUsagesCollector.java @@ -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.internal.statistic.collectors.fus.actions; + +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.collectors.fus.actions.persistence.IntentionsCollector; +import com.intellij.internal.statistic.service.fus.collectors.ApplicationUsagesCollector; +import com.intellij.internal.statistic.service.fus.collectors.FUStatisticsDifferenceSender; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +import static com.intellij.internal.statistic.service.fus.collectors.UsageDescriptorKeyValidator.ensureProperKey; + +public final class IntentionUsagesCollector extends ApplicationUsagesCollector implements FUStatisticsDifferenceSender { + + @NotNull + public Set getUsages() { + IntentionsCollector.State state = IntentionsCollector.getInstance().getState(); + assert state != null; + return ContainerUtil.map2Set(state.myIntentions.entrySet(), e -> new UsageDescriptor(ensureProperKey(e.getKey()), e.getValue())); + } + + @NotNull + public String getGroupId() { + return "statistics.actions.intentions"; + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/MainMenuUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/MainMenuUsagesCollector.java new file mode 100644 index 000000000000..406e37b38bca --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/MainMenuUsagesCollector.java @@ -0,0 +1,31 @@ +// 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.collectors.fus.actions; + +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.collectors.fus.actions.persistence.MainMenuCollector; +import com.intellij.internal.statistic.service.fus.collectors.ApplicationUsagesCollector; +import com.intellij.internal.statistic.service.fus.collectors.FUStatisticsDifferenceSender; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +import static com.intellij.internal.statistic.service.fus.collectors.UsageDescriptorKeyValidator.ensureProperKey; + +public final class MainMenuUsagesCollector extends ApplicationUsagesCollector implements FUStatisticsDifferenceSender { + + @NotNull + public Set getUsages() { + MainMenuCollector.State state = MainMenuCollector.getInstance().getState(); + assert state != null; + return ContainerUtil.map2Set(state.myValues.entrySet(), e -> { + String key = e.getKey().replaceAll(" -> ", "-"); + return new UsageDescriptor(ensureProperKey(key), e.getValue()); + }); + } + + @NotNull + public String getGroupId() { + return "statistics.actions.main.menu"; + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/persistence/ActionIdProvider.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/persistence/ActionIdProvider.java new file mode 100644 index 000000000000..e2a41f2370e3 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/persistence/ActionIdProvider.java @@ -0,0 +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.collectors.fus.actions.persistence; + +public interface ActionIdProvider { + String getId(); +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/actions/ActionsCollectorImpl.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/persistence/ActionsCollectorImpl.java similarity index 52% rename from platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/actions/ActionsCollectorImpl.java rename to platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/persistence/ActionsCollectorImpl.java index d69bf4f09255..dc6e2a0df780 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/actions/ActionsCollectorImpl.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/persistence/ActionsCollectorImpl.java @@ -1,25 +1,17 @@ // 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; +package com.intellij.internal.statistic.collectors.fus.actions.persistence; 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.FeatureUsageLogger; import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent; -import com.intellij.internal.statistic.service.fus.collectors.ApplicationUsagesCollector; -import com.intellij.internal.statistic.service.fus.collectors.FUStatisticsDifferenceSender; 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 org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Set; - /** * @author Konstantin Bulenkov */ @@ -56,36 +48,4 @@ public class ActionsCollectorImpl extends ActionsCollector implements Persistent public void loadState(@NotNull State state) { myState = state; } - - @Deprecated // old statistics service format - final static class ActionUsagesCollector extends UsagesCollector { - private static final GroupDescriptor GROUP = GroupDescriptor.create("Actions", GroupDescriptor.HIGHER_PRIORITY); - - @NotNull - public Set getUsages() { - State state = getInstance().getState(); - assert state != null; - return ContainerUtil.map2Set(state.myValues.entrySet(), e -> new UsageDescriptor(e.getKey(), e.getValue())); - } - - @NotNull - public GroupDescriptor getGroupId() { - return GROUP; - } - } - - final static class ActionUsagesCollectorNew extends ApplicationUsagesCollector implements FUStatisticsDifferenceSender { - - @NotNull - public Set getUsages() { - State state = getInstance().getState(); - assert state != null; - return ContainerUtil.map2Set(state.myValues.entrySet(), e -> new UsageDescriptor(e.getKey(), e.getValue())); - } - - @NotNull - public String getGroupId() { - return "statistics.actions"; - } - } } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/actions/IntentionsCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/persistence/IntentionsCollector.java similarity index 80% rename from platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/actions/IntentionsCollector.java rename to platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/persistence/IntentionsCollector.java index 3adf9daf88fa..57c96561533a 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/actions/IntentionsCollector.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/persistence/IntentionsCollector.java @@ -1,18 +1,15 @@ // 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; +package com.intellij.internal.statistic.collectors.fus.actions.persistence; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInsight.intention.IntentionActionDelegate; import com.intellij.codeInspection.LocalQuickFix; import com.intellij.codeInspection.ex.QuickFixWrapper; import com.intellij.internal.statistic.UsagesCollector; -import com.intellij.internal.statistic.beans.GroupDescriptor; -import com.intellij.internal.statistic.beans.UsageDescriptor; import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent; import com.intellij.lang.Language; import com.intellij.openapi.components.*; import com.intellij.openapi.util.text.StringUtil; -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; @@ -89,26 +86,10 @@ public class IntentionsCollector implements PersistentStateComponent myIntentions = new HashMap<>(); } - - final static class IntentionUsagesCollector extends UsagesCollector { - private static final GroupDescriptor GROUP = GroupDescriptor.create("Intentions"); - - @NotNull - public Set getUsages() { - State state = getInstance().getState(); - assert state != null; - return ContainerUtil.map2Set(state.myIntentions.entrySet(), e -> new UsageDescriptor(e.getKey(), e.getValue())); - } - - @NotNull - public GroupDescriptor getGroupId() { - return GROUP; - } - } } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/actions/MainMenuCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/persistence/MainMenuCollector.java similarity index 83% rename from platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/actions/MainMenuCollector.java rename to platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/persistence/MainMenuCollector.java index de6486048172..4f876e4f2026 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/actions/MainMenuCollector.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/persistence/MainMenuCollector.java @@ -1,16 +1,13 @@ // 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; +package com.intellij.internal.statistic.collectors.fus.actions.persistence; 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.persistence.UsageStatisticsPersistenceComponent; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.impl.ActionMenu; import com.intellij.openapi.components.*; import com.intellij.openapi.util.text.StringUtil; -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; @@ -125,25 +122,9 @@ public class MainMenuCollector implements PersistentStateComponent myValues = new HashMap<>(); } - - final static class MainMenuUsagesCollector extends UsagesCollector { - private static final GroupDescriptor GROUP = GroupDescriptor.create("Main Menu", GroupDescriptor.HIGHER_PRIORITY); - - @NotNull - public Set getUsages() { - State state = getInstance().getState(); - assert state != null; - return ContainerUtil.map2Set(state.myValues.entrySet(), e -> new UsageDescriptor(e.getKey(), e.getValue())); - } - - @NotNull - public GroupDescriptor getGroupId() { - return GROUP; - } - } } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/fileTypes/FileTypeUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/fileTypes/FileTypeUsagesCollector.java new file mode 100644 index 000000000000..e432b4bb7a41 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/fileTypes/FileTypeUsagesCollector.java @@ -0,0 +1,63 @@ +// 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.collectors.fus.fileTypes; + +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.service.fus.collectors.ProjectUsagesCollector; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.project.Project; +import com.intellij.project.ProjectKt; +import com.intellij.psi.search.FileTypeIndex; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.NotNullFunction; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** + * @author Nikolay Matveev + */ +public class FileTypeUsagesCollector extends ProjectUsagesCollector { + @NotNull + @Override + public String getGroupId() { + return "statistics.file.types"; + } + + @NotNull + @Override + public Set getUsages(@NotNull final Project project) { + return getDescriptors(project); + } + + @NotNull + public static Set getDescriptors(@NotNull Project project) { + final Set usedFileTypes = new HashSet<>(); + final FileTypeManager fileTypeManager = FileTypeManager.getInstance(); + if (fileTypeManager == null) { + return Collections.emptySet(); + } + final FileType[] registeredFileTypes = fileTypeManager.getRegisteredFileTypes(); + for (final FileType fileType : registeredFileTypes) { + if (project.isDisposed()) { + return Collections.emptySet(); + } + ApplicationManager.getApplication().runReadAction(() -> { + FileTypeIndex.processFiles(fileType, file -> { + //skip files from .idea directory otherwise 99% of projects would have XML and PLAIN_TEXT file types + if (!ProjectKt.getStateStore(project).isProjectFile(file)) { + usedFileTypes.add(fileType); + return false; + } + return true; + }, GlobalSearchScope.projectScope(project)); + }); + } + return ContainerUtil + .map2Set(usedFileTypes, (NotNullFunction)fileType -> new UsageDescriptor(fileType.getName(), 1)); + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/jdk/JdkInfoUsageCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/jdk/JdkInfoUsageCollector.java new file mode 100644 index 000000000000..9777d32d85dc --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/jdk/JdkInfoUsageCollector.java @@ -0,0 +1,31 @@ +// 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.collectors.fus.jdk; + +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.service.fus.collectors.ApplicationUsagesCollector; +import com.intellij.util.lang.JavaVersion; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.Set; + +import static com.intellij.internal.statistic.service.fus.collectors.UsageDescriptorKeyValidator.ensureProperKey; + +/** + * @author Konstantin Bulenkov + */ +public class JdkInfoUsageCollector extends ApplicationUsagesCollector { + @NotNull + @Override + public Set getUsages() { + final String vendor = System.getProperty("java.vendor", "Unknown"); + final String version = "1." + JavaVersion.current().feature; + return Collections.singleton(new UsageDescriptor(ensureProperKey(vendor + "." + version), 1)); + } + + @NotNull + @Override + public String getGroupId() { + return "statistics.jdk.user"; + } +} \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/os/OsNameUsageCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/os/OsNameUsageCollector.java new file mode 100644 index 000000000000..cb1b2d8c6530 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/os/OsNameUsageCollector.java @@ -0,0 +1,27 @@ +// 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.collectors.fus.os; + +import com.google.common.collect.ImmutableSet; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.service.fus.collectors.ApplicationUsagesCollector; +import com.intellij.internal.statistic.service.fus.collectors.UsageDescriptorKeyValidator; +import com.intellij.openapi.util.SystemInfo; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.Set; + +import static com.intellij.internal.statistic.service.fus.collectors.UsageDescriptorKeyValidator.ensureProperKey; + +public class OsNameUsageCollector extends ApplicationUsagesCollector { + @NotNull + @Override + public Set getUsages() { + String osName = SystemInfo.isLinux ? "Linux" : SystemInfo.isMac ? "Mac.OS.X" : SystemInfo.isWindows ? "Windows" : SystemInfo.OS_NAME; + return ImmutableSet.of(new UsageDescriptor(ensureProperKey(osName), 1)); + } + + @NotNull + @Override + public String getGroupId() { return "statistics.os.name"; } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/os/OsVersionUsageCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/os/OsVersionUsageCollector.java new file mode 100644 index 000000000000..f574d30e5d39 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/os/OsVersionUsageCollector.java @@ -0,0 +1,68 @@ +// 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.collectors.fus.os; + +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.service.fus.collectors.ApplicationUsagesCollector; +import com.intellij.internal.statistic.service.fus.collectors.UsageDescriptorKeyValidator; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.Version; +import com.intellij.openapi.util.text.StringUtil; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +public class OsVersionUsageCollector extends ApplicationUsagesCollector { + @NotNull + @Override + public Set getUsages() { + return getDescriptors(); + } + + @NotNull + public static Set getDescriptors() { + UsageDescriptor descriptor; + + if (SystemInfo.isLinux) { + String releaseId = null, releaseVersion = null; + + try { + Map values = Files.lines(Paths.get("/etc/os-release")) + .map(line -> StringUtil.split(line, "=")) + .filter(parts -> parts.size() == 2) + .collect( + Collectors.toMap(parts -> parts.get(0), parts -> StringUtil.unquoteString(parts.get(1)))); + releaseId = values.get("ID"); + releaseVersion = values.get("VERSION_ID"); + } + catch (IOException ignored) { + } + + if (releaseId == null) releaseId = "unknown"; + + if (releaseVersion == null) { + releaseVersion = SystemInfo.OS_VERSION; + Version version = Version.parseVersion(releaseVersion); + if (version != null) { + releaseVersion = version.toCompactString(); + } + } + + descriptor = new UsageDescriptor("Linux/" + releaseId + " " + releaseVersion, 1); + } + else { + descriptor = new UsageDescriptor(UsageDescriptorKeyValidator.ensureProperKey(SystemInfo.OS_NAME + "." + SystemInfo.OS_VERSION), 1); + } + + return Collections.singleton(descriptor); + } + + @NotNull + @Override + public String getGroupId() { return "statistics.os.version"; } +} \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/plugins/DisabledPluginsUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/plugins/DisabledPluginsUsagesCollector.java new file mode 100644 index 000000000000..0bd8deec3fbe --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/plugins/DisabledPluginsUsagesCollector.java @@ -0,0 +1,23 @@ +// 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.collectors.fus.plugins; + +import com.intellij.ide.plugins.PluginManagerCore; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.service.fus.collectors.ApplicationUsagesCollector; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +public class DisabledPluginsUsagesCollector extends ApplicationUsagesCollector { + + @NotNull + public String getGroupId() { + return "statistics.plugins.disabled"; + } + + @NotNull + public Set getUsages() { + return ContainerUtil.map2Set(PluginManagerCore.getDisabledPlugins(), descriptor -> new UsageDescriptor(descriptor, 1)); + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/plugins/NonBundledPluginsUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/plugins/NonBundledPluginsUsagesCollector.java new file mode 100644 index 000000000000..fded088baad6 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/plugins/NonBundledPluginsUsagesCollector.java @@ -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.internal.statistic.collectors.fus.plugins; + +import com.intellij.ide.plugins.IdeaPluginDescriptor; +import com.intellij.ide.plugins.PluginManagerCore; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.service.fus.collectors.ApplicationUsagesCollector; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.Set; + +public class NonBundledPluginsUsagesCollector extends ApplicationUsagesCollector { + @NotNull + public String getGroupId() { + return "statistics.plugins.non.bundled"; + } + + @NotNull + public Set getUsages() { + final IdeaPluginDescriptor[] plugins = PluginManagerCore.getPlugins(); + final List nonBundledEnabledPlugins = ContainerUtil.filter(plugins, d -> d.isEnabled() && !d.isBundled() && d.getPluginId() != null); + + return ContainerUtil.map2Set(nonBundledEnabledPlugins, descriptor -> new UsageDescriptor(descriptor.getPluginId().getIdString(), 1)); + } + +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/A11YUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/A11YUsagesCollector.java new file mode 100644 index 000000000000..f398fd0b2e70 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/A11YUsagesCollector.java @@ -0,0 +1,31 @@ +// 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.collectors.fus.ui; + +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.service.fus.collectors.ApplicationUsagesCollector; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.util.ui.accessibility.ScreenReader; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.Set; + +/** + * @author tav + */ +public class A11YUsagesCollector extends ApplicationUsagesCollector { + @NotNull + @Override + public Set getUsages() { + String activity = ScreenReader.isActive() ? "ENABLED" : "DISABLED"; + String os = SystemInfo.isWindows ? "Windows" : SystemInfo.isLinux ? "Linux" : SystemInfo.isMac ? "Mac" : "Unknown OS"; + return Collections.singleton(new UsageDescriptor(os + ".screen.reader." + activity, 1)); + } + + @NotNull + @Override + public String getGroupId() { + return "statistics.ui.a11y.screen.reader"; + } +} + diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/colors/impl/EditorColorSchemesUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/EditorColorSchemesUsagesCollector.java similarity index 64% rename from platform/platform-impl/src/com/intellij/openapi/editor/colors/impl/EditorColorSchemesUsagesCollector.java rename to platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/EditorColorSchemesUsagesCollector.java index 7068e1b1f994..48b5f20c7d91 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/colors/impl/EditorColorSchemesUsagesCollector.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/EditorColorSchemesUsagesCollector.java @@ -1,26 +1,11 @@ -/* - * 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. - */ -package com.intellij.openapi.editor.colors.impl; +// 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.collectors.fus.ui; -import com.intellij.internal.statistic.CollectUsagesException; -import com.intellij.internal.statistic.UsagesCollector; -import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.service.fus.collectors.ApplicationUsagesCollector; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.colors.impl.AbstractColorsScheme; import com.intellij.openapi.options.SchemeManager; import com.intellij.ui.ColorUtil; import com.intellij.util.containers.ContainerUtil; @@ -30,7 +15,7 @@ import org.jetbrains.annotations.Nullable; import java.util.Set; -public class EditorColorSchemesUsagesCollector extends UsagesCollector { +public class EditorColorSchemesUsagesCollector extends ApplicationUsagesCollector { public static final String GROUP_ID = "Color Schemes"; public static final String SCHEME_NAME_OTHER = "Other"; @@ -53,7 +38,12 @@ public class EditorColorSchemesUsagesCollector extends UsagesCollector { @NotNull @Override - public Set getUsages() throws CollectUsagesException { + public Set getUsages() { + return getDescriptors(); + } + + @NotNull + public static Set getDescriptors() { EditorColorsScheme currentScheme = EditorColorsManager.getInstance().getGlobalScheme(); Set usages = ContainerUtil.newHashSet(); String schemeName = SCHEME_NAME_OTHER; @@ -71,7 +61,7 @@ public class EditorColorSchemesUsagesCollector extends UsagesCollector { schemeName = knownName; } boolean isDark = ColorUtil.isDark(currentScheme.getDefaultBackground()); - schemeName += " (" + (isDark ? "Dark" : "Light") + ")"; + schemeName += "[" + (isDark ? "Dark" : "Light") + "]"; } usages.add(new UsageDescriptor(schemeName, 1)); } @@ -90,8 +80,8 @@ public class EditorColorSchemesUsagesCollector extends UsagesCollector { @NotNull @Override - public GroupDescriptor getGroupId() { - return GroupDescriptor.create(GROUP_ID); + public String getGroupId() { + return "statistics.ui.editor.color.schemes"; } } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/FontSizeInfoUsageCollector.kt b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/FontSizeInfoUsageCollector.kt new file mode 100644 index 000000000000..00fa99163d6e --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/FontSizeInfoUsageCollector.kt @@ -0,0 +1,57 @@ +// 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.collectors.fus.ui + +import com.intellij.ide.ui.UISettings +import com.intellij.ide.util.PropertiesComponent +import com.intellij.internal.statistic.CollectUsagesException +import com.intellij.internal.statistic.beans.UsageDescriptor +import com.intellij.internal.statistic.service.fus.collectors.ApplicationUsagesCollector +import com.intellij.internal.statistic.service.fus.collectors.UsageDescriptorKeyValidator.ensureProperKey +import com.intellij.openapi.editor.colors.EditorColorsManager +import com.intellij.openapi.editor.colors.impl.AppEditorFontOptions + +/** + * @author Konstantin Bulenkov + */ +class FontSizeInfoUsageCollector : ApplicationUsagesCollector() { + @Throws(CollectUsagesException::class) + override fun getUsages(): Set { + val scheme = EditorColorsManager.getInstance().globalScheme + val ui = UISettings.shadowInstance + var usages = setOf( + UsageDescriptor("UI.font.size[${ui.fontSize}]"), + UsageDescriptor(ensureProperKey("UI.font.name[${ui.fontFace}]")), + UsageDescriptor("Presentation.mode.font.size[${ui.presentationModeFontSize}]") + ) + if (!scheme.isUseAppFontPreferencesInEditor) { + usages += setOf( + UsageDescriptor("Editor.font.size[${scheme.editorFontSize}]"), + UsageDescriptor(ensureProperKey("Editor.font.name[${scheme.editorFontName}]")) + ) + } + else { + val appPrefs = AppEditorFontOptions.getInstance().fontPreferences + usages += setOf( + UsageDescriptor("IDE.editor.font.size[${appPrefs.getSize(appPrefs.fontFamily)}]"), + UsageDescriptor(ensureProperKey("IDE.editor.font.name[${appPrefs.fontFamily}]")) + ) + } + if (!scheme.isUseEditorFontPreferencesInConsole) { + usages += setOf( + UsageDescriptor("Console.font.size[${scheme.consoleFontSize}]"), + UsageDescriptor(ensureProperKey("Console.font.name[${scheme.consoleFontName}]")) + ) + } + val quickDocFontSize = PropertiesComponent.getInstance().getValue("quick.doc.font.size") + if (quickDocFontSize != null) { + usages += setOf( + UsageDescriptor("QuickDoc.font.size[" + quickDocFontSize +"]") + ) + } + return usages + } + + override fun getGroupId(): String { + return "statistics.ui.fonts" + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/HiDPIModeUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/HiDPIModeUsagesCollector.java new file mode 100644 index 000000000000..fc253e814854 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/HiDPIModeUsagesCollector.java @@ -0,0 +1,30 @@ +// 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.collectors.fus.ui; + +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.service.fus.collectors.ApplicationUsagesCollector; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.Set; + +/** + * @author tav + */ +public class HiDPIModeUsagesCollector extends ApplicationUsagesCollector { + @NotNull + @Override + public Set getUsages() { + String mode = UIUtil.isJreHiDPIEnabled() ? "per_monitor_dpi" : "system_dpi"; + String os = SystemInfo.isWindows ? "Windows" : SystemInfo.isLinux ? "Linux" : SystemInfo.isMac ? "Mac" : "UnknownOS"; + return Collections.singleton(new UsageDescriptor(os + "." + mode, 1)); + } + + @NotNull + @Override + public String getGroupId() { + return "statistics.ui.hidpi.mode"; + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/LaFUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/LaFUsagesCollector.java new file mode 100644 index 000000000000..4ee86338eb40 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/LaFUsagesCollector.java @@ -0,0 +1,35 @@ +// 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.collectors.fus.ui; + +import com.intellij.ide.ui.LafManager; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.service.fus.collectors.ApplicationUsagesCollector; +import com.intellij.internal.statistic.service.fus.collectors.UsageDescriptorKeyValidator; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.text.StringUtil; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.util.Collections; +import java.util.Set; + +import static com.intellij.internal.statistic.service.fus.collectors.UsageDescriptorKeyValidator.ensureProperKey; + +public class LaFUsagesCollector extends ApplicationUsagesCollector { + @NotNull + @Override + public Set getUsages() { + UIManager.LookAndFeelInfo laf = LafManager.getInstance().getCurrentLookAndFeel(); + String key = SystemInfo.OS_NAME + "."; + if (!StringUtil.isEmptyOrSpaces(SystemInfo.SUN_DESKTOP)) { + key=key.replaceAll(" ", "_"); + key += SystemInfo.SUN_DESKTOP + "."; + } + return laf != null ? Collections.singleton(new UsageDescriptor(ensureProperKey(key + laf.getName()), 1)) + : Collections.emptySet(); + } + + @NotNull + @Override + public String getGroupId() { return "statistics.ui.look.and.feel"; } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/ScaleInfoUsageCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/ScaleInfoUsageCollector.java new file mode 100644 index 000000000000..b2ef3b9c82c8 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/ScaleInfoUsageCollector.java @@ -0,0 +1,44 @@ +// 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.collectors.fus.ui; + +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.service.fus.collectors.ApplicationUsagesCollector; +import com.intellij.util.ui.JBUI; +import org.jdesktop.swingx.util.OS; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.Set; + +/** + * @author tav + */ +public class ScaleInfoUsageCollector extends ApplicationUsagesCollector { + @NotNull + @Override + public Set getUsages() { + return getDescriptors(); + } + + @NotNull + public static Set getDescriptors() { + float scale = JBUI.sysScale(); + + int scaleBase = (int)Math.floor(scale); + float scaleFract = scale - scaleBase; + + if (scaleFract == 0.0f) scaleFract = 0.0f; // count integer scale on a precise match only + else if (scaleFract < 0.375f) scaleFract = 0.25f; + else if (scaleFract < 0.625f) scaleFract = 0.5f; + else scaleFract = 0.75f; + + scale = scaleBase + scaleFract; + + String os = OS.isWindows() ? "Windows" : OS.isLinux() ? "Linux" : OS.isMacOSX() ? "Mac" : "UnknownOS"; + return Collections.singleton(new UsageDescriptor(os + "_" + scale, 1)); + } + + @NotNull + @Override + public String getGroupId() { return "statistics.ui.screen.scale"; } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/ShortcutUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/ShortcutUsagesCollector.java new file mode 100644 index 000000000000..e9829d685d71 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/ShortcutUsagesCollector.java @@ -0,0 +1,36 @@ +// 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.collectors.fus.ui; + +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.collectors.fus.ui.persistence.ShortcutsCollector; +import com.intellij.internal.statistic.service.fus.collectors.ApplicationUsagesCollector; +import com.intellij.internal.statistic.service.fus.collectors.FUStatisticsDifferenceSender; +import com.intellij.internal.statistic.service.fus.collectors.UsageDescriptorKeyValidator; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +import static com.intellij.internal.statistic.service.fus.collectors.UsageDescriptorKeyValidator.*; + +public final class ShortcutUsagesCollector extends ApplicationUsagesCollector implements FUStatisticsDifferenceSender { + + private static String getGroupName() { + if (SystemInfo.isMac) return "statistics.ui.shortcuts.on.mac"; + if (SystemInfo.isWindows) return "statistics.ui.shortcuts.on.windows"; + if (SystemInfo.isLinux) return "statistics.ui.shortcuts.on.linux"; + return "statistics.ui.shortcuts.on.other.os"; + } + + @NotNull + public Set getUsages() { + ShortcutsCollector.MyState state = ShortcutsCollector.getInstance().getState(); + return ContainerUtil.map2Set(state.myValues.entrySet(), e -> new UsageDescriptor(ensureProperKey(e.getKey()), e.getValue())); + } + + @NotNull + public String getGroupId() { + return getGroupName(); + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/ToolbarClicksUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/ToolbarClicksUsagesCollector.java new file mode 100644 index 000000000000..8a28d93cff3f --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/ToolbarClicksUsagesCollector.java @@ -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.internal.statistic.collectors.fus.ui; + +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.collectors.fus.ui.persistence.ToolbarClicksCollector; +import com.intellij.internal.statistic.service.fus.collectors.ApplicationUsagesCollector; +import com.intellij.internal.statistic.service.fus.collectors.FUStatisticsDifferenceSender; +import com.intellij.internal.statistic.service.fus.collectors.UsageDescriptorKeyValidator; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +import static com.intellij.internal.statistic.service.fus.collectors.UsageDescriptorKeyValidator.*; + +public final class ToolbarClicksUsagesCollector extends ApplicationUsagesCollector implements FUStatisticsDifferenceSender { + @NotNull + public Set getUsages() { + ToolbarClicksCollector.ClicksState state = ToolbarClicksCollector.getInstance().getState(); + assert state != null; + return ContainerUtil.map2Set(state.myValues.entrySet(), e -> new UsageDescriptor(ensureProperKey(e.getKey()), e.getValue())); + } + + @NotNull + public String getGroupId() { + return "statistics.ui.toolbar.clicks"; + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/UiInfoUsageCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/UiInfoUsageCollector.java new file mode 100644 index 000000000000..1b0652b682ed --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/UiInfoUsageCollector.java @@ -0,0 +1,96 @@ +// 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.collectors.fus.ui; + +import com.intellij.ide.GeneralSettings; +import com.intellij.ide.ui.UISettings; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.service.fus.collectors.ApplicationUsagesCollector; +import com.intellij.openapi.editor.ex.EditorSettingsExternalizable; +import com.intellij.util.ui.UIUtil; +import gnu.trove.THashSet; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.util.Set; + +import static com.intellij.internal.statistic.utils.StatisticsUtilKt.getBooleanUsage; + +/** + * @author Konstantin Bulenkov + */ +public class UiInfoUsageCollector extends ApplicationUsagesCollector { + + @NotNull + @Override + public Set getUsages() { + return getDescriptors(); + } + + @NotNull + public static Set getDescriptors() { + Set set = new THashSet<>(); + + add(set, "Nav.Bar.visible", navbar() ? 1 : 0); + add(set, "Nav.Bar.floating", navbar() ? 0 : 1); + add(set, "Toolbar.visible", toolbar() ? 1 : 0); + add(set, "Toolbar.hidden", toolbar() ? 0 : 1); + add(set, "Toolbar.and.NavBar", !toolbar() && navbar() ? 1 : 0); + add(set, "Toolbar.and.NavBar.hidden", !toolbar() && !navbar() ? 1 : 0); + add(set, "Status.bar.visible", status() ? 1 : 0); + add(set, "Status.bar.hidden", status() ? 0 : 1); + add(set, "Tool.Window.buttons.visible", stripes() ? 1 : 0); + add(set, "Tool.Window.buttons.hidden", stripes() ? 0 : 1); + add(set, "Recent.Files[15]", recent() == 15 ? 1 : 0); + add(set, "Recent.Files[15_30]", 15 < recent() && recent() < 31 ? 1 : 0); + add(set, "Recent.Files[30_50]", 30 < recent() && recent() < 51 ? 1 : 0); + add(set, "Recent.Files[more.than.50]", 50 < recent() ? 1 : 0); + add(set, "Block.cursor", EditorSettingsExternalizable.getInstance().isBlockCursor() ? 1 : 0); + add(set, "Line.Numbers", EditorSettingsExternalizable.getInstance().isLineNumbersShown() ? 1 : 0); + add(set, "Gutter.Icons", EditorSettingsExternalizable.getInstance().areGutterIconsShown() ? 1 : 0); + add(set, "Soft.Wraps", EditorSettingsExternalizable.getInstance().isUseSoftWraps() ? 1 : 0); + add(set, "Tabs.None", tabPlace() == 0 ? 1 : 0); + add(set, "Tabs.Top", tabPlace() == SwingConstants.TOP ? 1 : 0); + add(set, "Tabs.Bottom", tabPlace() == SwingConstants.BOTTOM ? 1 : 0); + add(set, "Tabs.Left", tabPlace() == SwingConstants.LEFT ? 1 : 0); + add(set, "Tabs.Right", tabPlace() == SwingConstants.RIGHT ? 1 : 0); + add(set, "Retina", UIUtil.isRetina() ? 1 : 0); + add(set, "Show.tips.on.startup", GeneralSettings.getInstance().isShowTipsOnStartup() ? 1 : 0); + set.add(getBooleanUsage("Allow.merging.buttons", UISettings.getInstance().getAllowMergeButtons())); + + return set; + } + + @NotNull + @Override + public String getGroupId() { + return "statistics.ui.info.features"; + } + + private static void add(Set set, String key, int value) { + set.add(new UsageDescriptor(key, value)); + } + + private static int tabPlace() { + return UISettings.getInstance().getEditorTabPlacement(); + } + + private static int recent() { + return UISettings.getInstance().getRecentFilesLimit(); + } + + private static boolean stripes() { + return UISettings.getInstance().getHideToolStripes(); + } + + private static boolean status() { + return UISettings.getInstance().getShowStatusBar(); + } + + private static boolean toolbar() { + return UISettings.getInstance().getShowMainToolbar(); + } + + private static boolean navbar() { + return UISettings.getInstance().getShowNavigationBar(); + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/ShortcutsCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/persistence/ShortcutsCollector.java similarity index 90% rename from platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/ShortcutsCollector.java rename to platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/persistence/ShortcutsCollector.java index 9442e93b3462..6c0fbc5c8dc1 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/ShortcutsCollector.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/persistence/ShortcutsCollector.java @@ -1,15 +1,11 @@ // 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.ui; +package com.intellij.internal.statistic.collectors.fus.ui.persistence; -import com.intellij.internal.statistic.UsagesCollector; -import com.intellij.internal.statistic.beans.GroupDescriptor; -import com.intellij.internal.statistic.beans.UsageDescriptor; import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.KeyboardShortcut; import com.intellij.openapi.components.*; import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.xmlb.annotations.MapAnnotation; @@ -19,7 +15,10 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import static java.awt.event.InputEvent.ALT_GRAPH_MASK; @@ -41,7 +40,7 @@ import static java.awt.event.KeyEvent.*; } ) public class ShortcutsCollector implements PersistentStateComponent { - final static class MyState { + public final static class MyState { @Tag("counts") @MapAnnotation(surroundWithTag = false, keyAttributeName = "shortcut", valueAttributeName = "count") public final Map myValues = new HashMap<>(); @@ -104,32 +103,10 @@ public class ShortcutsCollector implements PersistentStateComponent getUsages() { - MyState state = getInstance().getState(); - return ContainerUtil.map2Set(state.myValues.entrySet(), e -> new UsageDescriptor(e.getKey(), e.getValue())); - } - - @NotNull - public GroupDescriptor getGroupId() { - return GROUP; - } - } - private static String getLocaleUnawareKeyText(int keyCode) { if (keyCode >= VK_0 && keyCode <= VK_9 || keyCode >= VK_A && keyCode <= VK_Z) { diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/ToolbarClicksCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/persistence/ToolbarClicksCollector.java similarity index 71% rename from platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/ToolbarClicksCollector.java rename to platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/persistence/ToolbarClicksCollector.java index d86bf4d1d194..add4544f4210 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/ToolbarClicksCollector.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/persistence/ToolbarClicksCollector.java @@ -1,23 +1,18 @@ // 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.ui; +package com.intellij.internal.statistic.collectors.fus.ui.persistence; -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.persistence.UsageStatisticsPersistenceComponent; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.ActionWithDelegate; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.components.*; -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 java.util.HashMap; import java.util.Map; -import java.util.Set; /** * @author Konstantin Bulenkov @@ -30,7 +25,7 @@ import java.util.Set; } ) public class ToolbarClicksCollector implements PersistentStateComponent { - final static class ClicksState { + public final static class ClicksState { @Tag("counts") @MapAnnotation(surroundWithTag = false, keyAttributeName = "action", valueAttributeName = "count") public Map myValues = new HashMap<>(); @@ -71,23 +66,7 @@ public class ToolbarClicksCollector implements PersistentStateComponent getUsages() { - ClicksState state = getInstance().getState(); - assert state != null; - return ContainerUtil.map2Set(state.myValues.entrySet(), e -> new UsageDescriptor(e.getKey(), e.getValue())); - } - - @NotNull - public GroupDescriptor getGroupId() { - return GROUP; - } - } -} +} \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ExperimentalFeaturesUsageCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ExperimentalFeaturesUsageCollector.java similarity index 86% rename from platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ExperimentalFeaturesUsageCollector.java rename to platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ExperimentalFeaturesUsageCollector.java index 34fa28da0ab8..48086cb59dad 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ExperimentalFeaturesUsageCollector.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ExperimentalFeaturesUsageCollector.java @@ -1,5 +1,5 @@ -// 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. -package com.intellij.internal.statistic.customUsageCollectors; +// 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.collectors.legacy; import com.intellij.internal.statistic.UsagesCollector; import com.intellij.internal.statistic.beans.GroupDescriptor; @@ -14,6 +14,7 @@ import java.util.stream.Collectors; /** * @author Konstantin Bulenkov */ +@Deprecated // to be removed in 2018.2 public class ExperimentalFeaturesUsageCollector extends UsagesCollector { private static final GroupDescriptor GROUP_ID = GroupDescriptor.create("Experimental Features"); diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/RegistryUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/LegacyRegistryUsagesCollector.java similarity index 79% rename from platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/RegistryUsagesCollector.java rename to platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/LegacyRegistryUsagesCollector.java index 3d255486f2f4..12eb3c0d2c67 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/RegistryUsagesCollector.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/LegacyRegistryUsagesCollector.java @@ -1,5 +1,5 @@ -// 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. -package com.intellij.internal.statistic.customUsageCollectors; +// 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.collectors.legacy; import com.intellij.internal.statistic.UsagesCollector; import com.intellij.internal.statistic.beans.GroupDescriptor; @@ -13,7 +13,8 @@ import java.util.stream.Collectors; /** * @author Konstantin Bulenkov */ -public class RegistryUsagesCollector extends UsagesCollector { +@Deprecated // to be removed in 2018.2 +public class LegacyRegistryUsagesCollector extends UsagesCollector { private static final GroupDescriptor GROUP_ID = GroupDescriptor.create("Registry"); @NotNull diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/actions/LegacyActionUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/actions/LegacyActionUsagesCollector.java new file mode 100644 index 000000000000..279181c432f5 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/actions/LegacyActionUsagesCollector.java @@ -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.internal.statistic.collectors.legacy.actions; + +import com.intellij.ide.actions.ActionsCollector; +import com.intellij.internal.statistic.UsagesCollector; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +@Deprecated // old statistics service format +public final class LegacyActionUsagesCollector extends UsagesCollector { + private static final GroupDescriptor GROUP = GroupDescriptor.create("Actions", GroupDescriptor.HIGHER_PRIORITY); + + @NotNull + public Set getUsages() { + ActionsCollector.State state = ActionsCollector.getInstance().getState(); + assert state != null; + return ContainerUtil.map2Set(state.myValues.entrySet(), e -> new UsageDescriptor(e.getKey(), e.getValue())); + } + + @NotNull + public GroupDescriptor getGroupId() { + return GROUP; + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/actions/LegacyIntentionUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/actions/LegacyIntentionUsagesCollector.java new file mode 100644 index 000000000000..a5d3c10be3c8 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/actions/LegacyIntentionUsagesCollector.java @@ -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.internal.statistic.collectors.legacy.actions; + +import com.intellij.internal.statistic.UsagesCollector; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.collectors.fus.actions.persistence.IntentionsCollector; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +@Deprecated // to be removed in 2018.2 +public final class LegacyIntentionUsagesCollector extends UsagesCollector { + private static final GroupDescriptor GROUP = GroupDescriptor.create("Intentions"); + + @NotNull + public Set getUsages() { + IntentionsCollector.State state = IntentionsCollector.getInstance().getState(); + assert state != null; + return ContainerUtil.map2Set(state.myIntentions.entrySet(), e -> new UsageDescriptor(e.getKey(), e.getValue())); + } + + @NotNull + public GroupDescriptor getGroupId() { + return GROUP; + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/actions/LegacyMainMenuUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/actions/LegacyMainMenuUsagesCollector.java new file mode 100644 index 000000000000..33c33fd6c367 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/actions/LegacyMainMenuUsagesCollector.java @@ -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.internal.statistic.collectors.legacy.actions; + +import com.intellij.internal.statistic.UsagesCollector; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.collectors.fus.actions.persistence.MainMenuCollector; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +@Deprecated // to be removed in 2018.2 +public final class LegacyMainMenuUsagesCollector extends UsagesCollector { + private static final GroupDescriptor GROUP = GroupDescriptor.create("Main Menu", GroupDescriptor.HIGHER_PRIORITY); + + @NotNull + public Set getUsages() { + MainMenuCollector.State state = MainMenuCollector.getInstance().getState(); + assert state != null; + return ContainerUtil.map2Set(state.myValues.entrySet(), e -> new UsageDescriptor(e.getKey(), e.getValue())); + } + + @NotNull + public GroupDescriptor getGroupId() { + return GROUP; + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/build/BuildNumberUsageCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/build/BuildNumberUsageCollector.java similarity index 55% rename from platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/build/BuildNumberUsageCollector.java rename to platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/build/BuildNumberUsageCollector.java index 3af8f07cabf6..f950a54cca15 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/build/BuildNumberUsageCollector.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/build/BuildNumberUsageCollector.java @@ -1,19 +1,5 @@ -/* - * 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. - */ -package com.intellij.internal.statistic.customUsageCollectors.build; +// 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.collectors.legacy.build; import com.intellij.internal.statistic.CollectUsagesException; import com.intellij.internal.statistic.UsagesCollector; @@ -28,6 +14,7 @@ import java.util.Set; /** * @author Ivan Chirkov */ +@Deprecated // to be removed in 2018.2 public class BuildNumberUsageCollector extends UsagesCollector { @NotNull @Override diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/fileTypes/LegacyFileTypeUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/fileTypes/LegacyFileTypeUsagesCollector.java new file mode 100644 index 000000000000..6979dc29f3ad --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/fileTypes/LegacyFileTypeUsagesCollector.java @@ -0,0 +1,31 @@ +// 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.collectors.legacy.fileTypes; + +import com.intellij.internal.statistic.AbstractProjectsUsagesCollector; +import com.intellij.internal.statistic.CollectUsagesException; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.collectors.fus.fileTypes.FileTypeUsagesCollector; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +/** + * @author Nikolay Matveev + */ +public class LegacyFileTypeUsagesCollector extends AbstractProjectsUsagesCollector { + private static final String GROUP_ID = "file-type"; + + @NotNull + @Override + public GroupDescriptor getGroupId() { + return GroupDescriptor.create(GROUP_ID); + } + + @NotNull + @Override + public Set getProjectUsages(@NotNull final Project project) throws CollectUsagesException { + return FileTypeUsagesCollector.getDescriptors(project); + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ideSettings/IdeInitialConfigButtonUsages.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ideSettings/IdeInitialConfigButtonUsages.java similarity index 78% rename from platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ideSettings/IdeInitialConfigButtonUsages.java rename to platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ideSettings/IdeInitialConfigButtonUsages.java index 04160ca96a09..228b3668e8a1 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ideSettings/IdeInitialConfigButtonUsages.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ideSettings/IdeInitialConfigButtonUsages.java @@ -1,19 +1,5 @@ -/* - * 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. - */ -package com.intellij.internal.statistic.customUsageCollectors.ideSettings; +// 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.collectors.legacy.ideSettings; import javax.swing.*; import java.util.Collections; diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ideSettings/IdeInitialConfigUsageCollectors.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ideSettings/IdeInitialConfigUsageCollectors.java similarity index 82% rename from platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ideSettings/IdeInitialConfigUsageCollectors.java rename to platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ideSettings/IdeInitialConfigUsageCollectors.java index d1aaccd9ab82..9bd1b78576af 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ideSettings/IdeInitialConfigUsageCollectors.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ideSettings/IdeInitialConfigUsageCollectors.java @@ -1,19 +1,5 @@ -/* - * 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. - */ -package com.intellij.internal.statistic.customUsageCollectors.ideSettings; +// 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.collectors.legacy.ideSettings; import com.intellij.ide.WelcomeWizardUtil; import com.intellij.internal.statistic.CollectUsagesException; @@ -28,7 +14,7 @@ import java.util.Collections; import java.util.Set; import java.util.stream.Collectors; -import static com.intellij.internal.statistic.customUsageCollectors.ideSettings.IdeInitialConfigButtonUsages.*; +import static com.intellij.internal.statistic.collectors.legacy.ideSettings.IdeInitialConfigButtonUsages.*; public final class IdeInitialConfigUsageCollectors { public static class ConfigImport extends Base { diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/jdk/JdkSettingsUsageCollector.kt b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/jdk/JdkSettingsUsageCollector.kt similarity index 78% rename from platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/jdk/JdkSettingsUsageCollector.kt rename to platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/jdk/JdkSettingsUsageCollector.kt index 38198cb3c146..4eb1eed1b35b 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/jdk/JdkSettingsUsageCollector.kt +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/jdk/JdkSettingsUsageCollector.kt @@ -1,19 +1,5 @@ -/* - * 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. - */ -package com.intellij.internal.statistic.customUsageCollectors.jdk +// 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.collectors.legacy.jdk import com.intellij.internal.statistic.UsagesCollector import com.intellij.internal.statistic.beans.GroupDescriptor @@ -24,6 +10,7 @@ import java.util.function.Function /** * @author Konstantin Bulenkov */ +@Deprecated("") // to be removed in 2018.2 class JdkSettingsUsageCollector : UsagesCollector() { override fun getUsages(): Set { return ManagementFactory.getRuntimeMXBean().inputArguments diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/jdk/JdkInfoUsageCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/jdk/LegacyJdkInfoUsageCollector.java similarity index 84% rename from platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/jdk/JdkInfoUsageCollector.java rename to platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/jdk/LegacyJdkInfoUsageCollector.java index 564aa070249c..1d6f1e0b068b 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/jdk/JdkInfoUsageCollector.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/jdk/LegacyJdkInfoUsageCollector.java @@ -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.internal.statistic.customUsageCollectors.jdk; +package com.intellij.internal.statistic.collectors.legacy.jdk; import com.intellij.internal.statistic.UsagesCollector; import com.intellij.internal.statistic.beans.GroupDescriptor; @@ -13,7 +13,8 @@ import java.util.Set; /** * @author Konstantin Bulenkov */ -class JdkInfoUsageCollector extends UsagesCollector { +@Deprecated // to be removed in 2018.2 +class LegacyJdkInfoUsageCollector extends UsagesCollector { @NotNull @Override public Set getUsages() { diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/os/OsNameUsageCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/os/LegacyOsNameUsageCollector.java similarity index 53% rename from platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/os/OsNameUsageCollector.java rename to platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/os/LegacyOsNameUsageCollector.java index 1cc9070917d1..7e41227d6b12 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/os/OsNameUsageCollector.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/os/LegacyOsNameUsageCollector.java @@ -1,19 +1,5 @@ -/* - * 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. - */ -package com.intellij.internal.statistic.customUsageCollectors.os; +// 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.collectors.legacy.os; import com.intellij.internal.statistic.CollectUsagesException; import com.intellij.internal.statistic.UsagesCollector; @@ -28,7 +14,8 @@ import java.util.Set; /** * @author peter */ -class OsNameUsageCollector extends UsagesCollector { +@Deprecated // to be removed in 2018.2 +class LegacyOsNameUsageCollector extends UsagesCollector { @NotNull @Override public Set getUsages() throws CollectUsagesException { diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/os/LegacyOsVersionUsageCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/os/LegacyOsVersionUsageCollector.java new file mode 100644 index 000000000000..b91e8fdf4d52 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/os/LegacyOsVersionUsageCollector.java @@ -0,0 +1,29 @@ +// 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.collectors.legacy.os; + +import com.intellij.internal.statistic.UsagesCollector; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.collectors.fus.os.OsVersionUsageCollector; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +/** + * @author peter + */ +@Deprecated + // to be removed in 2018.2 +class LegacyOsVersionUsageCollector extends UsagesCollector { + @NotNull + @Override + public Set getUsages() { + return OsVersionUsageCollector.getDescriptors(); + } + + @NotNull + @Override + public GroupDescriptor getGroupId() { + return GroupDescriptor.create("user.os.version"); + } +} \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/plugins/LegacyDisabledPluginsUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/plugins/LegacyDisabledPluginsUsagesCollector.java new file mode 100644 index 000000000000..52fe70f34148 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/plugins/LegacyDisabledPluginsUsagesCollector.java @@ -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.collectors.legacy.plugins; + +import com.intellij.ide.plugins.PluginManagerCore; +import com.intellij.internal.statistic.UsagesCollector; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +@Deprecated // to be removed in 2018.2 +public class LegacyDisabledPluginsUsagesCollector extends UsagesCollector { + private static final String GROUP_ID = "disabled-plugins"; + + @NotNull + public GroupDescriptor getGroupId() { + return GroupDescriptor.create(GROUP_ID, GroupDescriptor.HIGHER_PRIORITY); + } + + @NotNull + public Set getUsages() { + return ContainerUtil.map2Set(PluginManagerCore.getDisabledPlugins(), descriptor -> new UsageDescriptor(descriptor, 1)); + } +} diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/NonBundledPluginsUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/plugins/LegacyNonBundledPluginsUsagesCollector.java similarity index 54% rename from platform/platform-impl/src/com/intellij/ide/plugins/NonBundledPluginsUsagesCollector.java rename to platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/plugins/LegacyNonBundledPluginsUsagesCollector.java index e4c68285bd5b..fd772f8e4f6e 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/NonBundledPluginsUsagesCollector.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/plugins/LegacyNonBundledPluginsUsagesCollector.java @@ -1,32 +1,19 @@ -/* - * Copyright 2000-2011 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.ide.plugins; +// 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.collectors.legacy.plugins; +import com.intellij.ide.plugins.IdeaPluginDescriptor; +import com.intellij.ide.plugins.PluginManagerCore; import com.intellij.internal.statistic.UsagesCollector; import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.internal.statistic.beans.UsageDescriptor; -import com.intellij.openapi.util.Condition; -import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import java.util.List; import java.util.Set; -public class NonBundledPluginsUsagesCollector extends UsagesCollector { +@Deprecated // to be removed in 2018.2 +public class LegacyNonBundledPluginsUsagesCollector extends UsagesCollector { private static final String GROUP_ID = "non-bundled-plugins"; @NotNull diff --git a/platform/platform-impl/src/com/intellij/featureStatistics/FeaturesUsageCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/productivity/LegacyProductivityFeaturesUsageCollector.java similarity index 57% rename from platform/platform-impl/src/com/intellij/featureStatistics/FeaturesUsageCollector.java rename to platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/productivity/LegacyProductivityFeaturesUsageCollector.java index 80836ca10175..e7f3ccebd16f 100644 --- a/platform/platform-impl/src/com/intellij/featureStatistics/FeaturesUsageCollector.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/productivity/LegacyProductivityFeaturesUsageCollector.java @@ -1,20 +1,8 @@ -/* - * Copyright 2000-2010 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.featureStatistics; +// 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.collectors.legacy.productivity; +import com.intellij.featureStatistics.FeatureDescriptor; +import com.intellij.featureStatistics.ProductivityFeaturesRegistry; import com.intellij.internal.statistic.UsagesCollector; import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.internal.statistic.beans.UsageDescriptor; @@ -23,7 +11,8 @@ import org.jetbrains.annotations.NotNull; import java.util.HashSet; import java.util.Set; -public class FeaturesUsageCollector extends UsagesCollector { +@Deprecated // to be removed in 2018.2 +public class LegacyProductivityFeaturesUsageCollector extends UsagesCollector { @NotNull @Override diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/A11YUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyA11YUsagesCollector.java similarity index 80% rename from platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/A11YUsagesCollector.java rename to platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyA11YUsagesCollector.java index ad347da84b1f..59bd776bb720 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/A11YUsagesCollector.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyA11YUsagesCollector.java @@ -1,5 +1,5 @@ -// 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. -package com.intellij.internal.statistic.customUsageCollectors.ui; +// 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.collectors.legacy.ui; import com.intellij.internal.statistic.UsagesCollector; import com.intellij.internal.statistic.beans.GroupDescriptor; @@ -14,7 +14,8 @@ import java.util.Set; /** * @author tav */ -public class A11YUsagesCollector extends UsagesCollector { +@Deprecated // to be removed in 2018.2 +public class LegacyA11YUsagesCollector extends UsagesCollector { @NotNull @Override public Set getUsages() { diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyEditorColorSchemesUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyEditorColorSchemesUsagesCollector.java new file mode 100644 index 000000000000..623267cb7c99 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyEditorColorSchemesUsagesCollector.java @@ -0,0 +1,29 @@ +// 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.collectors.legacy.ui; + +import com.intellij.internal.statistic.UsagesCollector; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.collectors.fus.ui.EditorColorSchemesUsagesCollector; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +@Deprecated // to be removed in 2018.2 +public class LegacyEditorColorSchemesUsagesCollector extends UsagesCollector { + + public static final String GROUP_ID = "Color Schemes"; + + @NotNull + @Override + public Set getUsages() { + return EditorColorSchemesUsagesCollector.getDescriptors(); + } + + @NotNull + @Override + public GroupDescriptor getGroupId() { + return GroupDescriptor.create(GROUP_ID); + } + +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/FontSizeInfoUsageCollector.kt b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyFontSizeInfoUsageCollector.kt similarity index 73% rename from platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/FontSizeInfoUsageCollector.kt rename to platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyFontSizeInfoUsageCollector.kt index 332fc5a83ceb..b67d482aba33 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/FontSizeInfoUsageCollector.kt +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyFontSizeInfoUsageCollector.kt @@ -1,19 +1,5 @@ -/* - * 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. - */ -package com.intellij.internal.statistic.customUsageCollectors.ui +// 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.collectors.legacy.ui import com.intellij.ide.ui.UISettings import com.intellij.ide.util.PropertiesComponent @@ -27,7 +13,7 @@ import com.intellij.openapi.editor.colors.impl.AppEditorFontOptions /** * @author Konstantin Bulenkov */ -class FontSizeInfoUsageCollector : UsagesCollector() { +class LegacyFontSizeInfoUsageCollector : UsagesCollector() { @Throws(CollectUsagesException::class) override fun getUsages(): Set { val scheme = EditorColorsManager.getInstance().globalScheme diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/HiDPIModeUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyHiDPIModeUsagesCollector.java similarity index 79% rename from platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/HiDPIModeUsagesCollector.java rename to platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyHiDPIModeUsagesCollector.java index c8626fcd957a..1cf29d54ac1f 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/HiDPIModeUsagesCollector.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyHiDPIModeUsagesCollector.java @@ -1,5 +1,5 @@ -// 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. -package com.intellij.internal.statistic.customUsageCollectors.ui; +// 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.collectors.legacy.ui; import com.intellij.internal.statistic.UsagesCollector; import com.intellij.internal.statistic.beans.GroupDescriptor; @@ -14,7 +14,8 @@ import java.util.Set; /** * @author tav */ -public class HiDPIModeUsagesCollector extends UsagesCollector { +@Deprecated // to be removed in 2018.2 +public class LegacyHiDPIModeUsagesCollector extends UsagesCollector { @NotNull @Override public Set getUsages() { diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/LaFUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyLaFUsagesCollector.java similarity index 52% rename from platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/LaFUsagesCollector.java rename to platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyLaFUsagesCollector.java index 20a3c31a9bbe..041d91e29f3a 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/LaFUsagesCollector.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyLaFUsagesCollector.java @@ -1,22 +1,7 @@ -/* - * 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. - */ -package com.intellij.internal.statistic.customUsageCollectors.ui; +// 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.collectors.legacy.ui; import com.intellij.ide.ui.LafManager; -import com.intellij.internal.statistic.CollectUsagesException; import com.intellij.internal.statistic.UsagesCollector; import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.internal.statistic.beans.UsageDescriptor; @@ -28,10 +13,11 @@ import javax.swing.*; import java.util.Collections; import java.util.Set; -public class LaFUsagesCollector extends UsagesCollector { +@Deprecated // to be removed in 2018.2 +public class LegacyLaFUsagesCollector extends UsagesCollector { @NotNull @Override - public Set getUsages() throws CollectUsagesException { + public Set getUsages() { UIManager.LookAndFeelInfo laf = LafManager.getInstance().getCurrentLookAndFeel(); String key = SystemInfo.OS_NAME + " - "; if (!StringUtil.isEmptyOrSpaces(SystemInfo.SUN_DESKTOP)) { diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyScaleInfoUsageCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyScaleInfoUsageCollector.java new file mode 100644 index 000000000000..8d772b074ac3 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyScaleInfoUsageCollector.java @@ -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.internal.statistic.collectors.legacy.ui; + +import com.intellij.internal.statistic.UsagesCollector; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.collectors.fus.ui.ScaleInfoUsageCollector; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +/** + * @author tav + */ +@Deprecated // to be removed in 2018.2 +public class LegacyScaleInfoUsageCollector extends UsagesCollector { + @NotNull + @Override + public Set getUsages() { + return ScaleInfoUsageCollector.getDescriptors(); + } + + @NotNull + @Override + public GroupDescriptor getGroupId() { + return GroupDescriptor.create("user.ui.screen.scale"); + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyShortcutUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyShortcutUsagesCollector.java new file mode 100644 index 000000000000..4719fee92054 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyShortcutUsagesCollector.java @@ -0,0 +1,35 @@ +// 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.collectors.legacy.ui; + +import com.intellij.internal.statistic.UsagesCollector; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.collectors.fus.ui.persistence.ShortcutsCollector; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +@Deprecated // to be removed in 2018.2 +public final class LegacyShortcutUsagesCollector extends UsagesCollector { + private static final GroupDescriptor GROUP = GroupDescriptor.create(getGroupName(), GroupDescriptor.HIGHER_PRIORITY); + + private static String getGroupName() { + if (SystemInfo.isMac) return "Shortcuts on Mac"; + if (SystemInfo.isWindows) return "Shortcuts on Windows"; + if (SystemInfo.isLinux) return "Shortcuts on Linux"; + return "Shortcuts on OtherOs"; + } + + @NotNull + public Set getUsages() { + ShortcutsCollector.MyState state = ShortcutsCollector.getInstance().getState(); + return ContainerUtil.map2Set(state.myValues.entrySet(), e -> new UsageDescriptor(e.getKey(), e.getValue())); + } + + @NotNull + public GroupDescriptor getGroupId() { + return GROUP; + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyToolbarClicksUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyToolbarClicksUsagesCollector.java new file mode 100644 index 000000000000..164088368031 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyToolbarClicksUsagesCollector.java @@ -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.internal.statistic.collectors.legacy.ui; + +import com.intellij.internal.statistic.UsagesCollector; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.collectors.fus.ui.persistence.ToolbarClicksCollector; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +@Deprecated // to be removed in 2018.2 +public final class LegacyToolbarClicksUsagesCollector extends UsagesCollector { + private static final GroupDescriptor GROUP = GroupDescriptor.create("Toolbar Clicks", GroupDescriptor.HIGHER_PRIORITY); + + @NotNull + public Set getUsages() { + ToolbarClicksCollector.ClicksState state = ToolbarClicksCollector.getInstance().getState(); + assert state != null; + return ContainerUtil.map2Set(state.myValues.entrySet(), e -> new UsageDescriptor(e.getKey(), e.getValue())); + } + + @NotNull + public GroupDescriptor getGroupId() { + return GROUP; + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyUiInfoUsageCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyUiInfoUsageCollector.java new file mode 100644 index 000000000000..09d1156e8c28 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/legacy/ui/LegacyUiInfoUsageCollector.java @@ -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.internal.statistic.collectors.legacy.ui; + +import com.intellij.internal.statistic.UsagesCollector; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.collectors.fus.ui.UiInfoUsageCollector; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +/** + * @author Konstantin Bulenkov + */ +@Deprecated // to be removed in 2018.2 +class LegacyUiInfoUsageCollector extends UsagesCollector { + @NotNull + @Override + public Set getUsages() { + return UiInfoUsageCollector.getDescriptors(); + } + + @NotNull + @Override + public GroupDescriptor getGroupId() { + return GroupDescriptor.create("UI Features"); + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/actions/ActionIdProvider.java b/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/actions/ActionIdProvider.java deleted file mode 100644 index 03164ad55ad7..000000000000 --- a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/actions/ActionIdProvider.java +++ /dev/null @@ -1,8 +0,0 @@ -/* - * 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. - */ -package com.intellij.internal.statistic.customUsageCollectors.actions; - -public interface ActionIdProvider { - String getId(); -} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/os/OsVersionUsageCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/os/OsVersionUsageCollector.java deleted file mode 100644 index 489f884fcf27..000000000000 --- a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/os/OsVersionUsageCollector.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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. - */ -package com.intellij.internal.statistic.customUsageCollectors.os; - -import com.intellij.internal.statistic.CollectUsagesException; -import com.intellij.internal.statistic.UsagesCollector; -import com.intellij.internal.statistic.beans.GroupDescriptor; -import com.intellij.internal.statistic.beans.UsageDescriptor; -import com.intellij.openapi.util.SystemInfo; -import com.intellij.openapi.util.Version; -import com.intellij.openapi.util.text.StringUtil; -import org.jetbrains.annotations.NotNull; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.Collections; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -/** - * @author peter - */ -class OsVersionUsageCollector extends UsagesCollector { - @NotNull - @Override - public Set getUsages() throws CollectUsagesException { - UsageDescriptor descriptor; - - if (SystemInfo.isLinux) { - String releaseId = null, releaseVersion = null; - - try { - Map values = Files.lines(Paths.get("/etc/os-release")) - .map(line -> StringUtil.split(line, "=")) - .filter(parts -> parts.size() == 2) - .collect(Collectors.toMap(parts -> parts.get(0), parts -> StringUtil.unquoteString(parts.get(1)))); - releaseId = values.get("ID"); - releaseVersion = values.get("VERSION_ID"); - } - catch (IOException ignored) { } - - if (releaseId == null) releaseId = "unknown"; - - if (releaseVersion == null) { - releaseVersion = SystemInfo.OS_VERSION; - Version version = Version.parseVersion(releaseVersion); - if (version != null) { - releaseVersion = version.toCompactString(); - } - } - - descriptor = new UsageDescriptor("Linux/" + releaseId + " " + releaseVersion, 1); - } - else { - descriptor = new UsageDescriptor(SystemInfo.OS_NAME + " " + SystemInfo.OS_VERSION, 1); - } - - return Collections.singleton(descriptor); - } - - @NotNull - @Override - public GroupDescriptor getGroupId() { - return GroupDescriptor.create("user.os.version"); - } -} \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/ScaleInfoUsageCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/ScaleInfoUsageCollector.java deleted file mode 100644 index 539b3803df1f..000000000000 --- a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/ScaleInfoUsageCollector.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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. - */ -package com.intellij.internal.statistic.customUsageCollectors.ui; - -import com.intellij.internal.statistic.CollectUsagesException; -import com.intellij.internal.statistic.UsagesCollector; -import com.intellij.internal.statistic.beans.GroupDescriptor; -import com.intellij.internal.statistic.beans.UsageDescriptor; -import com.intellij.util.ui.JBUI; -import org.jdesktop.swingx.util.OS; -import org.jetbrains.annotations.NotNull; - -import java.util.Collections; -import java.util.Set; - -/** - * @author tav - */ -public class ScaleInfoUsageCollector extends UsagesCollector { - @NotNull - @Override - public Set getUsages() throws CollectUsagesException { - float scale = JBUI.sysScale(); - - int scaleBase = (int)Math.floor(scale); - float scaleFract = scale - scaleBase; - - if (scaleFract == 0.0f) scaleFract = 0.0f; // count integer scale on a precise match only - else if (scaleFract < 0.375f) scaleFract = 0.25f; - else if (scaleFract < 0.625f) scaleFract = 0.5f; - else scaleFract = 0.75f; - - scale = scaleBase + scaleFract; - - String os = OS.isWindows() ? "Windows" : OS.isLinux() ? "Linux" : OS.isMacOSX() ? "Mac" : "Unknown OS"; - return Collections.singleton(new UsageDescriptor(os + " " + scale, 1)); - } - - @NotNull - @Override - public GroupDescriptor getGroupId() { - return GroupDescriptor.create("user.ui.screen.scale"); - } -} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/UiInfoUsageCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/UiInfoUsageCollector.java deleted file mode 100644 index ccc01a8e6909..000000000000 --- a/platform/platform-impl/src/com/intellij/internal/statistic/customUsageCollectors/ui/UiInfoUsageCollector.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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. - */ -package com.intellij.internal.statistic.customUsageCollectors.ui; - -import com.intellij.ide.GeneralSettings; -import com.intellij.ide.ui.UISettings; -import com.intellij.internal.statistic.UsagesCollector; -import com.intellij.internal.statistic.beans.GroupDescriptor; -import com.intellij.internal.statistic.beans.UsageDescriptor; -import com.intellij.openapi.editor.ex.EditorSettingsExternalizable; -import com.intellij.util.ui.UIUtil; -import gnu.trove.THashSet; -import org.jetbrains.annotations.NotNull; - -import javax.swing.*; -import java.util.Set; - -import static com.intellij.internal.statistic.utils.StatisticsUtilKt.getBooleanUsage; - -/** - * @author Konstantin Bulenkov - */ -class UiInfoUsageCollector extends UsagesCollector { - @NotNull - @Override - public Set getUsages() { - Set set = new THashSet<>(); - - add(set, "Nav Bar visible", navbar() ? 1 : 0); - add(set, "Nav Bar floating", navbar() ? 0 : 1); - add(set, "Toolbar visible", toolbar() ? 1 : 0); - add(set, "Toolbar hidden", toolbar() ? 0 : 1); - add(set, "Toolbar + NavBar", !toolbar() && navbar() ? 1 : 0); - add(set, "Toolbar and NavBar hidden", !toolbar() && !navbar() ? 1 : 0); - add(set, "Status bar visible", status() ? 1 : 0); - add(set, "Status bar hidden", status() ? 0 : 1); - add(set, "Tool Window buttons visible", stripes() ? 1 : 0); - add(set, "Tool Window buttons hidden", stripes() ? 0 : 1); - add(set, "Recent Files = 15", recent() == 15 ? 1 : 0); - add(set, "Recent Files (15, 30]", 15 < recent() && recent() < 31 ? 1 : 0); - add(set, "Recent Files (30, 50]", 30 < recent() && recent() < 51 ? 1 : 0); - add(set, "Recent Files > 50", 50 < recent() ? 1 : 0); - add(set, "Block cursor", EditorSettingsExternalizable.getInstance().isBlockCursor() ? 1 : 0); - add(set, "Line Numbers", EditorSettingsExternalizable.getInstance().isLineNumbersShown() ? 1 : 0); - add(set, "Gutter Icons", EditorSettingsExternalizable.getInstance().areGutterIconsShown() ? 1 : 0); - add(set, "Soft Wraps", EditorSettingsExternalizable.getInstance().isUseSoftWraps() ? 1 : 0); - add(set, "Tabs None", tabPlace() == 0 ? 1 : 0); - add(set, "Tabs Top", tabPlace() == SwingConstants.TOP ? 1 : 0); - add(set, "Tabs Bottom", tabPlace() == SwingConstants.BOTTOM ? 1 : 0); - add(set, "Tabs Left", tabPlace() == SwingConstants.LEFT ? 1 : 0); - add(set, "Tabs Right", tabPlace() == SwingConstants.RIGHT ? 1 : 0); - add(set, "Retina", UIUtil.isRetina() ? 1 : 0); - add(set, "Show tips on startup", GeneralSettings.getInstance().isShowTipsOnStartup() ? 1 : 0); - set.add(getBooleanUsage("Allow merging buttons", UISettings.getInstance().getAllowMergeButtons())); - - return set; - } - - @NotNull - @Override - public GroupDescriptor getGroupId() { - return GroupDescriptor.create("UI Features"); - } - - private static void add(Set set, String key, int value) { - set.add(new UsageDescriptor(key, value)); - } - - private static int tabPlace() { - return UISettings.getInstance().getEditorTabPlacement(); - } - - private static int recent() { - return UISettings.getInstance().getRecentFilesLimit(); - } - - private static boolean stripes() { - return UISettings.getInstance().getHideToolStripes(); - } - - private static boolean status() { - return UISettings.getInstance().getShowStatusBar(); - } - - private static boolean toolbar() { - return UISettings.getInstance().getShowMainToolbar(); - } - - private static boolean navbar() { - return UISettings.getInstance().getShowNavigationBar(); - } -} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/service/fus/beans/FSGroup.java b/platform/platform-impl/src/com/intellij/internal/statistic/service/fus/beans/FSGroup.java index 8cb0ac1492d2..1f6c898d3043 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/service/fus/beans/FSGroup.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/service/fus/beans/FSGroup.java @@ -2,6 +2,7 @@ package com.intellij.internal.statistic.service.fus.beans; import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.service.fus.collectors.UsageDescriptorKeyValidator; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -11,24 +12,16 @@ import java.util.Set; public class FSGroup { - private static final String FORBIDDEN_PATTERN = "[,\\s\\n]+"; - private static final String FORBIDDEN_PATTERN_REPLACEMENT = "[??]"; - public String id; public Map metrics ; private FSGroup(String id, Set usages) { this.id = id; for (UsageDescriptor usage : usages) { - getMetrics().put(replaceForbiddenPattern(usage), usage.getValue()); + getMetrics().put(UsageDescriptorKeyValidator.replaceForbiddenSymbols(usage.getKey()), usage.getValue()); } } - @NotNull - private static String replaceForbiddenPattern(@NotNull UsageDescriptor usage) { - return usage.getKey().replaceAll(FORBIDDEN_PATTERN, FORBIDDEN_PATTERN_REPLACEMENT); - } - @NotNull public Map getMetrics() { if (metrics == null) { diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/service/fus/collectors/UsageDescriptorKeyValidator.java b/platform/platform-impl/src/com/intellij/internal/statistic/service/fus/collectors/UsageDescriptorKeyValidator.java new file mode 100644 index 000000000000..82ce14d16abb --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/service/fus/collectors/UsageDescriptorKeyValidator.java @@ -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.service.fus.collectors; + +import org.jetbrains.annotations.NotNull; + +public class UsageDescriptorKeyValidator { + public static final String FORBIDDEN_PATTERN = "[,\\s\\n]+"; + public static final String FORBIDDEN_PATTERN_REPLACEMENT = "[??]"; + + @NotNull + public static String replaceForbiddenSymbols(@NotNull String key) { + return key.replaceAll(FORBIDDEN_PATTERN, FORBIDDEN_PATTERN_REPLACEMENT); + } + + @NotNull + public static String ensureProperKey(@NotNull String key) { + return key.replaceAll(FORBIDDEN_PATTERN, "."); + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionButton.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionButton.java index b231c47a0922..873d776532e9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionButton.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionButton.java @@ -18,7 +18,7 @@ package com.intellij.openapi.actionSystem.impl; import com.intellij.icons.AllIcons; import com.intellij.ide.DataManager; import com.intellij.ide.HelpTooltip; -import com.intellij.internal.statistic.customUsageCollectors.ui.ToolbarClicksCollector; +import com.intellij.internal.statistic.collectors.fus.ui.persistence.ToolbarClicksCollector; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.ActionButtonLook; import com.intellij.openapi.actionSystem.ex.ActionManagerEx; diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java index 6755344ae749..96dbbcc42925 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java @@ -10,8 +10,8 @@ import com.intellij.ide.plugins.IdeaPluginDescriptor; 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.ActionsCollectorImpl; +import com.intellij.internal.statistic.collectors.fus.actions.persistence.ActionIdProvider; +import com.intellij.internal.statistic.collectors.fus.actions.persistence.ActionsCollectorImpl; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.ActionManagerEx; diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java index e0e2299da461..75620457321e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java @@ -4,7 +4,7 @@ package com.intellij.openapi.actionSystem.impl; import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.ide.ui.UISettings; import com.intellij.ide.ui.laf.IconCache; -import com.intellij.internal.statistic.customUsageCollectors.actions.MainMenuCollector; +import com.intellij.internal.statistic.collectors.fus.actions.persistence.MainMenuCollector; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.ActionManagerEx; diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java index 0a44b2cab584..5d1d835dcbe0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java @@ -5,7 +5,7 @@ import com.intellij.icons.AllIcons; import com.intellij.ide.DataManager; import com.intellij.ide.HelpTooltip; import com.intellij.ide.impl.DataManagerImpl; -import com.intellij.internal.statistic.customUsageCollectors.ui.ToolbarClicksCollector; +import com.intellij.internal.statistic.collectors.fus.ui.persistence.ToolbarClicksCollector; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.ActionButtonLook; diff --git a/platform/platform-impl/src/com/intellij/openapi/application/ImportOldConfigsPanel.java b/platform/platform-impl/src/com/intellij/openapi/application/ImportOldConfigsPanel.java index 073c47c77f84..439e0c3bb7d6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/ImportOldConfigsPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/ImportOldConfigsPanel.java @@ -2,7 +2,7 @@ package com.intellij.openapi.application; import com.intellij.ide.cloudConfig.CloudConfigProvider; -import com.intellij.internal.statistic.customUsageCollectors.ideSettings.IdeInitialConfigButtonUsages; +import com.intellij.internal.statistic.collectors.legacy.ideSettings.IdeInitialConfigButtonUsages; import com.intellij.openapi.MnemonicHelper; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.Pair; diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java index 80d06923b079..3d7309d06f59 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java @@ -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.openapi.editor.actions; @@ -18,7 +18,6 @@ import com.intellij.openapi.editor.highlighter.HighlighterIterator; import com.intellij.openapi.editor.impl.EditorImpl; import com.intellij.openapi.editor.impl.FoldingModelImpl; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.tree.IElementType; @@ -235,7 +234,8 @@ public class EditorActionUtil { IElementType rightToken = it.getTokenType(); it.retreat(); IElementType leftToken = it.getTokenType(); - return !Comparing.equal(leftToken, rightToken); + if (leftToken == null || rightToken == null) return false; + return LanguageWordBoundaryFilter.INSTANCE.forLanguage(leftToken.getLanguage()).isWordBoundary(leftToken, rightToken); } public static boolean isWordStart(@NotNull CharSequence text, int offset, boolean isCamel) { diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java index b73dfed28310..9ff06c6fbc88 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java @@ -274,23 +274,19 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener mySplittersElement = element; } - @NotNull public VirtualFile[] getOpenFiles() { - final Set files = new ArrayListSet<>(); - for (final EditorWindow myWindow : myWindows) { - final EditorWithProviderComposite[] editors = myWindow.getEditors(); - for (final EditorWithProviderComposite editor : editors) { - VirtualFile file = editor.getFile(); - // background thread may call this method when invalid file is being removed - // do not return it here as it will quietly drop out soon - if (file.isValid()) { - files.add(file); - } + @NotNull + public VirtualFile[] getOpenFiles() { + Set files = new ArrayListSet<>(); + for (EditorWindow myWindow : myWindows) { + for (EditorWithProviderComposite editor : myWindow.getEditors()) { + files.add(editor.getFile()); } } return VfsUtilCore.toVirtualFileArray(files); } - @NotNull public VirtualFile[] getSelectedFiles() { + @NotNull + public VirtualFile[] getSelectedFiles() { final Set files = new ArrayListSet<>(); for (final EditorWindow window : myWindows) { final VirtualFile file = window.getSelectedFile(); diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java index 3c4df10ebc0e..c7060aed3298 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java @@ -19,7 +19,7 @@ import com.intellij.ide.DataManager; import com.intellij.ide.IdeEventQueue; import com.intellij.ide.ProhibitAWTEvents; import com.intellij.ide.impl.DataManagerImpl; -import com.intellij.internal.statistic.customUsageCollectors.ui.ShortcutsCollector; +import com.intellij.internal.statistic.collectors.fus.ui.persistence.ShortcutsCollector; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.ActionManagerEx; diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandler.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandler.java index 7be943a95bb0..b1467dae9238 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandler.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandler.java @@ -3,7 +3,7 @@ package com.intellij.openapi.keymap.impl; import com.intellij.ide.DataManager; import com.intellij.ide.IdeEventQueue; -import com.intellij.internal.statistic.customUsageCollectors.ui.ShortcutsCollector; +import com.intellij.internal.statistic.collectors.fus.ui.persistence.ShortcutsCollector; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.ActionManagerEx; diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java index 39c953cb67a5..f182c2998863 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java @@ -5,7 +5,7 @@ import com.intellij.icons.AllIcons; import com.intellij.ide.DataManager; import com.intellij.ide.ui.UISettings; import com.intellij.ide.ui.UISettingsListener; -import com.intellij.internal.statistic.customUsageCollectors.ui.ToolbarClicksCollector; +import com.intellij.internal.statistic.collectors.fus.ui.persistence.ToolbarClicksCollector; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.ActionManagerEx; diff --git a/platform/platform-impl/src/com/intellij/ui/plaf/beg/BegMenuItemUI.java b/platform/platform-impl/src/com/intellij/ui/plaf/beg/BegMenuItemUI.java index e80baefaa426..807190f15c3c 100644 --- a/platform/platform-impl/src/com/intellij/ui/plaf/beg/BegMenuItemUI.java +++ b/platform/platform-impl/src/com/intellij/ui/plaf/beg/BegMenuItemUI.java @@ -17,7 +17,7 @@ package com.intellij.ui.plaf.beg; import com.intellij.ide.ui.UISettings; -import com.intellij.internal.statistic.customUsageCollectors.actions.MainMenuCollector; +import com.intellij.internal.statistic.collectors.fus.actions.persistence.MainMenuCollector; import com.intellij.openapi.actionSystem.ActionPlaces; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.impl.ActionMenuItem; diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml index 23ccd83b3ab3..4dca2ad90ff2 100644 --- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml @@ -54,6 +54,11 @@ + + + + diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index cc9c16f69ccc..077d16644b92 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -906,11 +906,13 @@ + + + - diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index 6e4127605a12..5deaf23b3691 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -202,12 +202,12 @@ - - + + - - + serviceImplementation="com.intellij.internal.statistic.collectors.fus.actions.persistence.ActionsCollectorImpl"/> + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/NextPrevWordTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/NextPrevWordTest.java index 08c3ff838104..fe8479a788f0 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/NextPrevWordTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/NextPrevWordTest.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2014 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.editor.actions; import com.intellij.openapi.actionSystem.IdeActions; @@ -57,6 +43,12 @@ public class NextPrevWordTest extends LightPlatformCodeInsightFixtureTestCase { myFixture.checkResult("class Foo { String s = \"a\\xb\"; }"); } + public void testNextWordAtGreaterThanEqualOperator() { + myFixture.configureByText("Foo.java", "class Foo { boolean b = 1 >= 2; }"); + myFixture.performEditorAction(IdeActions.ACTION_EDITOR_NEXT_WORD); + myFixture.checkResult("class Foo { boolean b = 1 >= 2; }"); + } + public void testPrevNextWordWithFolding() { myFixture.configureByText("a.txt", "brown fox"); EditorTestUtil.addFoldRegion(myFixture.getEditor(), 4, 7, "...", true); diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/fileTypes/FileTypeUsagesCollectorTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/fileTypes/FileTypeUsagesCollectorTest.java index c653acf45da0..1c009a5a36d4 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/fileTypes/FileTypeUsagesCollectorTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/fileTypes/FileTypeUsagesCollectorTest.java @@ -17,6 +17,7 @@ package com.intellij.openapi.fileTypes; import com.intellij.internal.statistic.CollectUsagesException; import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.collectors.legacy.fileTypes.LegacyFileTypeUsagesCollector; import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase; import com.intellij.util.NotNullFunction; import com.intellij.util.containers.ContainerUtil; @@ -32,7 +33,7 @@ import java.util.Set; public class FileTypeUsagesCollectorTest extends LightPlatformCodeInsightFixtureTestCase { private void doTest(@NotNull Collection fileTypes) throws CollectUsagesException { - final Set usages = new FileTypeUsagesCollector().getProjectUsages(getProject()); + final Set usages = new LegacyFileTypeUsagesCollector().getProjectUsages(getProject()); for (UsageDescriptor usage : usages) { assertEquals(1, usage.getValue()); } diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index 8638ab34751e..10560b144c4b 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -1122,6 +1122,13 @@ cidr.test.framework.targetTypeFromHeaderDetectionEnable.description=Checks the t cidr.show.breadcrumbs=true cidr.show.breadcrumbs.description="Show breadcrumbs for C/C++/ObjC languages" +cidr.indent.lexer.only.objc=false +cidr.indent.lexer.only.objc.description=Enables indentation in the Objective-C files from the information of the lexer \ + (fast, but may lose an alignment when typing). +cidr.indent.lexer.only.cpp=false +cidr.indent.lexer.only.cpp.description=Enables indentation in the C and C++ files from the information of the lexer \ + (fast, but may lose an alignment when typing). + clion.enable.objc.settings=false clion.enable.objc.settings.description=Enables Objective-C-specific code style, colors etc. settings. diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListWorker.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListWorker.java index fea4481834c6..f14d407254ef 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListWorker.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListWorker.java @@ -169,7 +169,7 @@ public class ChangeListWorker { tracker.initChangeTracking(myDefault.id, ContainerUtil.map(myLists, list -> list.id), oldList != null ? oldList.id : null); if (LOG.isDebugEnabled()) { - LOG.debug(String.format("[registerChangeTracker] path: %s", filePath)); + LOG.debug(String.format("[registerChangeTracker] path: %s, old list: %s", filePath, oldList != null ? oldList.id : "null")); } } @@ -177,21 +177,24 @@ public class ChangeListWorker { PartialChangeTracker oldTracker = myPartialChangeTrackers.remove(filePath); if (!Comparing.equal(oldTracker, tracker)) { LOG.error(String.format("Wrong tracker removed: %s; expected: %s; passed: %s", filePath, oldTracker, tracker)); + return; } + ListData newList = null; Change change = getChangeForAfterPath(filePath); if (change != null) { - putChangeMapping(change, getMainList(oldTracker)); + newList = getMainList(oldTracker); + putChangeMapping(change, newList); } if (LOG.isDebugEnabled()) { - LOG.debug(String.format("[unregisterChangeTracker] path: %s", filePath)); + LOG.debug(String.format("[unregisterChangeTracker] path: %s, new list: %s, tracker lists: %s", + filePath, newList != null ? newList.id : "null", oldTracker.getAffectedChangeListsIds())); } } @NotNull - private ListData getMainList(@Nullable PartialChangeTracker oldTracker) { - if (oldTracker == null) return myDefault; + private ListData getMainList(@NotNull PartialChangeTracker oldTracker) { List changelistIds = oldTracker.getAffectedChangeListsIds(); if (changelistIds.size() == 1) { ListData list = getDataByIdVerify(changelistIds.get(0)); @@ -846,7 +849,7 @@ public class ChangeListWorker { return String.format("list: %s (%s) changes: %s", list.name, list.id, StringUtil.join(getChangesIn(list), ", ")); }, "\n"); String trackers = StringUtil.join(myPartialChangeTrackers.keySet(), ","); - return String.format("ChangeListWorker{ lists = {\n%s }\ntrackers = %s\n}", lists, trackers); + return String.format("ChangeListWorker{ default = %s, lists = {\n%s }\ntrackers = %s\n}", myDefault.id, lists, trackers); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/checkout/CheckoutAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/checkout/CheckoutAction.java index 29e6b7db1cdd..698b89b0ac13 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/checkout/CheckoutAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/checkout/CheckoutAction.java @@ -15,11 +15,13 @@ */ package com.intellij.openapi.vcs.checkout; -import com.intellij.internal.statistic.customUsageCollectors.actions.ActionIdProvider; +import com.intellij.internal.statistic.collectors.fus.actions.persistence.ActionIdProvider; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.project.*; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.vcs.CheckoutProvider; import com.intellij.openapi.vcs.ProjectLevelVcsManager; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/PartialLocalLineStatusTracker.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/PartialLocalLineStatusTracker.kt index 46187a0423c1..8bafea109bd8 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/PartialLocalLineStatusTracker.kt +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/PartialLocalLineStatusTracker.kt @@ -165,6 +165,8 @@ class PartialLocalLineStatusTracker(project: Project, } } + updateAffectedChangeLists() + dropExistingUndoActions() if (isValid()) eventDispatcher.multicaster.onBecomingValid(this) } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/LineStatusTrackerManager.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/LineStatusTrackerManager.kt index ef41a55bc639..07b9e691143e 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/LineStatusTrackerManager.kt +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/LineStatusTrackerManager.kt @@ -61,10 +61,10 @@ import com.intellij.openapi.wm.ToolWindowManager import com.intellij.testFramework.LightVirtualFile import com.intellij.util.EventDispatcher import com.intellij.util.concurrency.AppExecutorUtil +import com.intellij.util.concurrency.Semaphore +import com.intellij.util.ui.UIUtil import com.intellij.vcsUtil.VcsUtil -import org.jetbrains.annotations.CalledInAny -import org.jetbrains.annotations.CalledInAwt -import org.jetbrains.annotations.NonNls +import org.jetbrains.annotations.* import java.nio.charset.Charset import java.util.* @@ -152,7 +152,7 @@ class LineStatusTrackerManager( } trackers.clear() - loader.clear() + loader.dispose() } } @@ -476,7 +476,7 @@ class LineStatusTrackerManager( } } - private inner class MyBaseRevisionLoader() : SingleThreadLoader(project) { + private inner class MyBaseRevisionLoader : SingleThreadLoader() { override fun loadRequest(request: RefreshRequest): Result { if (isDisposed) return Result.Canceled() val document = request.document @@ -527,67 +527,60 @@ class LineStatusTrackerManager( return Result.Success(RefreshData(converted, newContentInfo)) } + @CalledInAwt override fun handleResult(request: RefreshRequest, result: Result) { val document = request.document when (result) { is Result.Canceled -> { - synchronized(LOCK) { - val virtualFile = fileDocumentManager.getFile(document) - if (virtualFile == null) return + val virtualFile = fileDocumentManager.getFile(document) ?: return - val state = fileStatesAwaitingRefresh.remove(virtualFile) - if (state == null) return + val state = synchronized(LOCK) { + fileStatesAwaitingRefresh.remove(virtualFile) ?: return + } - runInEdt(ModalityState.any()) { - val tracker = getLineStatusTracker(document) - if (tracker is PartialLocalLineStatusTracker) { - tracker.restoreState(state) - log("Loading canceled: state restored", virtualFile) - } - } + val tracker = getLineStatusTracker(document) + if (tracker is PartialLocalLineStatusTracker) { + tracker.restoreState(state) + log("Loading canceled: state restored", virtualFile) } } is Result.Error -> { - runInEdt(ModalityState.any()) { - synchronized(LOCK) { - val data = trackers[document] ?: return@runInEdt + synchronized(LOCK) { + val data = trackers[document] ?: return - data.tracker.dropBaseRevision() - data.contentInfo = null + data.tracker.dropBaseRevision() + data.contentInfo = null - checkIfTrackerCanBeReleased(document) - } + checkIfTrackerCanBeReleased(document) } } is Result.Success -> { - runInEdt(ModalityState.any()) { - val virtualFile = fileDocumentManager.getFile(document)!! - val refreshData = result.data + val virtualFile = fileDocumentManager.getFile(document)!! + val refreshData = result.data - synchronized(LOCK) { - val data = trackers[document] - if (data == null) { - log("Loading finished: tracker already released", virtualFile) - return@runInEdt - } - if (!shouldBeUpdated(data.contentInfo, refreshData.info)) { - log("Loading finished: no need to update", virtualFile) - return@runInEdt - } - - data.contentInfo = refreshData.info + synchronized(LOCK) { + val data = trackers[document] + if (data == null) { + log("Loading finished: tracker already released", virtualFile) + return + } + if (!shouldBeUpdated(data.contentInfo, refreshData.info)) { + log("Loading finished: no need to update", virtualFile) + return } - val tracker = getLineStatusTracker(document)!! - tracker.setBaseRevision(refreshData.text) - log("Loading finished: success", virtualFile) + data.contentInfo = refreshData.info + } - if (tracker is PartialLocalLineStatusTracker) { - val state = fileStatesAwaitingRefresh.remove(tracker.virtualFile) - if (state != null) { - tracker.restoreState(state) - log("Loading finished: state restored", virtualFile) - } + val tracker = getLineStatusTracker(document)!! + tracker.setBaseRevision(refreshData.text) + log("Loading finished: success", virtualFile) + + if (tracker is PartialLocalLineStatusTracker) { + val state = fileStatesAwaitingRefresh.remove(tracker.virtualFile) + if (state != null) { + tracker.restoreState(state) + log("Loading finished: state restored", virtualFile) } } } @@ -962,6 +955,43 @@ class LineStatusTrackerManager( }) } } + + + @TestOnly + fun waitUntilBaseContentsLoaded() { + val semaphore = Semaphore() + semaphore.down() + + loader.addAfterUpdateRunnable(Runnable { + semaphore.up() + }) + + val start = System.currentTimeMillis() + while (true) { + if (ApplicationManager.getApplication().isDispatchThread) { + UIUtil.dispatchAllInvocationEvents() + } + if (semaphore.waitFor(10)) { + return + } + if (System.currentTimeMillis() - start > 2000) { + throw IllegalStateException("Couldn't await base contents") + } + } + } + + @TestOnly + fun releaseAllTrackers() { + synchronized(LOCK) { + forcedDocuments.clear() + + for (data in trackers.values) { + unregisterTrackerInCLM(data) + data.tracker.release() + } + trackers.clear() + } + } } @@ -971,7 +1001,7 @@ class LineStatusTrackerManager( * - Allows to check whether request is scheduled or is waiting for completion. * - Notifies callbacks when queue is exhausted. */ -private abstract class SingleThreadLoader(private val project: Project) { +private abstract class SingleThreadLoader { private val LOG = Logger.getInstance(SingleThreadLoader::class.java) private val LOCK: Any = Any() @@ -983,15 +1013,19 @@ private abstract class SingleThreadLoader(private val project: Proje private val callbacksWaitingUpdateCompletion = ArrayList() private var isScheduled: Boolean = false + private var isDisposed: Boolean = false + @CalledInBackground protected abstract fun loadRequest(request: Request): Result + + @CalledInAwt protected abstract fun handleResult(request: Request, result: Result) @CalledInAwt fun scheduleRefresh(request: Request) { - if (isDisposed()) return + if (isDisposed) return synchronized(LOCK) { if (taskQueue.contains(request)) return @@ -1002,9 +1036,10 @@ private abstract class SingleThreadLoader(private val project: Proje } @CalledInAwt - fun clear() { + fun dispose() { val callbacks = mutableListOf() synchronized(LOCK) { + isDisposed = true taskQueue.clear() waitingForRefresh.clear() @@ -1050,7 +1085,7 @@ private abstract class SingleThreadLoader(private val project: Proje private fun schedule() { - if (isDisposed()) return + if (isDisposed) return synchronized(LOCK) { if (isScheduled) return @@ -1068,7 +1103,7 @@ private abstract class SingleThreadLoader(private val project: Proje val request = synchronized(LOCK) { val request = taskQueue.poll() - if (isDisposed() || request == null) { + if (isDisposed || request == null) { isScheduled = false return } @@ -1091,14 +1126,18 @@ private abstract class SingleThreadLoader(private val project: Proje } runInEdt(ModalityState.any()) { - handleResult(request, result) - notifyTrackerRefreshed(request) + try { + handleResult(request, result) + } + finally { + notifyTrackerRefreshed(request) + } } } @CalledInAwt private fun notifyTrackerRefreshed(request: Request) { - if (isDisposed()) return + if (isDisposed) return val callbacks = mutableListOf() synchronized(LOCK) { @@ -1124,8 +1163,6 @@ private abstract class SingleThreadLoader(private val project: Proje } } } - - private fun isDisposed() = project.isDisposed } private sealed class Result { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/LegacyVcsOptionsUsagesCollector.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/LegacyVcsOptionsUsagesCollector.java new file mode 100644 index 000000000000..8f07d6081779 --- /dev/null +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/LegacyVcsOptionsUsagesCollector.java @@ -0,0 +1,25 @@ +// 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.vcs.statistics; + +import com.intellij.internal.statistic.AbstractProjectsUsagesCollector; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +@Deprecated // to be removed in 2018.2 +public class LegacyVcsOptionsUsagesCollector extends AbstractProjectsUsagesCollector { + private static final String GROUP_ID = "vcs-options"; + + @NotNull + public GroupDescriptor getGroupId() { + return GroupDescriptor.create(GROUP_ID); + } + + @NotNull + public Set getProjectUsages(@NotNull Project project) { + return VcsOptionsUsagesCollector.getDescriptors(project); + } +} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/LegacyVcsStatsUsagesCollector.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/LegacyVcsStatsUsagesCollector.java new file mode 100644 index 000000000000..a7a1f23c2572 --- /dev/null +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/LegacyVcsStatsUsagesCollector.java @@ -0,0 +1,25 @@ +// 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.vcs.statistics; + +import com.intellij.internal.statistic.AbstractProjectsUsagesCollector; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +@Deprecated // to be removed in 2018.2 +public class LegacyVcsStatsUsagesCollector extends AbstractProjectsUsagesCollector { + private static final String GROUP_ID = "vcs-stats"; + + @NotNull + public GroupDescriptor getGroupId() { + return GroupDescriptor.create(GROUP_ID); + } + + @NotNull + public Set getProjectUsages(@NotNull Project project) { + return VcsStatsUsagesCollector.getDescriptors(project); + } +} diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/DisabledPluginsUsagesCollector.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/LegacyVcsUsagesCollector.java similarity index 63% rename from platform/platform-impl/src/com/intellij/ide/plugins/DisabledPluginsUsagesCollector.java rename to platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/LegacyVcsUsagesCollector.java index 4ab48850c44d..38294390c383 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/DisabledPluginsUsagesCollector.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/LegacyVcsUsagesCollector.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2010 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. @@ -13,19 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.ide.plugins; +package com.intellij.openapi.vcs.statistics; -import com.intellij.internal.statistic.UsagesCollector; +import com.intellij.internal.statistic.AbstractProjectsUsagesCollector; import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.internal.statistic.beans.UsageDescriptor; -import com.intellij.util.Function; -import com.intellij.util.containers.ContainerUtil; +import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; import java.util.Set; -public class DisabledPluginsUsagesCollector extends UsagesCollector { - private static final String GROUP_ID = "disabled-plugins"; +@Deprecated // to be removed in 2018.2 +public class LegacyVcsUsagesCollector extends AbstractProjectsUsagesCollector { + private static final String GROUP_ID = "vcs"; @NotNull public GroupDescriptor getGroupId() { @@ -33,7 +33,7 @@ public class DisabledPluginsUsagesCollector extends UsagesCollector { } @NotNull - public Set getUsages() { - return ContainerUtil.map2Set(PluginManagerCore.getDisabledPlugins(), descriptor -> new UsageDescriptor(descriptor, 1)); + public Set getProjectUsages(@NotNull Project project) { + return VcsNamesUsagesCollector.getDescriptors(project); } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsNamesUsagesCollector.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsNamesUsagesCollector.java new file mode 100644 index 000000000000..c94986797525 --- /dev/null +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsNamesUsagesCollector.java @@ -0,0 +1,46 @@ +// 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.vcs.statistics; + +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.service.fus.collectors.ProjectUsagesCollector; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vcs.AbstractVcs; +import com.intellij.openapi.vcs.ProjectLevelVcsManager; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class VcsNamesUsagesCollector extends ProjectUsagesCollector { + + @NotNull + public String getGroupId() { + return "statistics.vcs.names"; + } + + @NotNull + public Set getUsages(@NotNull Project project) { + return getDescriptors(project); + } + + @NotNull + public static Set getDescriptors(@NotNull Project project) { + Set usages = new HashSet<>(); + + AbstractVcs[] activeVcss = ProjectLevelVcsManager.getInstance(project).getAllActiveVcss(); + List vcsNames = ContainerUtil.map(activeVcss, AbstractVcs::getName); + + for (String vcs : vcsNames) { + usages.add(new UsageDescriptor(vcs, 1)); + } + + if (vcsNames.size() > 1) { + usages.add(new UsageDescriptor(StringUtil.join(ContainerUtil.sorted(vcsNames), ","), 1)); + } + + return usages; + } +} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsOptionsUsagesCollector.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsOptionsUsagesCollector.java index ef7247fa90b4..b7bc07b0d402 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsOptionsUsagesCollector.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsOptionsUsagesCollector.java @@ -1,23 +1,8 @@ -/* - * 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.openapi.vcs.statistics; -import com.intellij.internal.statistic.AbstractProjectsUsagesCollector; -import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.service.fus.collectors.ProjectUsagesCollector; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.VcsConfiguration; import org.jetbrains.annotations.NotNull; @@ -28,16 +13,17 @@ import java.util.Set; import static com.intellij.internal.statistic.utils.StatisticsUtilKt.getBooleanUsage; import static com.intellij.internal.statistic.utils.StatisticsUtilKt.getEnumUsage; -public class VcsOptionsUsagesCollector extends AbstractProjectsUsagesCollector { - private static final String GROUP_ID = "vcs-options"; +public class VcsOptionsUsagesCollector extends ProjectUsagesCollector { + @NotNull + public String getGroupId() { return "statistics.vcs.options"; } @NotNull - public GroupDescriptor getGroupId() { - return GroupDescriptor.create(GROUP_ID); + public Set getUsages(@NotNull Project project) { + return getDescriptors(project); } @NotNull - public Set getProjectUsages(@NotNull Project project) { + public static Set getDescriptors(@NotNull Project project) { VcsConfiguration configuration = VcsConfiguration.getInstance(project); Set usages = new HashSet<>(); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatsUsagesCollector.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatsUsagesCollector.java index 98e3641ade70..a06c9fe629d2 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatsUsagesCollector.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatsUsagesCollector.java @@ -1,30 +1,32 @@ -// 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.openapi.vcs.statistics; -import com.intellij.internal.statistic.AbstractProjectsUsagesCollector; -import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.service.fus.collectors.ProjectUsagesCollector; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.changes.ChangeListManagerImpl; import com.intellij.openapi.vcs.ex.ProjectLevelVcsManagerEx; -import java.util.HashSet; import org.jetbrains.annotations.NotNull; +import java.util.HashSet; import java.util.Set; import static com.intellij.internal.statistic.utils.StatisticsUtilKt.getBooleanUsage; import static com.intellij.internal.statistic.utils.StatisticsUtilKt.getCountingUsage; -public class VcsStatsUsagesCollector extends AbstractProjectsUsagesCollector { - private static final String GROUP_ID = "vcs-stats"; - +public class VcsStatsUsagesCollector extends ProjectUsagesCollector { @NotNull - public GroupDescriptor getGroupId() { - return GroupDescriptor.create(GROUP_ID); + public String getGroupId() { + return "statistics.vcs.metrics"; } @NotNull - public Set getProjectUsages(@NotNull Project project) { + public Set getUsages(@NotNull Project project) { + return getDescriptors(project); + } + + @NotNull + public static Set getDescriptors(@NotNull Project project) { Set usages = new HashSet<>(); ChangeListManagerImpl clm = ChangeListManagerImpl.getInstanceImpl(project); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsUsagesCollector.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsUsagesCollector.java deleted file mode 100644 index 0e57ad30c39f..000000000000 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsUsagesCollector.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2000-2010 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.vcs.statistics; - -import com.intellij.internal.statistic.AbstractProjectsUsagesCollector; -import com.intellij.internal.statistic.beans.GroupDescriptor; -import com.intellij.internal.statistic.beans.UsageDescriptor; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vcs.AbstractVcs; -import com.intellij.openapi.vcs.ProjectLevelVcsManager; -import com.intellij.util.containers.ContainerUtil; -import org.jetbrains.annotations.NotNull; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -public class VcsUsagesCollector extends AbstractProjectsUsagesCollector { - private static final String GROUP_ID = "vcs"; - - @NotNull - public GroupDescriptor getGroupId() { - return GroupDescriptor.create(GROUP_ID, GroupDescriptor.HIGHER_PRIORITY); - } - - @NotNull - public Set getProjectUsages(@NotNull Project project) { - Set usages = new HashSet<>(); - - AbstractVcs[] activeVcss = ProjectLevelVcsManager.getInstance(project).getAllActiveVcss(); - List vcsNames = ContainerUtil.map(activeVcss, AbstractVcs::getName); - - for (String vcs : vcsNames) { - usages.add(new UsageDescriptor(vcs, 1)); - } - - if (vcsNames.size() > 1) { - usages.add(new UsageDescriptor(StringUtil.join(ContainerUtil.sorted(vcsNames), ","), 1)); - } - - return usages; - } -} diff --git a/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/BaseLineStatusTrackerManagerTest.kt b/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/BaseLineStatusTrackerManagerTest.kt new file mode 100644 index 000000000000..04a55cccb91c --- /dev/null +++ b/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/BaseLineStatusTrackerManagerTest.kt @@ -0,0 +1,261 @@ +// 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.vcs + +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.application.runWriteAction +import com.intellij.openapi.command.CommandProcessor +import com.intellij.openapi.editor.Document +import com.intellij.openapi.fileEditor.FileDocumentManager +import com.intellij.openapi.progress.ProgressIndicator +import com.intellij.openapi.project.Project +import com.intellij.openapi.vcs.BaseLineStatusTrackerTestCase.Companion.parseInput +import com.intellij.openapi.vcs.changes.* +import com.intellij.openapi.vcs.changes.committed.MockAbstractVcs +import com.intellij.openapi.vcs.ex.LineStatusTracker +import com.intellij.openapi.vcs.ex.PartialLocalLineStatusTracker +import com.intellij.openapi.vcs.ex.Range +import com.intellij.openapi.vcs.impl.LineStatusTrackerManager +import com.intellij.openapi.vcs.impl.ProjectLevelVcsManagerImpl +import com.intellij.openapi.vcs.impl.projectlevelman.AllVcses +import com.intellij.openapi.vfs.VfsUtil +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.testFramework.LightPlatformTestCase +import com.intellij.testFramework.RunAll +import com.intellij.util.ThrowableRunnable +import com.intellij.vcsUtil.VcsUtil + +abstract class BaseLineStatusTrackerManagerTest : LightPlatformTestCase() { + protected lateinit var vcs: MyMockVcs + protected lateinit var changeProvider: MyMockChangeProvider + + protected lateinit var clm: ChangeListManagerImpl + protected lateinit var lstm: LineStatusTrackerManager + protected lateinit var dirtyScopeManager: VcsDirtyScopeManagerImpl + + protected lateinit var testRoot: VirtualFile + + protected lateinit var vcsManager: ProjectLevelVcsManagerImpl + + protected var arePartialChangelistsSupported: Boolean = true + + override fun setUp() { + super.setUp() + testRoot = runWriteAction { + VfsUtil.markDirtyAndRefresh(false, false, true, ourProject.baseDir) + VfsUtil.createDirectoryIfMissing(ourProject.baseDir, getTestName(true)) + } + + vcs = MyMockVcs(ourProject) + changeProvider = MyMockChangeProvider() + vcs.changeProvider = changeProvider + + clm = ChangeListManagerImpl.getInstanceImpl(ourProject) + lstm = LineStatusTrackerManager.getInstanceImpl(ourProject) + dirtyScopeManager = VcsDirtyScopeManager.getInstance(ourProject) as VcsDirtyScopeManagerImpl + + vcsManager = ProjectLevelVcsManager.getInstance(ourProject) as ProjectLevelVcsManagerImpl + vcsManager.registerVcs(vcs) + vcsManager.directoryMappings = listOf(VcsDirectoryMapping(testRoot.path, vcs.name)) + vcsManager.waitForInitialized() + assertTrue(vcsManager.hasActiveVcss()) + + try { + resetTestState() + } + catch (e: Throwable) { + super.tearDown() + throw e + } + } + + override fun tearDown() { + RunAll() + .append(ThrowableRunnable { resetChanges() }) + .append(ThrowableRunnable { resetChangelists() }) + .append(ThrowableRunnable { resetSettings() }) + .append(ThrowableRunnable { lstm.releaseAllTrackers() }) + .append(ThrowableRunnable { vcsManager.directoryMappings = emptyList() }) + .append(ThrowableRunnable { AllVcses.getInstance(ourProject).unregisterManually(vcs) }) + .append(ThrowableRunnable { runWriteAction { testRoot.delete(this) } }) + .append(ThrowableRunnable { super.tearDown() }) + .run() + } + + protected fun resetTestState() { + resetChanges() + resetChangelists() + resetSettings() + resetTestRootContent() + } + + private fun resetTestRootContent() { + VfsUtil.markDirtyAndRefresh(false, true, true, testRoot) + runWriteAction { testRoot.children.forEach { child -> child.delete(this) } } + } + + private fun resetSettings() { + VcsApplicationSettings.getInstance().ENABLE_PARTIAL_CHANGELISTS = true + VcsApplicationSettings.getInstance().SHOW_LST_GUTTER_MARKERS = true + VcsApplicationSettings.getInstance().SHOW_WHITESPACES_IN_LST = true + arePartialChangelistsSupported = true + } + + private fun resetChanges() { + changeProvider.changes.clear() + changeProvider.files.clear() + clm.waitUntilRefreshed() + } + + private fun resetChangelists() { + clm.addChangeList(LocalChangeList.DEFAULT_NAME, null) + clm.setDefaultChangeList(LocalChangeList.DEFAULT_NAME) + for (changeListName in clm.changeLists.map { it.name }) { + if (changeListName != LocalChangeList.DEFAULT_NAME) clm.removeChangeList(changeListName) + } + clm.waitUntilRefreshed() + } + + + protected fun addLocalFile(name: String, content: String): VirtualFile { + val file = runWriteAction { + val file = testRoot.createChildData(this, name) + VfsUtil.saveText(file, parseInput(content)) + file + } + + assertFalse(changeProvider.files.contains(file)) + changeProvider.files.add(file) + return file + } + + protected fun removeLocalFile(name: String) { + val file = runWriteAction { + val file = VfsUtil.findRelativeFile(testRoot, name) + file!!.delete(this) + file + } + + assertTrue(changeProvider.files.contains(file)) + changeProvider.files.remove(file) + } + + protected fun setBaseVersion(name: String, baseContent: String?) { + val filePath = VcsUtil.getFilePath(testRoot, name) + + val contentRevision: ContentRevision? = when (baseContent) { + null -> null + else -> SimpleContentRevision(parseInput(baseContent), filePath, "HEAD") + } + + changeProvider.changes[filePath] = contentRevision + } + + protected fun removeBaseVersion(name: String) { + val filePath = VcsUtil.getFilePath(testRoot, name) + changeProvider.changes.remove(filePath) + } + + protected fun refreshCLM() { + dirtyScopeManager.markEverythingDirty() + clm.scheduleUpdate() + clm.waitUntilRefreshed() + } + + protected fun releaseUnneededTrackers() { + runWriteAction { } // LineStatusTrackerManager.MyApplicationListener.afterWriteActionFinished + } + + + protected val VirtualFile.change: Change? get() = clm.getChange(this) + protected val VirtualFile.tracker: LineStatusTracker<*>? get() = lstm.getLineStatusTracker(this) + protected val VirtualFile.document: Document get() = FileDocumentManager.getInstance().getDocument(this)!! + protected fun VirtualFile.withOpenedEditor(task: () -> Unit) { + lstm.requestTrackerFor(document, this) + try { + task() + } + finally { + lstm.releaseTrackerFor(document, this) + } + } + protected open fun runCommand(task: () -> Unit) { + CommandProcessor.getInstance().executeCommand(getProject(), { + ApplicationManager.getApplication().runWriteAction(task) + }, "", null) + } + + protected fun String.asListNameToList(): LocalChangeList = clm.changeLists.find { it.name == this }!! + protected fun String.asListNameToId(): String = asListNameToList().id + protected fun Array.asListNamesToIds() = this.map { it.asListNameToId() } + private fun changeListsNames() = clm.changeLists.map { it.name } + + protected fun PartialLocalLineStatusTracker.assertAffectedChangeLists(vararg expectedNames: String) { + assertSameElements(this.affectedChangeListsIds, expectedNames.asListNamesToIds()) + } + + protected fun Range.assertChangeList(listName: String) { + val localRange = this as PartialLocalLineStatusTracker.LocalRange + assertEquals(localRange.changelistId, listName.asListNameToId()) + } + + + protected fun createChangelist(listName: String) { + assertDoesntContain(changeListsNames(), listName) + clm.addChangeList(listName, null) + } + + protected fun removeChangeList(listName: String) { + assertContainsElements(changeListsNames(), listName) + clm.removeChangeList(listName) + } + + protected fun setDefaultChangeList(listName: String) { + clm.setDefaultChangeList(listName) + } + + protected fun VirtualFile.moveChanges(fromListName: String, toListName: String) { + assertContainsElements(changeListsNames(), fromListName) + assertContainsElements(changeListsNames(), toListName) + val listChange = fromListName.asListNameToList().changes.find { it == this.change!! }!! + clm.moveChangesTo(toListName.asListNameToList(), listChange) + } + + protected fun VirtualFile.moveAllChangesTo(toListName: String) { + assertContainsElements(changeListsNames(), toListName) + clm.moveChangesTo(toListName.asListNameToList(), this.change!!) + } + + + protected class MyMockChangeProvider : ChangeProvider { + val changes = mutableMapOf() + val files = mutableSetOf() + + override fun getChanges(dirtyScope: VcsDirtyScope, + builder: ChangelistBuilder, + progress: ProgressIndicator, + addGate: ChangeListManagerGate) { + for ((filePath, beforeRevision) in changes) { + val file = files.find { VcsUtil.getFilePath(it) == filePath } + val afterContent: ContentRevision? = when (file) { + null -> null + else -> CurrentContentRevision(filePath) + } + + val change = Change(beforeRevision, afterContent) + + builder.processChange(change, MockAbstractVcs.getKey()) + } + } + + override fun isModifiedDocumentTrackingRequired(): Boolean { + return false + } + + override fun doCleanup(files: List) { + } + } + + protected inner class MyMockVcs(project: Project) : MockAbstractVcs(project) { + override fun arePartialChangelistsSupported(): Boolean = arePartialChangelistsSupported + } +} \ No newline at end of file diff --git a/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/BaseLineStatusTrackerTestCase.kt b/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/BaseLineStatusTrackerTestCase.kt index 72c82fff985a..21e09e1929b1 100644 --- a/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/BaseLineStatusTrackerTestCase.kt +++ b/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/BaseLineStatusTrackerTestCase.kt @@ -20,9 +20,7 @@ import com.intellij.diff.comparison.iterables.DiffIterableUtil.fair import com.intellij.diff.tools.util.text.LineOffsetsUtil import com.intellij.diff.util.DiffUtil import com.intellij.diff.util.Side -import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.runWriteAction -import com.intellij.openapi.command.CommandProcessor import com.intellij.openapi.editor.Document import com.intellij.openapi.editor.impl.DocumentImpl import com.intellij.openapi.fileEditor.FileDocumentManager @@ -30,29 +28,25 @@ import com.intellij.openapi.fileTypes.PlainTextFileType import com.intellij.openapi.util.Comparing import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.vcs.changes.ChangeListManagerImpl -import com.intellij.openapi.vcs.changes.LocalChangeList import com.intellij.openapi.vcs.ex.* import com.intellij.openapi.vcs.ex.LineStatusTracker.Mode import com.intellij.openapi.vfs.VirtualFile -import com.intellij.testFramework.LightPlatformTestCase import com.intellij.testFramework.LightPlatformTestCase.assertOrderedEquals import com.intellij.testFramework.LightVirtualFile import com.intellij.util.containers.ContainerUtil import java.util.* -private typealias DiffRange = com.intellij.diff.util.Range - -abstract class BaseLineStatusTrackerTestCase : LightPlatformTestCase() { +abstract class BaseLineStatusTrackerTestCase : BaseLineStatusTrackerManagerTest() { protected fun test(text: String, task: Test.() -> Unit) { test(text, text, false, task) } protected fun test(text: String, vcsText: String, smart: Boolean = false, task: Test.() -> Unit) { - val mode = if (smart) Mode.SMART else Mode.DEFAULT - doTest(text, vcsText, - { document, file -> SimpleLocalLineStatusTracker.createTracker(getProject(), document, file, mode) }, - { tracker -> Test(tracker) }, - task) + resetTestState() + VcsApplicationSettings.getInstance().SHOW_WHITESPACES_IN_LST = smart + arePartialChangelistsSupported = false + + doTest(text, vcsText, { tracker -> Test(tracker as SimpleLocalLineStatusTracker) }, task) } protected fun testPartial(text: String, task: PartialTest.() -> Unit) { @@ -60,32 +54,43 @@ abstract class BaseLineStatusTrackerTestCase : LightPlatformTestCase() { } protected fun testPartial(text: String, vcsText: String, task: PartialTest.() -> Unit) { - doTest(text, vcsText, - { document, file -> PartialLocalLineStatusTracker.createTracker(getProject(), document, file, Mode.SMART) }, - { tracker -> PartialTest(tracker) }, - task) + resetTestState() + + doTest(text, vcsText, { tracker -> PartialTest(tracker as PartialLocalLineStatusTracker) }, task) } - protected fun , TestHelper : Test> doTest(text: String, vcsText: String, - createTracker: (Document, VirtualFile) -> Tracker, - createTestHelper: (Tracker) -> TestHelper, - task: TestHelper.() -> Unit) { + private fun doTest(text: String, vcsText: String, + createTestHelper: (LineStatusTracker<*>) -> TestHelper, + task: TestHelper.() -> Unit) { + val fileName = "file.txt" + val file = addLocalFile(fileName, parseInput(text)) + setBaseVersion(fileName, parseInput(vcsText)) + refreshCLM() + + file.withOpenedEditor { + lstm.waitUntilBaseContentsLoaded() + + val testHelper = createTestHelper(file.tracker!!) + testHelper.verify() + task(testHelper) + testHelper.verify() + } + } + + protected fun lightTest(text: String, vcsText: String, smart: Boolean = false, task: Test.() -> Unit) { val file = LightVirtualFile("LSTTestFile", PlainTextFileType.INSTANCE, parseInput(text)) val document = FileDocumentManager.getInstance().getDocument(file)!! val tracker = runWriteAction { - val tracker = createTracker(document, file) + val tracker = SimpleLocalLineStatusTracker.createTracker(getProject(), document, file, if (smart) Mode.SMART else Mode.DEFAULT) tracker.setBaseRevision(parseInput(vcsText)) tracker } try { - val testHelper = createTestHelper(tracker) + val testHelper = Test(tracker) testHelper.verify() - task(testHelper) - testHelper.verify() - testHelper.destroy() } finally { tracker.release() @@ -93,15 +98,12 @@ abstract class BaseLineStatusTrackerTestCase : LightPlatformTestCase() { } - protected open class Test(val tracker: LineStatusTracker<*>) { + protected open inner class Test(val tracker: LineStatusTracker<*>) { val file: VirtualFile = tracker.virtualFile val document: Document = tracker.document val vcsDocument: Document = tracker.vcsDocument private val documentTracker = tracker.getDocumentTrackerInTestMode() - open fun destroy() { - } - fun assertHelperContentIs(expected: String, helper: PartialLocalLineStatusTracker.PartialCommitHelper) { assertEquals(parseInput(expected), helper.content) } @@ -129,36 +131,33 @@ abstract class BaseLineStatusTrackerTestCase : LightPlatformTestCase() { } - fun runCommand(task: () -> Unit) { - CommandProcessor.getInstance().executeCommand(getProject(), { - ApplicationManager.getApplication().runWriteAction(task) - }, "", null) - + fun runCommandVerify(task: () -> Unit) { + this@BaseLineStatusTrackerTestCase.runCommand(task) verify() } fun insertAtStart(text: String) { - runCommand { document.insertString(0, parseInput(text)) } + runCommandVerify { document.insertString(0, parseInput(text)) } } fun TestRange.insertBefore(text: String) { - runCommand { document.insertString(this.start, parseInput(text)) } + runCommandVerify { document.insertString(this.start, parseInput(text)) } } fun TestRange.insertAfter(text: String) { - runCommand { document.insertString(this.end, parseInput(text)) } + runCommandVerify { document.insertString(this.end, parseInput(text)) } } fun TestRange.delete() { - runCommand { document.deleteString(this.start, this.end) } + runCommandVerify { document.deleteString(this.start, this.end) } } fun TestRange.replace(text: String) { - runCommand { document.replaceString(this.start, this.end, parseInput(text)) } + runCommandVerify { document.replaceString(this.start, this.end, parseInput(text)) } } fun replaceWholeText(text: String) { - runCommand { document.replaceString(0, document.textLength, parseInput(text)) } + runCommandVerify { document.replaceString(0, document.textLength, parseInput(text)) } } fun stripTrailingSpaces() { @@ -171,7 +170,7 @@ abstract class BaseLineStatusTrackerTestCase : LightPlatformTestCase() { } fun rollbackLines(lines: BitSet) { - runCommand { tracker.rollbackChanges(lines) } + runCommandVerify { tracker.rollbackChanges(lines) } } @@ -198,7 +197,7 @@ abstract class BaseLineStatusTrackerTestCase : LightPlatformTestCase() { operator fun Int.not(): Helper = Helper(this) operator fun Helper.minus(end: Int): TestRange = TestRange(this.start, end) - class Helper(val start: Int) + inner class Helper(val start: Int) infix fun String.at(range: TestRange): TestRange { assertEquals(parseInput(this), range.text) @@ -273,7 +272,7 @@ abstract class BaseLineStatusTrackerTestCase : LightPlatformTestCase() { } fun Range.rollback() { - runCommand { + runCommandVerify { tracker.rollbackChanges(this) } } @@ -373,68 +372,22 @@ abstract class BaseLineStatusTrackerTestCase : LightPlatformTestCase() { private fun getCurrentLines(range: Range): List = DiffUtil.getLines(document, range.line1, range.line2) } - protected class PartialTest(val partialTracker: PartialLocalLineStatusTracker) : Test(partialTracker) { + protected inner class PartialTest(val partialTracker: PartialLocalLineStatusTracker) : Test(partialTracker) { private val clm = ChangeListManagerImpl.getInstanceImpl(getProject()) - init { - resetChangelists() - partialTracker.initChangeTracking(defaultChangeListIds(), changeListIds(), null) + + fun assertAffectedChangeLists(vararg expected: String) { + partialTracker.assertAffectedChangeLists(*expected) } - override fun destroy() { - resetChangelists() - } - - private fun resetChangelists() { - clm.addChangeList(LocalChangeList.DEFAULT_NAME, null) - clm.setDefaultChangeList(LocalChangeList.DEFAULT_NAME) - for (changeListName in changeListNames()) { - if (changeListName != LocalChangeList.DEFAULT_NAME) clm.removeChangeList(changeListName) - } - } - - - fun assertAffectedChangelists(vararg expected: String) { - assertSameElements(partialTracker.affectedChangeListsIds, expected.toListId()) - } - - fun Range.assertChangelist(list: String) { - val localRange = this as PartialLocalLineStatusTracker.LocalRange - assertEquals(localRange.changelistId, list.toListId()) - } - - - fun createChangelist(list: String) { - assertDoesntContain(changeListNames(), list) + fun createChangeList_SetDefault(list: String) { clm.addChangeList(list, null) - } - - fun removeChangelist(list: String) { - assertContainsElements(changeListNames(), list) - partialTracker.changeListRemoved(list.toListId()) - clm.removeChangeList(list) - } - - fun setDefaultChangelist(list: String) { - clm.addChangeList(list, null) - partialTracker.defaultListChanged(defaultChangeListIds(), list.toListId()) clm.setDefaultChangeList(list) } fun handlePartialCommit(side: Side, list: String): PartialLocalLineStatusTracker.PartialCommitHelper { - return partialTracker.handlePartialCommit(side, listOf(list.toListId())) - } - - fun moveChanges(fromList: String, toList: String) { - assertContainsElements(changeListNames(), fromList) - assertContainsElements(changeListNames(), toList) - partialTracker.moveChanges(fromList.toListId(), toList.toListId()) - } - - fun moveAllChangesTo(toList: String) { - assertContainsElements(changeListNames(), toList) - partialTracker.moveChangesTo(toList.toListId()) + return partialTracker.handlePartialCommit(side, listOf(list.asListNameToId())) } @@ -447,13 +400,6 @@ abstract class BaseLineStatusTrackerTestCase : LightPlatformTestCase() { val changeList = clm.addChangeList(list, null) partialTracker.moveToChangelist(lines, changeList) } - - - fun String.toListId(): String = clm.changeLists.find { it.name == this }!!.id - private fun Array.toListId() = this.map { it.toListId() } - private fun changeListIds() = clm.changeLists.map { it.id } - private fun changeListNames() = clm.changeLists.map { it.name } - private fun defaultChangeListIds() = clm.defaultChangeList.id } companion object { diff --git a/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/LineStatusTrackerManagerTest.kt b/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/LineStatusTrackerManagerTest.kt new file mode 100644 index 000000000000..ba2fe3807815 --- /dev/null +++ b/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/LineStatusTrackerManagerTest.kt @@ -0,0 +1,335 @@ +// 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.vcs + +import com.intellij.openapi.vcs.changes.Change +import com.intellij.openapi.vcs.ex.PartialLocalLineStatusTracker +import com.intellij.openapi.vcs.ex.SimpleLocalLineStatusTracker + +class LineStatusTrackerManagerTest : BaseLineStatusTrackerManagerTest() { + private val FILE_1 = "file1.txt" + private val FILE_2 = "file2.txt" + + fun `test mock changes`() { + setBaseVersion(FILE_1, "oldText") + refreshCLM() + assertEquals(1, clm.allChanges.size) + assertEquals(Change.Type.DELETED, clm.allChanges.first().type) + + addLocalFile(FILE_1, "text") + setBaseVersion(FILE_1, null) + refreshCLM() + assertEquals(1, clm.allChanges.size) + assertEquals(Change.Type.NEW, clm.allChanges.first().type) + + setBaseVersion(FILE_1, "oldText") + refreshCLM() + assertEquals(1, clm.allChanges.size) + assertEquals(Change.Type.MODIFICATION, clm.allChanges.first().type) + + removeLocalFile(FILE_1) + refreshCLM() + assertEquals(1, clm.allChanges.size) + assertEquals(Change.Type.DELETED, clm.allChanges.first().type) + + removeBaseVersion(FILE_1) + refreshCLM() + assertEquals(0, clm.allChanges.size) + + setBaseVersion(FILE_1, "oldText") + setBaseVersion(FILE_2, "oldText") + refreshCLM() + assertEquals(2, clm.allChanges.size) + } + + fun `test partial tracker lifecycle - editor for unchanged file`() { + createChangelist("Test") + val file = addLocalFile(FILE_1, "a_b_c_d_e") + assertNull(file.tracker) + + file.withOpenedEditor { + val tracker = file.tracker + assertNotNull(tracker) + assertTrue(tracker is SimpleLocalLineStatusTracker) + } + assertNull(file.tracker) + } + + fun `test partial tracker lifecycle - editor for modified file`() { + createChangelist("Test") + val file = addLocalFile(FILE_1, "a_b_c_d_e") + setBaseVersion(FILE_1, "a_b1_c_d1_e") + refreshCLM() + assertNull(file.tracker) + + file.withOpenedEditor { + val tracker = file.tracker + assertNotNull(tracker) + assertTrue(tracker is PartialLocalLineStatusTracker) + } + assertNotNull(file.tracker) + + lstm.waitUntilBaseContentsLoaded() + assertNull(file.tracker) + + file.withOpenedEditor { + val tracker = file.tracker + assertNotNull(tracker) + assertTrue(tracker is PartialLocalLineStatusTracker) + + lstm.waitUntilBaseContentsLoaded() + assertNotNull(file.tracker) + } + assertNull(file.tracker) + } + + fun `test partial tracker lifecycle - multiple editors`() { + createChangelist("Test") + val file = addLocalFile(FILE_1, "a_b_c_d_e") + setBaseVersion(FILE_1, "a_b1_c_d1_e") + refreshCLM() + assertNull(file.tracker) + + val requester1 = Any() + val requester2 = Any() + + lstm.requestTrackerFor(file.document, requester1) + assertNotNull(file.tracker) + + lstm.waitUntilBaseContentsLoaded() + lstm.requestTrackerFor(file.document, requester2) + assertNotNull(file.tracker) + + lstm.releaseTrackerFor(file.document, requester1) + assertNotNull(file.tracker) + + lstm.releaseTrackerFor(file.document, requester2) + assertNull(file.tracker) + } + + fun `test partial tracker lifecycle - with partial changes without editor`() { + createChangelist("Test") + val file = addLocalFile(FILE_1, "a_b_c_d_e") + setBaseVersion(FILE_1, "a_b1_c_d1_e") + refreshCLM() + assertNull(file.tracker) + + file.withOpenedEditor { + val tracker = file.tracker as PartialLocalLineStatusTracker + lstm.waitUntilBaseContentsLoaded() + + val ranges = tracker.getRanges()!! + assertEquals(2, ranges.size) + tracker.moveToChangelist(ranges[0], "Test".asListNameToList()) + tracker.assertAffectedChangeLists("Default", "Test") + } + assertNotNull(file.tracker) + + clm.waitUntilRefreshed() + releaseUnneededTrackers() + assertNotNull(file.tracker) + + file.moveAllChangesTo("Test") + clm.waitUntilRefreshed() + releaseUnneededTrackers() // partial tracker is not released immediately after becoming redundant + assertNull(file.tracker) + } + + fun `test tracker from non-default changelist`() { + createChangelist("Test") + + val file = addLocalFile(FILE_1, "a_b_c_d_e") + setBaseVersion(FILE_1, "a_b1_c_d1_e") + refreshCLM() + + file.moveAllChangesTo("Test") + clm.waitUntilRefreshed() + + file.withOpenedEditor { + val tracker = file.tracker as PartialLocalLineStatusTracker + lstm.waitUntilBaseContentsLoaded() + + tracker.assertAffectedChangeLists("Test") + } + } + + fun `test tracker from non-default changelist - modified during initialisation`() { + createChangelist("Test") + + val file = addLocalFile(FILE_1, "a_b_c_d_e") + setBaseVersion(FILE_1, "a_b_c_d1_e") + refreshCLM() + + file.moveAllChangesTo("Test") + clm.waitUntilRefreshed() + + file.withOpenedEditor { + val tracker = file.tracker as PartialLocalLineStatusTracker + runCommand { tracker.document.replaceString(0, 1, "a2") } + + lstm.waitUntilBaseContentsLoaded() + + tracker.assertAffectedChangeLists("Test", "Default") + } + } + + fun `test tracker changes moves`() { + createChangelist("Test #1") + createChangelist("Test #2") + + val file = addLocalFile(FILE_1, "a_b_c_d_e") + setBaseVersion(FILE_1, "a_b1_c_d1_e") + refreshCLM() + + file.moveAllChangesTo("Test #2") + assertNull(file.tracker) + + file.withOpenedEditor { + val tracker = file.tracker as PartialLocalLineStatusTracker + lstm.waitUntilBaseContentsLoaded() + assertEquals(2, tracker.getRanges()!!.size) + tracker.assertAffectedChangeLists("Test #2") + + file.moveAllChangesTo("Test #1") + tracker.assertAffectedChangeLists("Test #1") + + tracker.moveToChangelist(tracker.getRanges()!![0], "Test #2".asListNameToList()) + tracker.assertAffectedChangeLists("Test #1", "Test #2") + + file.moveChanges("Test #2", "Default") + tracker.assertAffectedChangeLists("Test #1", "Default") + + file.moveAllChangesTo("Test #2") + tracker.assertAffectedChangeLists("Test #2") + } + } + + fun `test tracker changes moves - empty tracker`() { + createChangelist("Test #1") + createChangelist("Test #2") + + val file = addLocalFile(FILE_1, "a_b_c_d_e") + setBaseVersion(FILE_1, "a_b_c_d_e") + refreshCLM() + + file.moveAllChangesTo("Test #2") + + file.withOpenedEditor { + val tracker = file.tracker as PartialLocalLineStatusTracker + lstm.waitUntilBaseContentsLoaded() + assertEquals(0, tracker.getRanges()!!.size) + tracker.assertAffectedChangeLists("Test #2") + + file.moveAllChangesTo("Test #1") + tracker.assertAffectedChangeLists("Test #1") + + file.moveAllChangesTo("Test #2") + tracker.assertAffectedChangeLists("Test #2") + + runCommand { tracker.document.replaceString(0, 1, "a2") } + tracker.assertAffectedChangeLists("Default") + } + } + + fun `test tracker before initialisation - no changed lines in vcs, local changes reverted`() { + createChangelist("Test") + + val file = addLocalFile(FILE_1, "a_b_c_d_e") + setBaseVersion(FILE_1, "a_b_c_d_e") + refreshCLM() + file.moveAllChangesTo("Test") + + file.withOpenedEditor { + val tracker = file.tracker as PartialLocalLineStatusTracker + + tracker.assertAffectedChangeLists("Test") + + runCommand { tracker.document.replaceString(0, 1, "a2") } + tracker.assertAffectedChangeLists("Default", "Test") + + runCommand { tracker.document.replaceString(0, 2, "a") } + tracker.assertAffectedChangeLists("Test") + + assertFalse(tracker.isOperational()) + assertNull(tracker.getRanges()) + + lstm.waitUntilBaseContentsLoaded() + assertEquals(0, tracker.getRanges()!!.size) + tracker.assertAffectedChangeLists("Test") + } + } + + fun `test tracker before initialisation - typing`() { + createChangelist("Test") + + val file = addLocalFile(FILE_1, "a_b_c_d_e") + setBaseVersion(FILE_1, "a_b_c_d_e2") + refreshCLM() + file.moveAllChangesTo("Test") + + file.withOpenedEditor { + val tracker = file.tracker as PartialLocalLineStatusTracker + + tracker.assertAffectedChangeLists("Test") + + runCommand { tracker.document.replaceString(0, 1, "a2") } + tracker.assertAffectedChangeLists("Default", "Test") + + assertFalse(tracker.isOperational()) + assertNull(tracker.getRanges()) + + lstm.waitUntilBaseContentsLoaded() + assertEquals(2, tracker.getRanges()!!.size) + tracker.assertAffectedChangeLists("Default", "Test") + } + } + + fun `test tracker before initialisation - no changed lines in vcs`() { + createChangelist("Test") + + val file = addLocalFile(FILE_1, "a_b_c_d_e") + setBaseVersion(FILE_1, "a_b_c_d_e") + refreshCLM() + file.moveAllChangesTo("Test") + + file.withOpenedEditor { + val tracker = file.tracker as PartialLocalLineStatusTracker + + tracker.assertAffectedChangeLists("Test") + + runCommand { tracker.document.replaceString(0, 1, "a2") } + tracker.assertAffectedChangeLists("Default", "Test") + + assertFalse(tracker.isOperational()) + assertNull(tracker.getRanges()) + + lstm.waitUntilBaseContentsLoaded() + assertEquals(1, tracker.getRanges()!!.size) + tracker.assertAffectedChangeLists("Default") + } + } + + fun `test tracker before initialisation - old local changes reverted`() { + createChangelist("Test") + + val file = addLocalFile(FILE_1, "a2_b_c_d_e") + setBaseVersion(FILE_1, "a_b_c_d_e") + refreshCLM() + file.moveAllChangesTo("Test") + + file.withOpenedEditor { + val tracker = file.tracker as PartialLocalLineStatusTracker + + tracker.assertAffectedChangeLists("Test") + + runCommand { tracker.document.replaceString(0, 2, "a") } + tracker.assertAffectedChangeLists("Default", "Test") + + assertFalse(tracker.isOperational()) + assertNull(tracker.getRanges()) + + lstm.waitUntilBaseContentsLoaded() + assertEquals(0, tracker.getRanges()!!.size) + tracker.assertAffectedChangeLists("Default") + } + } +} \ No newline at end of file diff --git a/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/LineStatusTrackerModifyDocumentTest.kt b/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/LineStatusTrackerModifyDocumentTest.kt index 962c2714a275..68868f4f8864 100644 --- a/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/LineStatusTrackerModifyDocumentTest.kt +++ b/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/LineStatusTrackerModifyDocumentTest.kt @@ -664,12 +664,12 @@ class LineStatusTrackerModifyDocumentTest : BaseLineStatusTrackerTestCase() { tracker.doFrozen(Runnable { assertNull(tracker.getRanges()) - runCommand { + runCommandVerify { document.setText("") document.setText("Y") } - runCommand { + runCommandVerify { document.setText("X\nX\nX\nX") } @@ -687,12 +687,12 @@ class LineStatusTrackerModifyDocumentTest : BaseLineStatusTrackerTestCase() { tracker.doFrozen(Runnable { assertNull(tracker.getRanges()) - runCommand { + runCommandVerify { document.setText("") document.setText("Y") } - runCommand { + runCommandVerify { document.setText(parseInput("Y_X_X_X_X")) } @@ -711,7 +711,7 @@ class LineStatusTrackerModifyDocumentTest : BaseLineStatusTrackerTestCase() { assertNull(tracker.getRanges()) tracker.doFrozen(Runnable { - runCommand { + runCommandVerify { document.setText("") document.setText("Y") } @@ -720,7 +720,7 @@ class LineStatusTrackerModifyDocumentTest : BaseLineStatusTrackerTestCase() { }) assertNull(tracker.getRanges()) - runCommand { + runCommandVerify { document.setText("X\nX\nX\nX") } @@ -740,7 +740,7 @@ class LineStatusTrackerModifyDocumentTest : BaseLineStatusTrackerTestCase() { tracker.setBaseRevision(parseInput("X_X_X_Z_Z")) - runCommand { + runCommandVerify { document.setText(parseInput("Y_X_X_X_X_Z_Z")) } diff --git a/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/LineStatusTrackerRevertAutoTest.kt b/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/LineStatusTrackerRevertAutoTest.kt index 2599a7bdb631..c08d4a554b86 100644 --- a/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/LineStatusTrackerRevertAutoTest.kt +++ b/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/LineStatusTrackerRevertAutoTest.kt @@ -63,13 +63,13 @@ class LineStatusTrackerRevertAutoTest : BaseLineStatusTrackerTestCase() { if (i % 1000 == 0) LOG.debug(i.toString()) try { val initial = generateText(textLength) - test(initial, initial, smart) { + lightTest(initial, initial, smart) { // println("Initial: " + initial.replace("\n", "\\n")); val count = myRng.nextInt(modifications) for (j in 0 until count) { val writeChanges = myRng.nextInt(4) + 1 - runCommand { + runCommandVerify { for (k in 0 until writeChanges) { applyRandomChange(changeLength) } @@ -110,7 +110,7 @@ class LineStatusTrackerRevertAutoTest : BaseLineStatusTrackerTestCase() { try { val initial = generateText(textLength) val initialVcs = generateText(textLength) - test(initial, initialVcs, smart) { + lightTest(initial, initialVcs, smart) { checkRevert(tracker.getRanges()!!.size * 2) } diff --git a/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/PartialLineStatusTrackerTest.kt b/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/PartialLineStatusTrackerTest.kt index 881e7750e56a..61d1dff22f92 100644 --- a/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/PartialLineStatusTrackerTest.kt +++ b/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/PartialLineStatusTrackerTest.kt @@ -11,8 +11,8 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() { testPartial("1234_2345_3456") { "12".insertAfter("a") - range().assertChangelist("Default") - assertAffectedChangelists("Default") + range().assertChangeList("Default") + assertAffectedChangeLists("Default") } } @@ -20,19 +20,19 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() { testPartial("1234_2345_3456") { "12".insertAfter("a") - range().assertChangelist("Default") + range().assertChangeList("Default") - setDefaultChangelist("Test") + createChangeList_SetDefault("Test") "12".insertBefore("X_Y_Z") - range().assertChangelist("Default") - assertAffectedChangelists("Default") + range().assertChangeList("Default") + assertAffectedChangeLists("Default") "3456".replace("X_Y_Z") - range(0).assertChangelist("Default") - range(1).assertChangelist("Test") - assertAffectedChangelists("Default", "Test") + range(0).assertChangeList("Default") + range(1).assertChangeList("Test") + assertAffectedChangeLists("Default", "Test") } } @@ -40,24 +40,24 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() { testPartial("1234_2345_3456") { "12".insertAfter("a") - range().assertChangelist("Default") - assertAffectedChangelists("Default") + range().assertChangeList("Default") + assertAffectedChangeLists("Default") - setDefaultChangelist("Test") + createChangeList_SetDefault("Test") - range().assertChangelist("Default") - assertAffectedChangelists("Default") + range().assertChangeList("Default") + assertAffectedChangeLists("Default") "56".insertAfter("b") - range(0).assertChangelist("Default") - range(1).assertChangelist("Test") - assertAffectedChangelists("Default", "Test") + range(0).assertChangeList("Default") + range(1).assertChangeList("Test") + assertAffectedChangeLists("Default", "Test") "2345".insertAfter("c") - range().assertChangelist("Test") - assertAffectedChangelists("Test") + range().assertChangeList("Test") + assertAffectedChangeLists("Test") } } @@ -65,24 +65,24 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() { testPartial("1234_2345_3456") { "12".insertAfter("a") - range().assertChangelist("Default") - assertAffectedChangelists("Default") + range().assertChangeList("Default") + assertAffectedChangeLists("Default") - setDefaultChangelist("Test") + createChangeList_SetDefault("Test") - range().assertChangelist("Default") - assertAffectedChangelists("Default") + range().assertChangeList("Default") + assertAffectedChangeLists("Default") "56".insertAfter("b") - range(0).assertChangelist("Default") - range(1).assertChangelist("Test") - assertAffectedChangelists("Default", "Test") + range(0).assertChangeList("Default") + range(1).assertChangeList("Test") + assertAffectedChangeLists("Default", "Test") "2345_".delete() - range().assertChangelist("Test") - assertAffectedChangelists("Test") + range().assertChangeList("Test") + assertAffectedChangeLists("Test") } } @@ -90,14 +90,14 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() { testPartial("1234_2345_3456") { "12".insertAfter("a") - range().assertChangelist("Default") - assertAffectedChangelists("Default") + range().assertChangeList("Default") + assertAffectedChangeLists("Default") createChangelist("Test") range().moveTo("Test") - range().assertChangelist("Test") - assertAffectedChangelists("Test") + range().assertChangeList("Test") + assertAffectedChangeLists("Test") } } @@ -105,31 +105,31 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() { testPartial("1234_2345_3456") { "12".insertAfter("a") - range().assertChangelist("Default") - assertAffectedChangelists("Default") + range().assertChangeList("Default") + assertAffectedChangeLists("Default") - setDefaultChangelist("Test") + createChangeList_SetDefault("Test") - range().assertChangelist("Default") - assertAffectedChangelists("Default") + range().assertChangeList("Default") + assertAffectedChangeLists("Default") "56".insertAfter("b") - range(0).assertChangelist("Default") - range(1).assertChangelist("Test") - assertAffectedChangelists("Default", "Test") + range(0).assertChangeList("Default") + range(1).assertChangeList("Test") + assertAffectedChangeLists("Default", "Test") range(0).moveTo("Test") - range(0).assertChangelist("Test") - range(1).assertChangelist("Test") - assertAffectedChangelists("Test") + range(0).assertChangeList("Test") + range(1).assertChangeList("Test") + assertAffectedChangeLists("Test") range(1).moveTo("Default") - range(0).assertChangelist("Test") - range(1).assertChangelist("Default") - assertAffectedChangelists("Default", "Test") + range(0).assertChangeList("Test") + range(1).assertChangeList("Default") + assertAffectedChangeLists("Default", "Test") } } @@ -137,25 +137,25 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() { testPartial("1234_2345_3456") { "12".insertAfter("a") - range().assertChangelist("Default") - assertAffectedChangelists("Default") + range().assertChangeList("Default") + assertAffectedChangeLists("Default") - setDefaultChangelist("Test") + createChangeList_SetDefault("Test") - range().assertChangelist("Default") - assertAffectedChangelists("Default") + range().assertChangeList("Default") + assertAffectedChangeLists("Default") "56".insertAfter("b") - range(0).assertChangelist("Default") - range(1).assertChangelist("Test") - assertAffectedChangelists("Default", "Test") + range(0).assertChangeList("Default") + range(1).assertChangeList("Test") + assertAffectedChangeLists("Default", "Test") - removeChangelist("Default") + removeChangeList("Default") - range(0).assertChangelist("Test") - range(1).assertChangelist("Test") - assertAffectedChangelists("Test") + range(0).assertChangeList("Test") + range(1).assertChangeList("Test") + assertAffectedChangeLists("Test") } } @@ -184,7 +184,7 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() { testPartial("A_ _C_D_E_") { "A".replace("C_D_E") - setDefaultChangelist("Test") + createChangeList_SetDefault("Test") (2 th "C_D_E_").delete() assertTextContentIs("C_D_E_ _") @@ -203,7 +203,7 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() { assertTextContentIs("A_B1_C_E_F_M_G_N_H_") assertBaseTextContentIs("A_B_C_D_E_F_G_H_") - assertAffectedChangelists("Default", "Test") + assertAffectedChangeLists("Default", "Test") val helper = handlePartialCommit(Side.LEFT, "Test") helper.applyChanges() @@ -211,7 +211,7 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() { assertHelperContentIs("A_B_C_E_F_G_N_H_", helper) assertTextContentIs("A_B1_C_E_F_M_G_N_H_") assertBaseTextContentIs("A_B_C_E_F_G_N_H_") - assertAffectedChangelists("Default") + assertAffectedChangeLists("Default") } } @@ -226,7 +226,7 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() { assertTextContentIs("A_B1_C_E_F_M_G_N_H_") assertBaseTextContentIs("A_B_C_D_E_F_G_H_") - assertAffectedChangelists("Default", "Test") + assertAffectedChangeLists("Default", "Test") val helper = handlePartialCommit(Side.LEFT, "Default") helper.applyChanges() @@ -234,7 +234,7 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() { assertHelperContentIs("A_B1_C_D_E_F_M_G_H_", helper) assertTextContentIs("A_B1_C_E_F_M_G_N_H_") assertBaseTextContentIs("A_B1_C_D_E_F_M_G_H_") - assertAffectedChangelists("Test") + assertAffectedChangeLists("Test") } } @@ -249,7 +249,7 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() { assertTextContentIs("A_B1_C_E_F_M_G_N_H_") assertBaseTextContentIs("A_B_C_D_E_F_G_H_") - assertAffectedChangelists("Default", "Test") + assertAffectedChangeLists("Default", "Test") val helper = handlePartialCommit(Side.RIGHT, "Test") helper.applyChanges() @@ -257,7 +257,7 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() { assertHelperContentIs("A_B1_C_D_E_F_M_G_H_", helper) assertTextContentIs("A_B1_C_D_E_F_M_G_H_") assertBaseTextContentIs("A_B_C_D_E_F_G_H_") - assertAffectedChangelists("Default") + assertAffectedChangeLists("Default") } } @@ -272,10 +272,10 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() { assertTextContentIs("A_B1_C_E_F_M_G_N_H_") assertBaseTextContentIs("A_B_C_D_E_F_G_H_") - assertAffectedChangelists("Default", "Test") + assertAffectedChangeLists("Default", "Test") tracker.doFrozen(Runnable { - runCommand { + runCommandVerify { "B1_".replace("X_Y_Z_") val helper = handlePartialCommit(Side.LEFT, "Default") @@ -284,7 +284,7 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() { assertHelperContentIs("A_X_Y_Z_C_D_E_F_M_G_H_", helper) assertTextContentIs("A_X_Y_Z_C_E_F_M_G_N_H_") assertBaseTextContentIs("A_X_Y_Z_C_D_E_F_M_G_H_") - assertAffectedChangelists("Test") + assertAffectedChangeLists("Test") } }) } @@ -301,10 +301,10 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() { assertTextContentIs("A_B1_C_E_F_M_G_N_H_") assertBaseTextContentIs("A_B_C_D_E_F_G_H_") - assertAffectedChangelists("Default", "Test") + assertAffectedChangeLists("Default", "Test") tracker.doFrozen(Runnable { - runCommand { + runCommandVerify { "B1_".replace("X_Y_Z_") val helper = handlePartialCommit(Side.LEFT, "Default") @@ -321,7 +321,7 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() { assertHelperContentIs("A_X_Y_Z_C_D_E_F_M_G_H_", helper) assertTextContentIs("A_X_Y_Z_C_E_F_M2_G_N2_H_") assertBaseTextContentIs("A_X_Y_Z_C_D_E_F_M_G_H_") - assertAffectedChangelists("Test") + assertAffectedChangeLists("Test") } }) } diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/GrNumberConverter.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/GrNumberConverter.java index 275a83bd3ea9..4881e05acecb 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/GrNumberConverter.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/GrNumberConverter.java @@ -53,10 +53,10 @@ public class GrNumberConverter extends GrTypeConverter { return isFloatOrDoubleType(targetType) ? OK : null; if (TypesUtil.isClassType(targetType, JAVA_MATH_BIG_DECIMAL)) - return TypesUtil.isNumericType(actualType) ? OK : ERROR; + return TypesUtil.isNumericType(actualType) || PsiType.NULL.equals(actualType) ? OK : ERROR; if (TypesUtil.isClassType(targetType, JAVA_MATH_BIG_INTEGER)) - return TypesUtil.isIntegralNumberType(actualType) ? OK : ERROR; + return TypesUtil.isIntegralNumberType(actualType) || PsiType.NULL.equals(actualType) ? OK : ERROR; if (TypesUtil.isClassType(actualType, JAVA_MATH_BIG_INTEGER)) return TypesUtil.isClassType(targetType, JAVA_MATH_BIG_INTEGER) || TypesUtil.isClassType(targetType, JAVA_MATH_BIG_DECIMAL) ? OK : null; diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrAssignAutoTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrAssignAutoTest.groovy index 32591a258dce..25d0666160c1 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrAssignAutoTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrAssignAutoTest.groovy @@ -134,6 +134,25 @@ class GrAssignAutoTest extends GrHighlightingTestBase { 'BigInteger -> int[]', 'BigInteger -> double[]', 'BigInteger -> short', 'int[] -> double[]', 'int[] -> Integer[]'] } + void testReturnAssignValue() { + doTest ''' + @CompileStatic + %2$s method%3$s() { + return %1$s + } + ''', + vectorProduct(values, types), + [], + ['true -> int', 'true -> double', 'true -> short', 'true -> byte', 'false -> int', 'false -> double', 'false -> short', + 'false -> byte', '(Void)null -> int', '(Void)null -> double', '(Void)null -> BigDecimal', '(Void)null -> BigInteger', + '(Void)null -> List', '(Void)null -> Thread', '(Void)null -> List', '(Void)null -> List', + '(Void)null -> List', '(Void)null -> List', '(Void)null -> List', '(Void)null -> List', + '(Void)null -> boolean[]', '(Void)null -> int[]', '(Void)null -> double[]', '(Void)null -> String[]', + '(Void)null -> Integer[]', '(Void)null -> List[]', '(Void)null -> Object[]', '(Void)null -> Thread[]', + '(Void)null -> short', '(Void)null -> byte', '(Void)null -> Set', '(Void)null -> Set', + '(Void)null -> Set', '(Void)null -> Set', '(Void)null -> Set'] + } + void testLocalAssignValue() { doTest ''' @CompileStatic