diff options
author | Dana Dahlstrom <dahlstrom@google.com> | 2022-06-22 22:00:00 -0700 |
---|---|---|
committer | Dana Dahlstrom <dahlstrom@google.com> | 2022-06-22 22:00:00 -0700 |
commit | bc61b8c5206ae3afb2455cbba7cd15989f58a4ad (patch) | |
tree | 873b8eb484e78dee676ed71935c17f0cd2103a35 | |
parent | 854aa9282230bbd1bf6caea780b7ee473bf20d82 (diff) | |
parent | 6ed4281aa53e1672d2e5870243c6606bb48afc84 (diff) | |
download | idea-bc61b8c5206ae3afb2455cbba7cd15989f58a4ad.tar.gz |
Merge IntelliJ IDEA 2022.1.2 221.5787.30
Change-Id: I6ed4281aa53e1672d2e5870243c6606bb48afc84
360 files changed, 1994 insertions, 1624 deletions
diff --git a/.idea/modules.xml b/.idea/modules.xml index 95f4acd2c58d..db3c643d17d9 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -557,8 +557,6 @@ <module fileurl="file://$PROJECT_DIR$/plugins/eclipse/jps-plugin/intellij.eclipse.jps.iml" filepath="$PROJECT_DIR$/plugins/eclipse/jps-plugin/intellij.eclipse.jps.iml" /> <module fileurl="file://$PROJECT_DIR$/plugins/editorconfig/intellij.editorconfig.iml" filepath="$PROJECT_DIR$/plugins/editorconfig/intellij.editorconfig.iml" /> <module fileurl="file://$PROJECT_DIR$/plugins/emojipicker/intellij.emojipicker.iml" filepath="$PROJECT_DIR$/plugins/emojipicker/intellij.emojipicker.iml" /> - <module fileurl="file://$PROJECT_DIR$/plugins/dependency-updater/intellij.externalSystem.dependencyUpdater.iml" filepath="$PROJECT_DIR$/plugins/dependency-updater/intellij.externalSystem.dependencyUpdater.iml" /> - <module fileurl="file://$PROJECT_DIR$/plugins/dependency-updater/intellij.externalSystem.dependencyUpdater.tests.iml" filepath="$PROJECT_DIR$/plugins/dependency-updater/intellij.externalSystem.dependencyUpdater.tests.iml" /> <module fileurl="file://$PROJECT_DIR$/plugins/ide-features-trainer/intellij.featuresTrainer.iml" filepath="$PROJECT_DIR$/plugins/ide-features-trainer/intellij.featuresTrainer.iml" /> <module fileurl="file://$PROJECT_DIR$/plugins/filePrediction/intellij.filePrediction.iml" filepath="$PROJECT_DIR$/plugins/filePrediction/intellij.filePrediction.iml" /> <module fileurl="file://$PROJECT_DIR$/plugins/gradle/intellij.gradle.iml" filepath="$PROJECT_DIR$/plugins/gradle/intellij.gradle.iml" /> @@ -774,6 +772,8 @@ <module fileurl="file://$PROJECT_DIR$/platform/external-process-auth-helper/intellij.platform.externalProcessAuthHelper.iml" filepath="$PROJECT_DIR$/platform/external-process-auth-helper/intellij.platform.externalProcessAuthHelper.iml" /> <module fileurl="file://$PROJECT_DIR$/platform/external-process-auth-helper/rt/intellij.platform.externalProcessAuthHelper.rt.iml" filepath="$PROJECT_DIR$/platform/external-process-auth-helper/rt/intellij.platform.externalProcessAuthHelper.rt.iml" /> <module fileurl="file://$PROJECT_DIR$/platform/external-system-api/intellij.platform.externalSystem.iml" filepath="$PROJECT_DIR$/platform/external-system-api/intellij.platform.externalSystem.iml" /> + <module fileurl="file://$PROJECT_DIR$/platform/external-system-api/dependency-updater/intellij.platform.externalSystem.dependencyUpdater.iml" filepath="$PROJECT_DIR$/platform/external-system-api/dependency-updater/intellij.platform.externalSystem.dependencyUpdater.iml" /> + <module fileurl="file://$PROJECT_DIR$/platform/external-system-api/dependency-updater/intellij.platform.externalSystem.dependencyUpdater.tests.iml" filepath="$PROJECT_DIR$/platform/external-system-api/dependency-updater/intellij.platform.externalSystem.dependencyUpdater.tests.iml" /> <module fileurl="file://$PROJECT_DIR$/platform/external-system-impl/intellij.platform.externalSystem.impl.iml" filepath="$PROJECT_DIR$/platform/external-system-impl/intellij.platform.externalSystem.impl.iml" /> <module fileurl="file://$PROJECT_DIR$/platform/external-system-rt/intellij.platform.externalSystem.rt.iml" filepath="$PROJECT_DIR$/platform/external-system-rt/intellij.platform.externalSystem.rt.iml" /> <module fileurl="file://$PROJECT_DIR$/platform/external-system-api/testFramework/intellij.platform.externalSystem.testFramework.iml" filepath="$PROJECT_DIR$/platform/external-system-api/testFramework/intellij.platform.externalSystem.testFramework.iml" /> diff --git a/RegExpSupport/src/org/intellij/lang/regexp/inspection/RegExpSimplifiableInspection.java b/RegExpSupport/src/org/intellij/lang/regexp/inspection/RegExpSimplifiableInspection.java index e42b0abfd088..b305abf3fd29 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/inspection/RegExpSimplifiableInspection.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/inspection/RegExpSimplifiableInspection.java @@ -80,6 +80,7 @@ public class RegExpSimplifiableInspection extends LocalInspectionTool { else { if (elements.length == 1) { final RegExpClassElement element = elements[0]; + if (element instanceof RegExpPosixBracketExpression) return; if (!(element instanceof RegExpCharRange)) { if (!(element instanceof RegExpChar) || !"{}().*+?|$".contains(element.getText())) { // [a] -> a diff --git a/RegExpSupport/test/org/intellij/lang/regexp/inspection/RegExpSimplifiableInspectionTest.java b/RegExpSupport/test/org/intellij/lang/regexp/inspection/RegExpSimplifiableInspectionTest.java index 69dfd8afcac0..5d39079e1b68 100644 --- a/RegExpSupport/test/org/intellij/lang/regexp/inspection/RegExpSimplifiableInspectionTest.java +++ b/RegExpSupport/test/org/intellij/lang/regexp/inspection/RegExpSimplifiableInspectionTest.java @@ -4,6 +4,8 @@ package org.intellij.lang.regexp.inspection; import com.intellij.codeInspection.CommonQuickFixBundle; import com.intellij.codeInspection.LocalInspectionTool; import org.intellij.lang.annotations.Language; +import org.intellij.lang.regexp.RegExpFileType; +import org.intellij.lang.regexp.ecmascript.EcmaScriptRegexpLanguage; import org.jetbrains.annotations.NotNull; /** @@ -84,6 +86,10 @@ public class RegExpSimplifiableInspectionTest extends RegExpInspectionTestCase { doTest("a{3,3}", 1, 5, "{3}", "a{3}"); } + public void testSinglePosixBracketExpressionInClass() { + highlightTest("[[:upper:]]", RegExpFileType.forLanguage(EcmaScriptRegexpLanguage.INSTANCE)); + } + private void doTest(@Language("RegExp") String code, @Language("RegExp") String replacement) { doTest(code, 0, code.length(), replacement, replacement); } diff --git a/build.txt b/build.txt index 10de74387d14..c4d55ece6d28 100644 --- a/build.txt +++ b/build.txt @@ -1 +1 @@ -221.5591.52.2211.SNAPSHOT +221.5787.30.2211.SNAPSHOT diff --git a/build/dependencies/gradle.properties b/build/dependencies/gradle.properties index 895c07fc8518..05fcfc8eadc8 100644 --- a/build/dependencies/gradle.properties +++ b/build/dependencies/gradle.properties @@ -1,9 +1,9 @@ # The file might be automatically updated. Comments and empty lines will be removed. # kotlinPluginBuild format: <plugin-version>[:<channel>], e.g. 1.3.20-release-IJ2018.3-1 or 1.3.20-eap-100-IJ2018.3-1:EAP -VulnerabilitySearchPluginVersion=0.7.27 +VulnerabilitySearchPluginVersion=0.7.32 bundledMavenVersion=3.8.1 gradleApiVersion=5.2.1 -jdkBuild=11_0_14_1b2043.45 -rkernelVersion=221.2 -runtimeBuild=11_0_14_1b2043.45 +jdkBuild=11_0_15b2043.56 +rkernelVersion=221.7 +runtimeBuild=11_0_15b2043.56 zkmVersion=17.0.1 diff --git a/build/groovy/org/jetbrains/intellij/build/BaseIdeaProperties.groovy b/build/groovy/org/jetbrains/intellij/build/BaseIdeaProperties.groovy index 3e8b6c30a453..972c1e071b4b 100644 --- a/build/groovy/org/jetbrains/intellij/build/BaseIdeaProperties.groovy +++ b/build/groovy/org/jetbrains/intellij/build/BaseIdeaProperties.groovy @@ -46,7 +46,6 @@ abstract class BaseIdeaProperties extends JetBrainsProductProperties { "intellij.repository.search", "intellij.maven.model", "intellij.maven", - "intellij.externalSystem.dependencyUpdater", "intellij.packageSearch", "intellij.gradle", "intellij.gradle.dependencyUpdater", diff --git a/build/tasks/resources/linux/class-report.txt b/build/tasks/resources/linux/class-report.txt index 19050f67cd4f..714c8dc95c0a 100644 --- a/build/tasks/resources/linux/class-report.txt +++ b/build/tasks/resources/linux/class-report.txt @@ -798,6 +798,7 @@ META-INF/ExternalSystem.xml:lib/app.jar META-INF/ExternalSystemExtensionPoints.xml:lib/app.jar META-INF/ExternalSystemExtensions.xml:lib/app.jar META-INF/ExternalSystemActions.xml:lib/app.jar +META-INF/ExternalSystemDependencyUpdater.xml:lib/app.jar intellij.platform.remoteServers.impl.xml:lib/app.jar META-INF/XmlPlugin.xml:lib/app.jar META-INF/XmlActions.xml:lib/app.jar diff --git a/build/tasks/resources/mac/class-report.txt b/build/tasks/resources/mac/class-report.txt index 47de89d1f2b5..42ebf8ca916d 100644 --- a/build/tasks/resources/mac/class-report.txt +++ b/build/tasks/resources/mac/class-report.txt @@ -621,6 +621,7 @@ io/netty/channel/AbstractChannel$AnnotatedNoRouteToHostException.class:lib/3rd-p META-INF/ExternalSystem.xml:lib/app.jar META-INF/ExternalSystemExtensionPoints.xml:lib/app.jar META-INF/ExternalSystemExtensions.xml:lib/app.jar +META-INF/ExternalSystemDependencyUpdater.xml:lib/app.jar io/netty/channel/AbstractChannel$AnnotatedSocketException.class:lib/3rd-party-rt.jar META-INF/ExternalSystemActions.xml:lib/app.jar intellij.platform.remoteServers.impl.xml:lib/app.jar diff --git a/build/tasks/resources/windows/class-report.txt b/build/tasks/resources/windows/class-report.txt index b37821edd60e..d0bc372f40b9 100644 --- a/build/tasks/resources/windows/class-report.txt +++ b/build/tasks/resources/windows/class-report.txt @@ -599,6 +599,7 @@ META-INF/ExternalSystem.xml:lib/app.jar META-INF/ExternalSystemExtensionPoints.xml:lib/app.jar META-INF/ExternalSystemExtensions.xml:lib/app.jar META-INF/ExternalSystemActions.xml:lib/app.jar +META-INF/ExternalSystemDependencyUpdater.xml:lib/app.jar intellij.platform.remoteServers.impl.xml:lib/app.jar META-INF/XmlPlugin.xml:lib/app.jar META-INF/XmlActions.xml:lib/app.jar diff --git a/community-resources/src/META-INF/IdeaPlugin.xml b/community-resources/src/META-INF/IdeaPlugin.xml index 8f20ba94fe98..07514f05626e 100644 --- a/community-resources/src/META-INF/IdeaPlugin.xml +++ b/community-resources/src/META-INF/IdeaPlugin.xml @@ -24,7 +24,6 @@ <content> <module name="intellij.notebooks.visualization"/> - <module name="intellij.platform.feedback"/> <module name="intellij.platform.images.copyright"/> </content> </idea-plugin> diff --git a/community-resources/src/idea/IdeaApplicationInfo.xml b/community-resources/src/idea/IdeaApplicationInfo.xml index 2223ab3eac78..0de0448af119 100644 --- a/community-resources/src/idea/IdeaApplicationInfo.xml +++ b/community-resources/src/idea/IdeaApplicationInfo.xml @@ -1,7 +1,7 @@ <component xmlns="http://jetbrains.org/intellij/schema/application-info" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jetbrains.org/intellij/schema/application-info http://jetbrains.org/intellij/schema/ApplicationInfo.xsd"> - <version major="2022" minor="1.1"/> + <version major="2022" minor="1.2"/> <company name="JetBrains s.r.o." url="https://www.jetbrains.com"/> <build number="IC-__BUILD__" date="__BUILD_DATE__" majorReleaseDate="20220412" /> <logo url="/idea_community_logo.png" textcolor="ffffff" progressColor="ffae00" progressY="396" progressHeight="4" /> diff --git a/docs/plugin-graph/plugin-graph.json b/docs/plugin-graph/plugin-graph.json index d030e9519968..22f18155c68b 100644 --- a/docs/plugin-graph/plugin-graph.json +++ b/docs/plugin-graph/plugin-graph.json @@ -4159,18 +4159,6 @@ }, { "group": "nodes", "data": { - "id": "8B", - "name": "intellij.externalSystem.dependencyUpdater", - "n": "i.externalSystem.dependencyUpdater", - "package": null, - "sourceModule": "intellij.externalSystem.dependencyUpdater", - "descriptor": "community/plugins/dependency-updater/resources/META-INF/plugin.xml", - "pluginId": "com.intellij.externalSystem.dependencyUpdater", - "type": 1 - } -}, { - "group": "nodes", - "data": { "id": "RP1", "name": "kotlin.idea", "n": "kotlin.idea", diff --git a/intellij.idea.community.main.iml b/intellij.idea.community.main.iml index 6030b66b2338..f929231529f6 100644 --- a/intellij.idea.community.main.iml +++ b/intellij.idea.community.main.iml @@ -143,8 +143,6 @@ <orderEntry type="module" module-name="intellij.packageSearch.kotlin" scope="RUNTIME" /> <orderEntry type="module" module-name="intellij.packageSearch.maven" scope="RUNTIME" /> <orderEntry type="module" module-name="intellij.emojipicker" scope="RUNTIME" /> - <orderEntry type="module" module-name="intellij.externalSystem.dependencyUpdater" scope="RUNTIME" /> - <orderEntry type="module" module-name="intellij.externalSystem.dependencyUpdater.tests" scope="TEST" /> <orderEntry type="module" module-name="intellij.gradle.dependencyUpdater" scope="RUNTIME" /> <orderEntry type="module" module-name="intellij.settingsRepository.tests" scope="TEST" /> <orderEntry type="module" module-name="intellij.settingsSync" scope="RUNTIME" /> diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index 026029fa6e00..47849845dcd5 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -110,7 +110,8 @@ import org.jetbrains.jps.model.java.compiler.JavaCompilers; import org.jvnet.winp.Priority; import org.jvnet.winp.WinProcess; -import javax.tools.*; +import javax.tools.JavaCompiler; +import javax.tools.ToolProvider; import java.awt.*; import java.io.File; import java.io.IOException; @@ -844,8 +845,8 @@ public final class BuildManager implements Disposable { final String projectPath = getProjectPath(project); final boolean isAutomake = messageHandler instanceof AutoMakeMessageHandler; - final BuilderMessageHandler handler = new NotifyingMessageHandler(project, messageHandler, isAutomake); - WSLDistribution wslDistribution = findWSLDistributionForBuild(project); + final WSLDistribution wslDistribution = findWSLDistributionForBuild(project); + final BuilderMessageHandler handler = new NotifyingMessageHandler(project, messageHandler, wslDistribution != null ? wslDistribution::getWindowsPath : null, isAutomake); try { ensureListening(wslDistribution != null ? wslDistribution.getHostIpAddress() : InetAddress.getLoopbackAddress()); } @@ -1785,11 +1786,14 @@ public final class BuildManager implements Disposable { private static final class NotifyingMessageHandler extends DelegatingMessageHandler { private final Project myProject; private final BuilderMessageHandler myDelegateHandler; + @Nullable + private final Function<String, String> myPathMapper; private final boolean myIsAutomake; - NotifyingMessageHandler(@NotNull Project project, @NotNull BuilderMessageHandler delegateHandler, final boolean isAutomake) { + NotifyingMessageHandler(@NotNull Project project, @NotNull BuilderMessageHandler delegateHandler, @Nullable Function<String, String> pathMapper, final boolean isAutomake) { myProject = project; myDelegateHandler = delegateHandler; + myPathMapper = pathMapper; myIsAutomake = isAutomake; } @@ -1827,6 +1831,34 @@ public final class BuildManager implements Disposable { } } } + + @Override + public void handleBuildMessage(Channel channel, UUID sessionId, CmdlineRemoteProto.Message.BuilderMessage msg) { + CmdlineRemoteProto.Message.BuilderMessage _message = msg; + if (myPathMapper != null) { + if (_message.hasCompileMessage()) { + final CmdlineRemoteProto.Message.BuilderMessage.CompileMessage compileMessage = _message.getCompileMessage(); + if (compileMessage.hasSourceFilePath()) { + final CmdlineRemoteProto.Message.BuilderMessage.CompileMessage.Builder builder = CmdlineRemoteProto.Message.BuilderMessage.CompileMessage.newBuilder(compileMessage); + builder.setSourceFilePath(myPathMapper.apply(compileMessage.getSourceFilePath())); + _message = CmdlineRemoteProto.Message.BuilderMessage.newBuilder(_message).setCompileMessage(builder).build(); + } + } + if (_message.hasBuildEvent()) { + final CmdlineRemoteProto.Message.BuilderMessage.BuildEvent buildEvent = _message.getBuildEvent(); + final int filesCount = buildEvent.getGeneratedFilesCount(); + if (filesCount > 0) { + final CmdlineRemoteProto.Message.BuilderMessage.BuildEvent.Builder builder = CmdlineRemoteProto.Message.BuilderMessage.BuildEvent.newBuilder(buildEvent); + for (int idx = 0; idx < filesCount; idx++) { + final CmdlineRemoteProto.Message.BuilderMessage.BuildEvent.GeneratedFile file = buildEvent.getGeneratedFiles(idx); + builder.setGeneratedFiles(idx, CmdlineRemoteProto.Message.BuilderMessage.BuildEvent.GeneratedFile.newBuilder(file).setOutputRoot(myPathMapper.apply(file.getOutputRoot()))); + } + _message = CmdlineRemoteProto.Message.BuilderMessage.newBuilder(_message).setBuildEvent(builder).build(); + } + } + } + super.handleBuildMessage(channel, sessionId, _message); + } } private static final class StdOutputCollector extends ProcessAdapter { diff --git a/java/execution/impl/src/com/intellij/execution/CommonJavaRunConfigurationParameters.java b/java/execution/impl/src/com/intellij/execution/CommonJavaRunConfigurationParameters.java index 61d1dec62b80..88890992e89c 100644 --- a/java/execution/impl/src/com/intellij/execution/CommonJavaRunConfigurationParameters.java +++ b/java/execution/impl/src/com/intellij/execution/CommonJavaRunConfigurationParameters.java @@ -1,16 +1,21 @@ -/* - * 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.execution; import com.intellij.execution.configurations.ConfigurationWithAlternativeJre; import com.intellij.execution.configurations.ModuleBasedConfigurationOptions; +import com.intellij.execution.impl.statistics.FusAwareRunConfiguration; +import com.intellij.execution.impl.statistics.RunConfigurationUsageTriggerCollector; +import com.intellij.execution.util.JavaParametersUtil; +import com.intellij.internal.statistic.eventLog.events.EventPair; +import com.intellij.util.lang.JavaVersion; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collections; import java.util.List; -public interface CommonJavaRunConfigurationParameters extends CommonProgramRunConfigurationParameters, ConfigurationWithAlternativeJre { +public interface CommonJavaRunConfigurationParameters extends CommonProgramRunConfigurationParameters, ConfigurationWithAlternativeJre, + FusAwareRunConfiguration { void setVMParameters(@Nullable String value); String getVMParameters(); @@ -38,4 +43,16 @@ public interface CommonJavaRunConfigurationParameters extends CommonProgramRunCo default void setClasspathModifications(List<ModuleBasedConfigurationOptions.ClasspathModification> modifications) { } + + @Override + default @NotNull List<EventPair<?>> getAdditionalUsageData() { + String jrePath = getAlternativeJrePath(); + if (jrePath != null) { + JavaVersion version = JavaParametersUtil.getJavaVersion(jrePath); + if (version != null) { + return Collections.singletonList(RunConfigurationUsageTriggerCollector.ALTERNATIVE_JRE_VERSION.with(version.feature)); + } + } + return Collections.emptyList(); + } } diff --git a/java/execution/impl/src/com/intellij/execution/application/ApplicationConfiguration.java b/java/execution/impl/src/com/intellij/execution/application/ApplicationConfiguration.java index 71e8fffd73c2..2f60141984cb 100644 --- a/java/execution/impl/src/com/intellij/execution/application/ApplicationConfiguration.java +++ b/java/execution/impl/src/com/intellij/execution/application/ApplicationConfiguration.java @@ -1,4 +1,4 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.execution.application; import com.intellij.diagnostic.logging.LogConfigurationPanel; @@ -34,6 +34,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiMethodUtil; import com.intellij.refactoring.listeners.RefactoringElementListener; import com.intellij.util.PathUtil; +import com.intellij.util.containers.ContainerUtil; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -309,10 +310,11 @@ public class ApplicationConfiguration extends JavaRunConfigurationBase @Override public @NotNull List<EventPair<?>> getAdditionalUsageData() { PsiClass mainClass = getMainClass(); + List<EventPair<?>> additionalUsageData = super.getAdditionalUsageData(); if (mainClass == null) { - return Collections.emptyList(); + return additionalUsageData; } - return Collections.singletonList(EventFields.Language.with(mainClass.getLanguage())); + return ContainerUtil.concat(additionalUsageData, Collections.singletonList(EventFields.Language.with(mainClass.getLanguage()))); } public static void onAlternativeJreChanged(boolean changed, Project project) { diff --git a/java/execution/impl/src/com/intellij/execution/util/JavaParametersUtil.java b/java/execution/impl/src/com/intellij/execution/util/JavaParametersUtil.java index c1dbc0e6ff2c..ba3ad9cedb8b 100644 --- a/java/execution/impl/src/com/intellij/execution/util/JavaParametersUtil.java +++ b/java/execution/impl/src/com/intellij/execution/util/JavaParametersUtil.java @@ -1,4 +1,4 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.execution.util; import com.intellij.codeInsight.daemon.impl.analysis.JavaModuleGraphUtil; @@ -27,6 +27,7 @@ import com.intellij.util.ObjectUtils; import com.intellij.util.PathUtil; import com.intellij.util.PathsList; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.lang.JavaVersion; import org.intellij.lang.annotations.MagicConstant; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -151,6 +152,20 @@ public final class JavaParametersUtil { } return jdk; } + + public static @Nullable JavaVersion getJavaVersion(String jreHome) { + final Sdk configuredJdk = ProjectJdkTable.getInstance().findJdk(jreHome); + if (configuredJdk != null) { + return JavaVersion.tryParse(configuredJdk.getVersionString()); + } + + if (JdkUtil.checkForJre(jreHome)) { + final JavaSdk javaSdk = JavaSdk.getInstance(); + return JavaVersion.tryParse(javaSdk.getVersionString(jreHome)); + } + + return null; + } private static Sdk createAlternativeJdk(@NotNull Project project, @NotNull String jreHome) throws CantRunException { final Sdk configuredJdk = ProjectJdkTable.getInstance().findJdk(jreHome); diff --git a/java/idea-ui/src/com/intellij/ide/starters/local/wizard/StarterLibrariesStep.kt b/java/idea-ui/src/com/intellij/ide/starters/local/wizard/StarterLibrariesStep.kt index a6aa414648e6..1c4e043b75c9 100644 --- a/java/idea-ui/src/com/intellij/ide/starters/local/wizard/StarterLibrariesStep.kt +++ b/java/idea-ui/src/com/intellij/ide/starters/local/wizard/StarterLibrariesStep.kt @@ -266,7 +266,7 @@ open class StarterLibrariesStep(contextProvider: StarterContextProvider) : Modul val initial = selectedStarterId == null val selectedStarter = when (val previouslySelectedStarter = starterContext.starter?.id) { - null -> starterPack.starters.firstOrNull() + null -> starterPack.starters.find { it.id == starterPack.defaultStarterId } ?: starterPack.starters.firstOrNull() else -> starterPack.starters.find { it.id == previouslySelectedStarter } } if (selectedStarter != null) { diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/java/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/java/ControlFlowAnalyzer.java index 460d178c352f..e5232d1ceb4a 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/java/ControlFlowAnalyzer.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/java/ControlFlowAnalyzer.java @@ -1085,6 +1085,8 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { PsiExpression expression = ((PsiGuardedPattern)innerPattern).getGuardingExpression(); if (expression != null) { expression.accept(this); + } else { + addInstruction(new PushValueInstruction(DfTypes.BOOLEAN)); } DeferredOffset condGotoOffset = new DeferredOffset(); addInstruction(new ConditionalGotoInstruction(condGotoOffset, DfTypes.TRUE)); diff --git a/java/java-features-trainer/src/com/intellij/java/ift/JavaBasedLangSupport.kt b/java/java-features-trainer/src/com/intellij/java/ift/JavaBasedLangSupport.kt index 81646e067e97..2f6a2de9494d 100644 --- a/java/java-features-trainer/src/com/intellij/java/ift/JavaBasedLangSupport.kt +++ b/java/java-features-trainer/src/com/intellij/java/ift/JavaBasedLangSupport.kt @@ -5,8 +5,10 @@ import com.intellij.openapi.application.runInEdt import com.intellij.openapi.application.runWriteAction import com.intellij.openapi.command.CommandProcessor import com.intellij.openapi.project.Project +import com.intellij.openapi.projectRoots.JavaSdkType import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.projectRoots.ex.JavaSdkUtil +import com.intellij.openapi.roots.ProjectRootManager import com.intellij.openapi.roots.impl.LanguageLevelProjectExtensionImpl import com.intellij.openapi.vfs.VirtualFile import com.intellij.pom.java.LanguageLevel @@ -48,4 +50,6 @@ abstract class JavaBasedLangSupport : AbstractLangSupport() { override fun checkSdk(sdk: Sdk?, project: Project) {} override fun blockProjectFileModification(project: Project, file: VirtualFile): Boolean = true + + override fun isSdkConfigured(project: Project) = ProjectRootManager.getInstance(project).projectSdk?.sdkType is JavaSdkType }
\ No newline at end of file diff --git a/java/java-features-trainer/src/com/intellij/java/ift/JavaLangSupport.kt b/java/java-features-trainer/src/com/intellij/java/ift/JavaLangSupport.kt index f1beda9ee47a..8af51817089d 100644 --- a/java/java-features-trainer/src/com/intellij/java/ift/JavaLangSupport.kt +++ b/java/java-features-trainer/src/com/intellij/java/ift/JavaLangSupport.kt @@ -1,15 +1,10 @@ // Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.java.ift -import com.intellij.openapi.application.runWriteAction -import com.intellij.openapi.progress.util.AbstractProgressIndicatorExBase -import com.intellij.openapi.project.Project import com.intellij.openapi.project.ProjectBundle import com.intellij.openapi.roots.OrderRootType -import com.intellij.openapi.roots.ProjectRootManager import com.intellij.openapi.roots.ui.configuration.JdkComboBox import com.intellij.openapi.roots.ui.configuration.SdkListItem -import com.intellij.openapi.roots.ui.configuration.projectRoot.SdkDownloadTracker import com.intellij.openapi.ui.popup.Balloon import com.intellij.ui.HyperlinkLabel import com.intellij.ui.components.panels.NonOpaquePanel @@ -44,17 +39,15 @@ internal class JavaLangSupport : JavaBasedLangSupport() { override val sdkConfigurationTasks: LessonContext.(lesson: KLesson) -> Unit = { val setupSdkText = ProjectBundle.message("project.sdk.setup") - fun isJdkInstalled(project: Project) = JavaProjectUtil.getProjectJdk(project) != null - task { - if (isJdkInstalled(project)) return@task + if (isSdkConfigured(project)) return@task triggerAndFullHighlight { usePulsation = true }.component { ui: HyperlinkLabel -> ui.text == setupSdkText } } task { - if (isJdkInstalled(project)) return@task + if (isSdkConfigured(project)) return@task rehighlightPreviousUi = true text(JavaLessonsBundle.message("java.missed.sdk.click.setup", strong(setupSdkText))) @@ -69,14 +62,13 @@ internal class JavaLangSupport : JavaBasedLangSupport() { } task { - if (isJdkInstalled(project)) return@task + if (isSdkConfigured(project)) return@task rehighlightPreviousUi = true text(JavaLessonsBundle.message("java.missed.sdk.configure")) var progressHighlightingStarted = false - var downloadingListenerAdded = false timerCheck { - val jdk = JavaProjectUtil.getProjectJdk(project) + val jdk = JavaProjectUtil.getEffectiveJdk(project) if (jdk != null && !progressHighlightingStarted) { progressHighlightingStarted = true @@ -95,18 +87,6 @@ internal class JavaLangSupport : JavaBasedLangSupport() { } } - if (jdk != null && !downloadingListenerAdded) { - downloadingListenerAdded = SdkDownloadTracker.getInstance().tryRegisterDownloadingListener(jdk, taskDisposable, - AbstractProgressIndicatorExBase()) { - // todo: For some reason after the downloading JDK is not fully applied, imports are still red. - // So we need to trigger the indexing by setting the same JDK that already set just to call listeners of JDK update. - // Remove this hack when IDEA-244649 will be fixed. - runWriteAction { - ProjectRootManager.getInstance(project).projectSdk = JavaProjectUtil.getProjectJdk(project) - } - } - } - jdk != null && jdk.rootProvider.getFiles(OrderRootType.CLASSES).isNotEmpty() } } diff --git a/java/java-features-trainer/src/com/intellij/java/ift/JavaProjectUtil.kt b/java/java-features-trainer/src/com/intellij/java/ift/JavaProjectUtil.kt index 8889495d7b6d..f5a7ea8b6e50 100644 --- a/java/java-features-trainer/src/com/intellij/java/ift/JavaProjectUtil.kt +++ b/java/java-features-trainer/src/com/intellij/java/ift/JavaProjectUtil.kt @@ -32,10 +32,10 @@ object JavaProjectUtil { .executeLookup() } - fun getProjectJdk(project: Project): Sdk? { + fun getEffectiveJdk(project: Project): Sdk? { val projectJdk = ProjectRootManager.getInstance(project).projectSdk val module = ModuleManager.getInstance(project).modules.first() val moduleJdk = ModuleRootManager.getInstance(module).sdk - return moduleJdk ?: projectJdk + return (moduleJdk ?: projectJdk).takeIf { it?.sdkType is JavaSdk } } }
\ No newline at end of file diff --git a/java/java-features-trainer/src/com/intellij/java/ift/lesson/essential/JavaOnboardingTourLesson.kt b/java/java-features-trainer/src/com/intellij/java/ift/lesson/essential/JavaOnboardingTourLesson.kt index 618fc2a520dc..89ec8537b683 100644 --- a/java/java-features-trainer/src/com/intellij/java/ift/lesson/essential/JavaOnboardingTourLesson.kt +++ b/java/java-features-trainer/src/com/intellij/java/ift/lesson/essential/JavaOnboardingTourLesson.kt @@ -244,7 +244,7 @@ class JavaOnboardingTourLesson : KLesson("java.onboarding", JavaLessonsBundle.me }) } - val currentJdk = JavaProjectUtil.getProjectJdk(project) + val currentJdk = JavaProjectUtil.getEffectiveJdk(project) @Suppress("HardCodedStringLiteral") val currentJdkVersion: @NlsSafe String = currentJdk?.let { JavaSdk.getInstance().getVersionString(it) } ?: "none" diff --git a/java/java-impl-inspections/src/com/intellij/codeInspection/ManualMinMaxCalculationInspection.java b/java/java-impl-inspections/src/com/intellij/codeInspection/ManualMinMaxCalculationInspection.java index 2c554cb6a47c..7e95b7a244ba 100644 --- a/java/java-impl-inspections/src/com/intellij/codeInspection/ManualMinMaxCalculationInspection.java +++ b/java/java-impl-inspections/src/com/intellij/codeInspection/ManualMinMaxCalculationInspection.java @@ -122,28 +122,31 @@ public class ManualMinMaxCalculationInspection extends AbstractBaseJavaLocalInsp @Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { PsiElement element = descriptor.getPsiElement(); + final CommentTracker ct = new CommentTracker(); if (element instanceof PsiConditionalExpression) { ConditionalModel model = ConditionalModel.from((PsiConditionalExpression)element); if (model == null) return; - String replacement = createReplacement(model.getCondition()); + String replacement = createReplacement(model.getCondition(), ct); if (replacement == null) return; - PsiReplacementUtil.replaceExpression((PsiExpression)element, replacement, new CommentTracker()); + PsiReplacementUtil.replaceExpression((PsiExpression)element, replacement, ct); return; } PsiIfStatement ifStatement = PsiTreeUtil.getParentOfType(element, PsiIfStatement.class); if (ifStatement == null) return; IfConditionalModel model = IfConditionalModel.from(ifStatement, false); if (model == null) return; - String replacement = createReplacement(model.getCondition()); + String replacement = createReplacement(model.getCondition(), ct); if (replacement == null) return; PsiStatement elseBranch = model.getElseBranch(); final PsiElement result; if (elseBranch instanceof PsiDeclarationStatement) { - result = replace(ifStatement, elseBranch, model.getElseExpression(), replacement); + PsiReplacementUtil.replaceExpression(model.getElseExpression(), replacement, new CommentTracker()); + result = PsiReplacementUtil.replaceStatement(ifStatement, ct.text(elseBranch), ct); elseBranch.delete(); } else { - result = replace(ifStatement, model.getThenBranch(), model.getThenExpression(), replacement); + PsiReplacementUtil.replaceExpression(model.getThenExpression(), replacement, new CommentTracker()); + result = PsiReplacementUtil.replaceStatement(ifStatement, ct.text(model.getThenBranch()), ct); if (!PsiTreeUtil.isAncestor(ifStatement, elseBranch, true)) { new CommentTracker().deleteAndRestoreComments(elseBranch); } @@ -151,23 +154,14 @@ public class ManualMinMaxCalculationInspection extends AbstractBaseJavaLocalInsp SimplifiableIfStatementInspection.tryJoinDeclaration(result); } - private static @NotNull PsiElement replace(@NotNull PsiIfStatement ifStatement, - @NotNull PsiStatement branch, @NotNull PsiExpression toReplace, - @NotNull String replacement) { - PsiReplacementUtil.replaceExpression(toReplace, replacement, new CommentTracker()); - CommentTracker tracker = new CommentTracker(); - tracker.text(branch); - return PsiReplacementUtil.replaceStatement(ifStatement, branch.getText(), tracker); - } - @Nullable - private String createReplacement(@NotNull PsiExpression expression) { + private String createReplacement(@NotNull PsiExpression expression, CommentTracker ct) { PsiBinaryExpression condition = getCondition(expression); if (condition == null) return null; PsiExpression left = condition.getLOperand(); PsiExpression right = condition.getROperand(); if (right == null) return null; - return CommonClassNames.JAVA_LANG_MATH + (myUseMathMin ? ".min" : ".max") + "(" + left.getText() + "," + right.getText() + ")"; + return CommonClassNames.JAVA_LANG_MATH + (myUseMathMin ? ".min" : ".max") + "(" + ct.text(left) + "," + ct.text(right) + ")"; } } } diff --git a/java/java-impl/src/com/intellij/testIntegration/JavaTestFramework.java b/java/java-impl/src/com/intellij/testIntegration/JavaTestFramework.java index c622ff3f8145..092d6b05d30e 100644 --- a/java/java-impl/src/com/intellij/testIntegration/JavaTestFramework.java +++ b/java/java-impl/src/com/intellij/testIntegration/JavaTestFramework.java @@ -58,6 +58,10 @@ public abstract class JavaTestFramework implements TestFramework { */ protected boolean isFrameworkAvailable(@NotNull PsiElement clazz) { String markerClassFQName = getMarkerClassFQName(); + return isFrameworkApplicable(clazz, markerClassFQName); + } + + protected static boolean isFrameworkApplicable(@NotNull PsiElement clazz, String markerClassFQName) { if (markerClassFQName == null) return true; return CachedValuesManager.<ConcurrentMap<String, PsiClass>>getCachedValue(clazz, () -> { var project = clazz.getProject(); @@ -67,7 +71,7 @@ public abstract class JavaTestFramework implements TestFramework { ProjectRootManager.getInstance(project)); }).get(markerClassFQName) != null; } - + @Override public boolean isTestClass(@NotNull PsiElement clazz) { return clazz instanceof PsiClass && isFrameworkAvailable(clazz) && isTestClass((PsiClass)clazz, false); diff --git a/java/java-psi-api/src/com/intellij/pom/java/LanguageLevel.java b/java/java-psi-api/src/com/intellij/pom/java/LanguageLevel.java index 668080021efd..8ba91dc510f8 100644 --- a/java/java-psi-api/src/com/intellij/pom/java/LanguageLevel.java +++ b/java/java-psi-api/src/com/intellij/pom/java/LanguageLevel.java @@ -47,7 +47,7 @@ public enum LanguageLevel { /** * Should point to the last released JDK. */ - public static final LanguageLevel HIGHEST = JDK_17; + public static final LanguageLevel HIGHEST = JDK_18; public static final Key<LanguageLevel> KEY = Key.create("LANGUAGE_LEVEL"); private final Supplier<@Nls String> myPresentableText; diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/EmptySnippet.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/EmptySnippet.java index 6ffb3f007368..4a20be7be055 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/EmptySnippet.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/EmptySnippet.java @@ -1,6 +1,6 @@ /** * A simple program. - * {<warning descr="'@snippet' tag is not available at this language level">@snippet</warning> :} + * {@snippet :} */ class A { }
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/OnlyEmptyLinesInSnippet.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/OnlyEmptyLinesInSnippet.java index b1d1bcc2ed22..2aeed05ef985 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/OnlyEmptyLinesInSnippet.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/OnlyEmptyLinesInSnippet.java @@ -1,6 +1,6 @@ /** * A simple program. - * {<warning descr="'@snippet' tag is not available at this language level">@snippet</warning> : + * {@snippet : * * } */ diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/Snippet.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/Snippet.java index 89f1983164ab..69a0bcfb5476 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/Snippet.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/Snippet.java @@ -1,4 +1,4 @@ -/** {<warning descr="'@snippet' tag is not available at this language level">@snippet</warning> : +/** {@snippet : * Body * } */ diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/SnippetInlineTag.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/SnippetInlineTag.java index 55ba2ae4a71e..02fc75371b22 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/SnippetInlineTag.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/SnippetInlineTag.java @@ -1,5 +1,5 @@ /** - * {<warning descr="'@snippet' tag is not available at this language level">@snippet</warning> lang=JAVA : + * {@snippet lang=JAVA : * public class ShowOptional { * void show(Optional<String> v) { * // @start region="example" diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/SnippetInstructions.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/SnippetInstructions.java index 2eb4bf1a727d..3ceb23d6ee60 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/SnippetInstructions.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/SnippetInstructions.java @@ -1,4 +1,4 @@ -/** {<warning descr="'@snippet' tag is not available at this language level">@snippet</warning> : +/** {@snippet : * Optional<Integer> v = null; * if (v.isPresent()) { * System.out.println("v: " + v.get()); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/SnippetInstructionsWithUnhandledThrowable.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/SnippetInstructionsWithUnhandledThrowable.java index df98556537a5..21708b43c196 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/SnippetInstructionsWithUnhandledThrowable.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/SnippetInstructionsWithUnhandledThrowable.java @@ -1,4 +1,4 @@ -/** {<warning descr="'@snippet' tag is not available at this language level">@snippet</warning> : +/** {@snippet : * FileInputStream is = new FileInputStream("hello.world"); * int r = is.read(); * } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/SnippetMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/SnippetMethod.java index 9b4c0a77a9c9..8c5e195c91ec 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/SnippetMethod.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/SnippetMethod.java @@ -1,4 +1,4 @@ -/** {<warning descr="'@snippet' tag is not available at this language level">@snippet</warning> : +/** {@snippet : * void f() {} * } */ diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/UnalignedLeadingAsterisks.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/UnalignedLeadingAsterisks.java index 2cd16118c296..1145759d40a0 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/UnalignedLeadingAsterisks.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/UnalignedLeadingAsterisks.java @@ -2,7 +2,7 @@ class A { /** * A simple program. - * {<warning descr="'@snippet' tag is not available at this language level">@snippet</warning> : + * {@snippet : * class HelloWorld { * void * f( diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/EmptySnippet.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/EmptySnippet.java index 6ffb3f007368..4a20be7be055 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/EmptySnippet.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/EmptySnippet.java @@ -1,6 +1,6 @@ /** * A simple program. - * {<warning descr="'@snippet' tag is not available at this language level">@snippet</warning> :} + * {@snippet :} */ class A { }
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/OnlyEmptyLinesInSnippet.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/OnlyEmptyLinesInSnippet.java index b1d1bcc2ed22..2aeed05ef985 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/OnlyEmptyLinesInSnippet.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/OnlyEmptyLinesInSnippet.java @@ -1,6 +1,6 @@ /** * A simple program. - * {<warning descr="'@snippet' tag is not available at this language level">@snippet</warning> : + * {@snippet : * * } */ diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/Snippet.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/Snippet.java index 89f1983164ab..69a0bcfb5476 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/Snippet.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/Snippet.java @@ -1,4 +1,4 @@ -/** {<warning descr="'@snippet' tag is not available at this language level">@snippet</warning> : +/** {@snippet : * Body * } */ diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/SnippetInlineTag.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/SnippetInlineTag.java index 55ba2ae4a71e..02fc75371b22 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/SnippetInlineTag.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/SnippetInlineTag.java @@ -1,5 +1,5 @@ /** - * {<warning descr="'@snippet' tag is not available at this language level">@snippet</warning> lang=JAVA : + * {@snippet lang=JAVA : * public class ShowOptional { * void show(Optional<String> v) { * // @start region="example" diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/SnippetInstructions.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/SnippetInstructions.java index 2eb4bf1a727d..3ceb23d6ee60 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/SnippetInstructions.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/SnippetInstructions.java @@ -1,4 +1,4 @@ -/** {<warning descr="'@snippet' tag is not available at this language level">@snippet</warning> : +/** {@snippet : * Optional<Integer> v = null; * if (v.isPresent()) { * System.out.println("v: " + v.get()); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/SnippetInstructionsWithUnhandledThrowable.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/SnippetInstructionsWithUnhandledThrowable.java index df98556537a5..21708b43c196 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/SnippetInstructionsWithUnhandledThrowable.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/SnippetInstructionsWithUnhandledThrowable.java @@ -1,4 +1,4 @@ -/** {<warning descr="'@snippet' tag is not available at this language level">@snippet</warning> : +/** {@snippet : * FileInputStream is = new FileInputStream("hello.world"); * int r = is.read(); * } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/SnippetMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/SnippetMethod.java index 9b4c0a77a9c9..8c5e195c91ec 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/SnippetMethod.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/SnippetMethod.java @@ -1,4 +1,4 @@ -/** {<warning descr="'@snippet' tag is not available at this language level">@snippet</warning> : +/** {@snippet : * void f() {} * } */ diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/EclipseDefaultOptionalOrElse.java b/java/java-tests/testData/inspection/dataFlow/fixture/EclipseDefaultOptionalOrElse.java new file mode 100644 index 000000000000..70a8b8cbe87f --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/EclipseDefaultOptionalOrElse.java @@ -0,0 +1,12 @@ +import java.util.Optional; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +// IDEA-291604 +@NonNullByDefault +class Test { + public @Nullable String test(final Optional<String> optional, final @Nullable String fallback) { + return optional.orElse(fallback); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/FieldUpdateViaSetter.java b/java/java-tests/testData/inspection/dataFlow/fixture/FieldUpdateViaSetter.java new file mode 100644 index 000000000000..a91473ea5ee4 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/FieldUpdateViaSetter.java @@ -0,0 +1,25 @@ +// IDEA-293687 +public class FieldUpdateViaSetter { + private static final MutableBoolean flag = new MutableBoolean(); + + public static void main(String[] args) { + for (int i = 0; i < 10; ++i) { + if (flag.value && i == 0) { + break; + } + if (flag.value && i == 3) { + System.out.println("IDEA thinks we can't get here"); + break; + } + flag.setValue(true); + } + } + + private static final class MutableBoolean { + private boolean value; + + public void setValue(boolean newValue) { + value = newValue; + } + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/Patterns.java b/java/java-tests/testData/inspection/dataFlow/fixture/Patterns.java index 1d62bb1b7b4d..11c636fe4f59 100644 --- a/java/java-tests/testData/inspection/dataFlow/fixture/Patterns.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/Patterns.java @@ -1,4 +1,10 @@ class Test { + int testIncomplete(Object obj) { + return switch(obj) { + case String s &&<EOLError descr="Expression expected"></EOLError><EOLError descr="':' expected"></EOLError> + }; + } + void test1(Object o) { int a; switch (o) { diff --git a/java/java-tests/testData/inspection/manualMinMaxCalculation/afterVariableValueUsed.java b/java/java-tests/testData/inspection/manualMinMaxCalculation/afterVariableValueUsed.java new file mode 100644 index 000000000000..ec22af9ec05b --- /dev/null +++ b/java/java-tests/testData/inspection/manualMinMaxCalculation/afterVariableValueUsed.java @@ -0,0 +1,23 @@ +// "Replace with 'Math.min()' call" "true" +import java.util.Random; + +class VariableValueUsed { + private static final Random rnd = new Random(); + + private static int test() { + return rnd.nextInt(); + } + + public static void main(String[] args) { + int l = 2; + int myNumber = test(); + + /*3*/ + /*1*/ + /*2*/ + /*5*/ + myNumber = Math.min(l +/*6*/1, myNumber/*4*/ - 2); + + System.out.println(myNumber); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/inspection/manualMinMaxCalculation/beforeVariableValueUsed.java b/java/java-tests/testData/inspection/manualMinMaxCalculation/beforeVariableValueUsed.java new file mode 100644 index 000000000000..fafa0d52bead --- /dev/null +++ b/java/java-tests/testData/inspection/manualMinMaxCalculation/beforeVariableValueUsed.java @@ -0,0 +1,23 @@ +// "Replace with 'Math.min()' call" "true" +import java.util.Random; + +class VariableValueUsed { + private static final Random rnd = new Random(); + + private static int test() { + return rnd.nextInt(); + } + + public static void main(String[] args) { + int l = 2; + int myNumber = test(); + + <caret>if (l+/*6*/1 <=/*3*/ myNumber/*4*/ - 2) { + myNumber = l/*1*/+1; + } else { + myNumber = /*2*/ myNumber /*5*/- 2; + } + + System.out.println(myNumber); + } +}
\ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/JavadocCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/JavadocCompletionTest.groovy index a5ffbed224fa..05a15438273e 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/JavadocCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/JavadocCompletionTest.groovy @@ -161,7 +161,7 @@ class JavadocCompletionTest extends LightFixtureCompletionTestCase { void testInlineLookup() { configureByFile("InlineTagName.java") - assertStringItems("code", "docRoot", "index", "inheritDoc", "link", "linkplain", "literal", "summary", "systemProperty", "value") + assertStringItems("code", "docRoot", "index", "inheritDoc", "link", "linkplain", "literal", "snippet", "summary", "systemProperty", "value") } @NeedsIndex.ForStandardLibrary @@ -776,7 +776,7 @@ interface Bar<T> extends Foo<T> { void "test tags at top level inline"() { myFixture.configureByText 'a.java', "interface Foo { /** Hello <caret> */void foo(int a); }" myFixture.completeBasic() - assert myFixture.lookupElementStrings == ['{@code}', '{@docRoot}', '{@index}', '{@inheritDoc}', '{@linkplain}', '{@link}', '{@literal}', '{@summary}', '{@systemProperty}', '{@value}'] + assert myFixture.lookupElementStrings == ['{@code}', '{@docRoot}', '{@index}', '{@inheritDoc}', '{@linkplain}', '{@link}', '{@literal}', '{@snippet}', '{@summary}', '{@systemProperty}', '{@value}'] def element = myFixture.lookupElements[5] assert element.lookupString == "{@link}" selectItem(element) @@ -786,7 +786,7 @@ interface Bar<T> extends Foo<T> { void "test tags after return"() { myFixture.configureByText 'a.java', "interface Foo { /** @return <caret> */int foo(int a); }" myFixture.completeBasic() - assert myFixture.lookupElementStrings == ['{@code}', '{@docRoot}', '{@index}', '{@inheritDoc}', '{@linkplain}', '{@link}', '{@literal}', '{@return}', '{@summary}', '{@systemProperty}', '{@value}'] + assert myFixture.lookupElementStrings == ['{@code}', '{@docRoot}', '{@index}', '{@inheritDoc}', '{@linkplain}', '{@link}', '{@literal}', '{@return}', '{@snippet}', '{@summary}', '{@systemProperty}', '{@value}'] def element = myFixture.lookupElements[5] assert element.lookupString == "{@link}" selectItem(element) @@ -796,7 +796,7 @@ interface Bar<T> extends Foo<T> { void "test tags at top level inline in brace"() { myFixture.configureByText 'a.java', "interface Foo { /** Hello {<caret>} */void foo(int a); }" myFixture.completeBasic() - assert myFixture.lookupElementStrings == ['@code', '@docRoot', '@index', '@inheritDoc', '@link', '@linkplain', '@literal', '@summary', '@systemProperty', '@value'] + assert myFixture.lookupElementStrings == ['@code', '@docRoot', '@index', '@inheritDoc', '@link', '@linkplain', '@literal', '@snippet', '@summary', '@systemProperty', '@value'] def element = myFixture.lookupElements[4] assert element.lookupString == "@link" selectItem(element) diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java index 0f85ac7c8942..59a614261d9f 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java @@ -308,6 +308,12 @@ public class DataFlowInspection8Test extends DataFlowInspectionTestCase { myFixture.addClass("package org.eclipse.jdt.annotation;public @interface NonNullByDefault {}"); doTest(); } + public void testEclipseDefaultOptionalOrElse() { + myFixture.addClass("package org.eclipse.jdt.annotation;public @interface NonNullByDefault {}"); + myFixture.addClass("package org.eclipse.jdt.annotation;import java.lang.annotation.*;" + + "@Target({ElementType.TYPE_USE}) public @interface Nullable {}"); + doTest(); + } public void testClassInsideLambda() { doTest(); } public void testMultiDimensionalArrays() { setupTypeUseAnnotations("typeUse", myFixture); diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java index f68e169505f4..a6e66e27f33b 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java @@ -698,6 +698,7 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase { public void testBoxedDivisionComparison() { doTest(); } public void testUnknownComparedToNullable() { doTest(); } public void testCastInCatch() { doTest(); } + public void testFieldUpdateViaSetter() { doTest(); } public void testInitArrayInConstructor() { doTest(); } public void testGetterNullityAfterCheck() { doTest(); } public void testInferenceNullityMismatch() { doTestWith(insp -> insp.SUGGEST_NULLABLE_ANNOTATIONS = false); } diff --git a/java/jdkAnnotations/java/util/annotations.xml b/java/jdkAnnotations/java/util/annotations.xml index 04d2fe86fbb8..f2a1a11e38a8 100644 --- a/java/jdkAnnotations/java/util/annotations.xml +++ b/java/jdkAnnotations/java/util/annotations.xml @@ -3429,6 +3429,7 @@ </annotation> </item> <item name='java.util.Optional T orElse(T) 0'> + <annotation name='org.jetbrains.annotations.Nullable'/> <annotation name='org.intellij.lang.annotations.Flow'> <val name="targetIsContainer" val="true"/> </annotation> diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/LanguageLevel.java b/jps/model-api/src/org/jetbrains/jps/model/java/LanguageLevel.java index 2f1de1828167..75c8c09f52c8 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/java/LanguageLevel.java +++ b/jps/model-api/src/org/jetbrains/jps/model/java/LanguageLevel.java @@ -26,7 +26,7 @@ public enum LanguageLevel { JDK_18(18), JDK_18_PREVIEW(18), JDK_X(19); - public static final LanguageLevel HIGHEST = JDK_17; + public static final LanguageLevel HIGHEST = JDK_18; private final JavaVersion myVersion; diff --git a/jvm/jvm-analysis-kotlin-tests/testData/codeInspection/junit5malformed/MalformedParameterizedCollectionKt.kt b/jvm/jvm-analysis-kotlin-tests/testData/codeInspection/junit5malformed/MalformedParameterizedCollectionKt.kt new file mode 100644 index 000000000000..4f6e7109d032 --- /dev/null +++ b/jvm/jvm-analysis-kotlin-tests/testData/codeInspection/junit5malformed/MalformedParameterizedCollectionKt.kt @@ -0,0 +1,16 @@ +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EmptySource + +object MalformedParameterizedCollectionKt { + @ParameterizedTest + @EmptySource + fun testFooSet(input: Set<String?>?) {} + + @ParameterizedTest + @EmptySource + fun testFooList(input: List<String?>?) {} + + @ParameterizedTest + @EmptySource + fun testFooMap(input: Map<String?, String?>?) {} +} diff --git a/jvm/jvm-analysis-kotlin-tests/testSrc/com/intellij/codeInspection/tests/kotlin/KotlinJUnit5MalformedParameterizedTest.kt b/jvm/jvm-analysis-kotlin-tests/testSrc/com/intellij/codeInspection/tests/kotlin/KotlinJUnit5MalformedParameterizedTest.kt index d4f3f4331430..8dd293f0d8b3 100644 --- a/jvm/jvm-analysis-kotlin-tests/testSrc/com/intellij/codeInspection/tests/kotlin/KotlinJUnit5MalformedParameterizedTest.kt +++ b/jvm/jvm-analysis-kotlin-tests/testSrc/com/intellij/codeInspection/tests/kotlin/KotlinJUnit5MalformedParameterizedTest.kt @@ -54,6 +54,10 @@ class KotlinJUnit5MalformedParameterizedTest : JavaCodeInsightFixtureTestCase() myFixture.testHighlighting("CantResolveTarget.kt") } + fun `test MalformedParameterizedCollectionKt`() { + myFixture.testHighlighting("MalformedParameterizedCollectionKt.kt") + } + fun `test CantResolveTarget highlighting`() { myFixture.testHighlighting("CantResolveTarget.kt") } @@ -87,4 +91,4 @@ class KotlinJUnit5MalformedParameterizedTest : JavaCodeInsightFixtureTestCase() fun `test EnumResolve quickFixes`() { myFixture.testHighlighting("EnumResolve.kt") } -}
\ No newline at end of file +} diff --git a/jvm/jvm-analysis-tests/src/com/intellij/codeInspection/tests/JUnit5AssertionsConverterInspectionTestBase.kt b/jvm/jvm-analysis-tests/src/com/intellij/codeInspection/tests/JUnit5AssertionsConverterInspectionTestBase.kt index f7fc55351cae..c997aad4c7d5 100644 --- a/jvm/jvm-analysis-tests/src/com/intellij/codeInspection/tests/JUnit5AssertionsConverterInspectionTestBase.kt +++ b/jvm/jvm-analysis-tests/src/com/intellij/codeInspection/tests/JUnit5AssertionsConverterInspectionTestBase.kt @@ -51,6 +51,10 @@ abstract class JUnit5AssertionsConverterInspectionTestBase : UastInspectionTestB public @interface Test {} """.trimIndent()) myFixture.addClass(""" + package org.junit.platform.commons.annotation; + public @interface Testable {} + """.trimIndent()) + myFixture.addClass(""" package org.junit.jupiter.api; public final class Assertions { public static void assertArrayEquals(Object[] expected, Object[] actual) {} diff --git a/license/hdrhistogram_license.txt b/license/hdrhistogram_license.txt deleted file mode 100644 index 401ccfb0ec51..000000000000 --- a/license/hdrhistogram_license.txt +++ /dev/null @@ -1,41 +0,0 @@ -The code in this repository code was Written by Gil Tene, Michael Barker, -and Matt Warren, and released to the public domain, as explained at -http://creativecommons.org/publicdomain/zero/1.0/ - -For users of this code who wish to consume it under the "BSD" license -rather than under the public domain or CC0 contribution text mentioned -above, the code found under this directory is *also* provided under the -following license (commonly referred to as the BSD 2-Clause License). This -license does not detract from the above stated release of the code into -the public domain, and simply represents an additional license granted by -the Author. - ------------------------------------------------------------------------------ -** Beginning of "BSD 2-Clause License" text. ** - - Copyright (c) 2012, 2013, 2014, 2015, 2016 Gil Tene - Copyright (c) 2014 Michael Barker - Copyright (c) 2014 Matt Warren - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - THE POSSIBILITY OF SUCH DAMAGE. diff --git a/license/r8_license.txt b/license/r8_license.txt deleted file mode 100644 index b9cd251b54f0..000000000000 --- a/license/r8_license.txt +++ /dev/null @@ -1,382 +0,0 @@ -This file lists all licenses for code distributed. -All non-library code has the following 3-Clause BSD license. - - -Copyright (c) 2016, the R8 project authors. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of Google Inc. nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Summary of distributed libraries: - -- artifact: com.google.guava:guava:+ - name: Guava Google Core Libraries for Java - copyrightHolder: The Guava Authors - license: The Apache Software License, Version 2.0 - licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt -- artifact: com.google.code.gson:gson:+ - name: Gson - license: The Apache Software License, Version 2.0 - licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt - url: https://github.com/google/gson -- artifact: it.unimi.dsi:fastutil:+ - name: fastutil - license: Apache License, Version 2.0 - licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.html - url: http://fasutil.di.unimi.it/ -- artifact: net.sf.jopt-simple:jopt-simple:+ - name: JOpt Simple - license: The MIT License - licenseUrl: http://www.opensource.org/licenses/mit-license.php - url: http://pholser.github.com/jopt-simple -- artifact: org.ow2.asm:asm-commons:+ - name: ASM Commons - copyrightHolder: INRIA, France Telecom - license: ASM license - licenseUrl: http://asm.ow2.org/license.html - url: http://asm.ow2.org/index.html -- artifact: org.ow2.asm:asm-tree:+ - name: ASM Tree - copyrightHolder: INRIA, France Telecom - license: ASM license - licenseUrl: http://asm.ow2.org/license.html - url: http://asm.ow2.org/index.html -- artifact: org.ow2.asm:asm-util:+ - name: ASM Util - copyrightHolder: INRIA, France Telecom - license: ASM license - licenseUrl: http://asm.ow2.org/license.html - url: http://asm.ow2.org/index.html -- artifact: org.ow2.asm:asm-analysis:+ - name: ASM Util - copyrightHolder: INRIA, France Telecom - license: ASM license - licenseUrl: http://asm.ow2.org/license.html - url: http://asm.ow2.org/index.html -- artifact: org.ow2.asm:asm:+ - name: ASM Core - copyrightHolder: INRIA, France Telecom - license: ASM license - licenseUrl: http://asm.ow2.org/license.html - url: http://asm.ow2.org/index.html -- artifact: org.jetbrains.kotlin:kotlin-stdlib:+ - name: org.jetbrains.kotlin:kotlin-stdlib - copyrightHolder: JetBrains s.r.o. - license: The Apache License, Version 2.0 - licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt - url: https://kotlinlang.org/ -- artifact: org.jetbrains.kotlin:kotlin-stdlib-common:+ - name: org.jetbrains.kotlin:kotlin-stdlib - copyrightHolder: JetBrains s.r.o. - license: The Apache License, Version 2.0 - licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt - url: https://kotlinlang.org/ -- artifact: org.jetbrains.kotlinx:kotlinx-metadata-jvm:+ - name: org.jetbrains.kotlinx:kotlinx-metadata-jvm - copyrightHolder: JetBrains s.r.o. - license: The Apache License, Version 2.0 - licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt - url: https://kotlinlang.org/ -- artifact: org.jetbrains:annotations:+ - name: IntelliJ IDEA Annotations - copyrightHolder: JetBrains s.r.o. - license: The Apache Software License, Version 2.0 - licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt - url: http://www.jetbrains.org - - -Licenses details: - - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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 (c) 2000-2011 INRIA, France Telecom -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -3. Neither the name of the copyright holders nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -THE POSSIBILITY OF SUCH DAMAGE. - -Apache Commons Compress -Copyright 2002-2016 The Apache Software Foundation - -This product includes software developed at -The Apache Software Foundation (http://www.apache.org/). - -The files in the package org.apache.commons.compress.archivers.sevenz -were derived from the LZMA SDK, version 9.20 (C/ and CPP/7zip/), -which has been placed in the public domain: - -"LZMA SDK is placed in the public domain." (http://www.7-zip.org/sdk.html) - - - The MIT License - - Copyright (c) 2004-2016 Paul R. Holser, Jr. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/completion/CompletionUtil.java b/platform/analysis-impl/src/com/intellij/codeInsight/completion/CompletionUtil.java index df0c47c97712..15b5f93f7567 100644 --- a/platform/analysis-impl/src/com/intellij/codeInsight/completion/CompletionUtil.java +++ b/platform/analysis-impl/src/com/intellij/codeInsight/completion/CompletionUtil.java @@ -1,4 +1,4 @@ -// Copyright 2000-2020 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.completion; import com.intellij.codeInsight.TailType; @@ -90,7 +90,7 @@ public final class CompletionUtil { } /** - * @return an alphanumertic prefix for completion matching, calculated from the given parameters. + * @return an alphanumeric prefix for completion matching, calculated from the given parameters. * The prefix is the longest substring from inside {@code parameters.getPosition()}'s text, * ending at {@code parameters.getOffset()}, consisting of letters and digits. */ diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/RainbowVisitor.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/RainbowVisitor.java index 11035f930ad8..49f9067b9edd 100644 --- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/RainbowVisitor.java +++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/RainbowVisitor.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2016 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.daemon; import com.intellij.codeHighlighting.RainbowHighlighter; @@ -26,6 +12,13 @@ import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +/** + * Provides an additional coloring layer to improve the visual distinction of several related items (e.g., method parameters, local variables). + * <p/> + * Register in {@code com.intellij.highlightVisitor} extension point. + * <p/> + * Implement {@link com.intellij.openapi.options.colors.RainbowColorSettingsPage} in corresponding {@link com.intellij.openapi.options.colors.ColorSettingsPage}. + */ public abstract class RainbowVisitor implements HighlightVisitor { private HighlightInfoHolder myHolder; private RainbowHighlighter myRainbowHighlighter; diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/FileStatusMap.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/FileStatusMap.java index 3b635f5fe299..c74f2ec31695 100644 --- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/FileStatusMap.java +++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/FileStatusMap.java @@ -1,4 +1,4 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.daemon.impl; import com.intellij.codeHighlighting.DirtyScopeTrackingHighlightingPassFactory; @@ -137,7 +137,7 @@ public final class FileStatusMap implements Disposable { public String toString() { @NonNls StringBuilder s = new StringBuilder(); s.append("defensivelyMarked = ").append(defensivelyMarked); - s.append("; wolfPassFinfished = ").append(wolfPassFinished); + s.append("; wolfPassFinished = ").append(wolfPassFinished); s.append("; errorFound = ").append(errorFound); s.append("; dirtyScopes: ("); dirtyScopes.forEach((passId, rangeMarker) -> diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/lookup/LookupItem.java b/platform/analysis-impl/src/com/intellij/codeInsight/lookup/LookupItem.java index 6fb1a755c85d..b65771489336 100644 --- a/platform/analysis-impl/src/com/intellij/codeInsight/lookup/LookupItem.java +++ b/platform/analysis-impl/src/com/intellij/codeInsight/lookup/LookupItem.java @@ -1,4 +1,4 @@ -// Copyright 2000-2020 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.lookup; @@ -92,8 +92,7 @@ public class LookupItem<T> extends MutableLookupElement implements Comparable { } /** - * Returns a string which will be inserted to the editor when this item is - * choosen. + * Returns a string which will be inserted to the editor when this item is chosen. */ @Override @NotNull diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/CommunityLibraryLicenses.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/CommunityLibraryLicenses.groovy index 8a2be6cd82a6..586369c16ead 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/CommunityLibraryLicenses.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/CommunityLibraryLicenses.groovy @@ -264,8 +264,7 @@ final class CommunityLibraryLicenses { new LibraryLicense(name: "dbus-java", libraryName: "dbus-java", license: "LGPL", url: "https://mvnrepository.com/artifact/com.github.hypfvieh/dbus-java"), new LibraryLicense(name: "DecentXML", libraryName: "decentxml", - license: "New BSD License", licenseUrl: "https://www.opensource.org/licenses/bsd-license.php", - url: "https://code.google.com/p/decentxml"), + url: "https://code.google.com/p/decentxml").newBsd(), new LibraryLicense(name: "docutils", attachedTo: "intellij.python", version: "0.12", license: "BSD", url: "https://docutils.sourceforge.io/"), new LibraryLicense(libraryName: "DTDParser", version: "1.13", license: "LGPL", url: "https://sourceforge.net/projects/dtdparser/", @@ -415,7 +414,7 @@ final class CommunityLibraryLicenses { licenseUrl: "https://github.com/json-path/JsonPath/blob/master/LICENSE").apache(), new LibraryLicense(libraryName: "jb-jdi", license: "GPL 2.0 + Classpath", url: "https://github.com/JetBrains/intellij-deps-jdi", licenseUrl: "https://raw.githubusercontent.com/JetBrains/intellij-deps-jdi/master/LICENSE.txt"), - new LibraryLicense(name: "JCEF", libraryName: "jcef", license: "Permissive", + new LibraryLicense(name: "JCEF", libraryName: "jcef", license: "BSD 3-Clause", licenseUrl: "https://bitbucket.org/chromiumembedded/java-cef/src/master/LICENSE.txt", url: "https://bitbucket.org/chromiumembedded/java-cef"), new LibraryLicense(name: "JCIP Annotations", libraryName: "jcip", license: "Creative Commons Attribution License", @@ -643,6 +642,7 @@ final class CommunityLibraryLicenses { url: "https://github.com/googlefonts/roboto", licenseUrl: "https://github.com/google/roboto/blob/master/LICENSE").apache(), new LibraryLicense(name: "roman", attachedTo: "intellij.python", version: "1.4.0", + url: "https://docutils.sourceforge.io/docutils/utils/roman.py", license: "Python 2.1.1 license", licenseUrl: "https://www.python.org/download/releases/2.1.1/license/"), new LibraryLicense(libraryName: "sa-jdwp", license: "GPL 2.0 + Classpath", url: "https://github.com/JetBrains/jdk-sa-jdwp", @@ -756,7 +756,8 @@ final class CommunityLibraryLicenses { new LibraryLicense(name: "XStream", libraryName: "XStream", url: "https://x-stream.github.io/", licenseUrl: "https://x-stream.github.io/license.html").newBsd(), new LibraryLicense(name: "XZ for Java", libraryName: "xz", license: "Public Domain", - url: "https://tukaani.org/xz/java.html"), + url: "https://tukaani.org/xz/java.html", + licenseUrl: "https://git.tukaani.org/?p=xz-java.git;a=blob;f=COPYING;h=8dd17645c4610c3d5eed9bcdd2699ecfac00406b;hb=refs/heads/master"), new LibraryLicense(name: "zip-signer", libraryName: "zip-signer", url: "https://github.com/JetBrains/marketplace-zip-signer").apache(), new LibraryLicense(name: "Zstd-JNI", libraryName: "com.github.luben:zstd", diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/CommunityRepositoryModules.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/CommunityRepositoryModules.groovy index b75945c71f1b..b2110f962f02 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/CommunityRepositoryModules.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/CommunityRepositoryModules.groovy @@ -122,7 +122,6 @@ final class CommunityRepositoryModules { withModule("intellij.packageSearch.maven") withModule("intellij.packageSearch.kotlin") }, - plugin("intellij.externalSystem.dependencyUpdater"), plugin("intellij.gradle.dependencyUpdater"), plugin("intellij.android.gradle.dsl"), plugin("intellij.gradle.java") { diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/LibraryLicense.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/LibraryLicense.groovy index 983a1fa41d4b..23bcd3e103d8 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/LibraryLicense.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/LibraryLicense.groovy @@ -1,4 +1,4 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.intellij.build import com.intellij.util.containers.ContainerUtil @@ -120,7 +120,7 @@ final class LibraryLicense { additionalLibraryNames: additionalLibraryNames, attachedTo: attachedTo, transitiveDependency: transitiveDependency, - license: "Simplified BSD", + license: "BSD 2-Clause", licenseUrl: licenseUrl ?: "https://opensource.org/licenses/BSD-2-Clause" ) } @@ -136,7 +136,7 @@ final class LibraryLicense { additionalLibraryNames: additionalLibraryNames, attachedTo: attachedTo, transitiveDependency: transitiveDependency, - license: "New BSD", + license: "BSD 3-Clause", licenseUrl: licenseUrl ?: "https://opensource.org/licenses/BSD-3-Clause" ) } diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/PlatformModules.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/PlatformModules.groovy index 1ba64c15ce26..868c1a9741be 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/PlatformModules.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/PlatformModules.groovy @@ -37,6 +37,7 @@ final class PlatformModules { "intellij.platform.vcs.dvcs", "intellij.platform.editor", "intellij.platform.externalSystem", + "intellij.platform.externalSystem.dependencyUpdater", "intellij.platform.codeStyle", "intellij.platform.indexing", "intellij.platform.jps.model", diff --git a/platform/code-style-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java b/platform/code-style-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java index 12e2de926007..072d92fea2d4 100644 --- a/platform/code-style-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java +++ b/platform/code-style-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java @@ -1,4 +1,4 @@ -// Copyright 2000-2021 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.psi.codeStyle; import com.intellij.CodeStyleBundle; @@ -186,7 +186,7 @@ public class CodeStyleSettings extends LegacyCodeStyleSettings implements Clonea private static final String ourSystemLineSeparator = System.lineSeparator(); /** - * Line separator. It can be null if choosen line separator is "System-dependent"! + * Line separator. It can be null if chosen line separator is "System-dependent"! */ public String LINE_SEPARATOR; diff --git a/platform/code-style-impl/src/com/intellij/formatting/FormatterIterationMonitor.java b/platform/code-style-impl/src/com/intellij/formatting/FormatterIterationMonitor.java index d7636f1fae15..c47bd64d67ed 100644 --- a/platform/code-style-impl/src/com/intellij/formatting/FormatterIterationMonitor.java +++ b/platform/code-style-impl/src/com/intellij/formatting/FormatterIterationMonitor.java @@ -1,12 +1,12 @@ -// Copyright 2000-2019 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.formatting; import com.intellij.openapi.diagnostic.Logger; import org.jetbrains.annotations.NotNull; /** - * Prevents formatter from endlessly doing some iterations for some specific and probably erroneus models, for e.g. with - * unrestricted block nesting, wrapping and etc. + * Prevents formatter from endlessly doing some iterations for some specific and probably erroneous models, for e.g. with + * unrestricted block nesting, wrapping, etc. */ public class FormatterIterationMonitor<T> { private final static Logger LOG = Logger.getInstance(FormatterIterationMonitor.class); diff --git a/platform/core-api/src/com/intellij/openapi/fileEditor/FileDocumentManager.java b/platform/core-api/src/com/intellij/openapi/fileEditor/FileDocumentManager.java index 013697e54e66..853e930c84e6 100644 --- a/platform/core-api/src/com/intellij/openapi/fileEditor/FileDocumentManager.java +++ b/platform/core-api/src/com/intellij/openapi/fileEditor/FileDocumentManager.java @@ -1,4 +1,4 @@ -// Copyright 2000-2020 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.openapi.fileEditor; import com.intellij.core.CoreBundle; @@ -113,7 +113,7 @@ public abstract class FileDocumentManager implements SavingRequestor { /** * Feeds all documents that have unsaved changes to the processor passed - * @param processor - Processor to collect all the unsaved documents. Return false to stop processing or true to contunue + * @param processor - Processor to collect all the unsaved documents. Return false to stop processing or true to continue. * @return false if processing has been stopped before all the unsaved documents where processed */ public boolean processUnsavedDocuments(Processor<? super Document> processor) { diff --git a/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java b/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java index 4668b26303a5..4b16be62e3bd 100644 --- a/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java +++ b/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java @@ -13,6 +13,7 @@ import com.intellij.openapi.util.SystemInfoRt; import com.intellij.openapi.util.io.BufferExposingByteArrayInputStream; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.FileUtilRt; +import com.intellij.openapi.util.io.OSAgnosticPathUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.util.text.StringUtilRt; import com.intellij.util.PathUtil; @@ -598,8 +599,8 @@ public class VfsUtilCore { if (!SystemInfoRt.isWindows) uri = "/" + uri; file = VirtualFileManager.getInstance().findFileByUrl(StandardFileSystems.JAR_PROTOCOL_PREFIX + uri); } - else if (!SystemInfoRt.isWindows && StringUtil.startsWithChar(uri, '/') || - SystemInfoRt.isWindows && uri.length() >= 2 && Character.isLetter(uri.charAt(0)) && uri.charAt(1) == ':') { + else if (SystemInfoRt.isUnix && uri.startsWith("/") || + SystemInfoRt.isWindows && (OSAgnosticPathUtil.isAbsoluteDosPath(uri) || OSAgnosticPathUtil.isUncPath(uri))) { file = StandardFileSystems.local().findFileByPath(uri); } @@ -831,4 +832,4 @@ public class VfsUtilCore { //noinspection deprecation return new CompactVirtualFileSet(files); } -}
\ No newline at end of file +} diff --git a/platform/core-impl/src/com/intellij/ide/plugins/ModuleGraph.kt b/platform/core-impl/src/com/intellij/ide/plugins/ModuleGraph.kt index a37b45e548e1..df8a78330eda 100644 --- a/platform/core-impl/src/com/intellij/ide/plugins/ModuleGraph.kt +++ b/platform/core-impl/src/com/intellij/ide/plugins/ModuleGraph.kt @@ -205,12 +205,7 @@ private fun collectDirectDependenciesInOldFormat(rootDescriptor: IdeaPluginDescr } } - if (rootDescriptor.pluginId == PluginManagerCore.JAVA_PLUGIN_ID) { - idMap.get(PluginManagerCore.CORE_ID.idString)!!.content.modules.firstOrNull { it.name == "intellij.platform.feedback" }?.let { - result.add(it.requireDescriptor()) - } - } - else if (knownNotFullyMigratedPluginIds.contains(rootDescriptor.pluginId.idString)) { + if (knownNotFullyMigratedPluginIds.contains(rootDescriptor.pluginId.idString)) { idMap.get(PluginManagerCore.CORE_ID.idString)!!.content.modules.mapTo(result) { it.requireDescriptor() } } diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerImpl.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerImpl.java index 46b2e8349bb7..72f4c575726c 100644 --- a/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerImpl.java +++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerImpl.java @@ -20,7 +20,6 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.DocumentUtil; import com.intellij.util.ObjectUtils; import com.intellij.util.diff.FilesTooBigForDiffException; -import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -35,8 +34,7 @@ public class RangeMarkerImpl extends UserDataHolderBase implements RangeMarkerEx private final long myId; private static final StripedIDGenerator counter = new StripedIDGenerator(); - @ApiStatus.Internal - public RangeMarkerImpl(@NotNull DocumentEx document, int start, int end, boolean register, boolean forceDocumentStrongReference) { + RangeMarkerImpl(@NotNull DocumentEx document, int start, int end, boolean register, boolean forceDocumentStrongReference) { this(forceDocumentStrongReference ? document : ObjectUtils.notNull(FileDocumentManager.getInstance().getFile(document), document), document.getTextLength(), start, end, register, false, false); } diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java index 2e49ca54556c..5de3dd1bc765 100644 --- a/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java +++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java @@ -9,7 +9,6 @@ import com.intellij.openapi.editor.ex.PrioritizedDocumentListener; import com.intellij.openapi.editor.ex.RangeMarkerEx; import com.intellij.util.DocumentEventUtil; import com.intellij.util.SmartList; -import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -18,10 +17,8 @@ import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; -@ApiStatus.Internal -public class RangeMarkerTree<T extends RangeMarkerEx> extends IntervalTreeImpl<T> implements PrioritizedDocumentListener { - - public RangeMarkerTree(@NotNull Document document) { +class RangeMarkerTree<T extends RangeMarkerEx> extends IntervalTreeImpl<T> implements PrioritizedDocumentListener { + RangeMarkerTree(@NotNull Document document) { document.addDocumentListener(this); } RangeMarkerTree() { @@ -56,7 +53,7 @@ public class RangeMarkerTree<T extends RangeMarkerEx> extends IntervalTreeImpl<T return 0; } - public void dispose(@NotNull Document document) { + void dispose(@NotNull Document document) { document.removeDocumentListener(this); } @@ -114,8 +111,7 @@ public class RangeMarkerTree<T extends RangeMarkerEx> extends IntervalTreeImpl<T ((RangeMarkerImpl)key).myNode = (RMNode<RangeMarkerEx>)intervalNode; } - @ApiStatus.Internal - public static class RMNode<T extends RangeMarkerEx> extends IntervalTreeImpl.IntervalNode<T> { + static class RMNode<T extends RangeMarkerEx> extends IntervalTreeImpl.IntervalNode<T> { private static final byte EXPAND_TO_LEFT_FLAG = VALID_FLAG<<1; private static final byte EXPAND_TO_RIGHT_FLAG = EXPAND_TO_LEFT_FLAG<<1; static final byte STICK_TO_RIGHT_FLAG = EXPAND_TO_RIGHT_FLAG<<1; diff --git a/platform/core-ui/src/ui/RasterizedImageDataLoader.java b/platform/core-ui/src/ui/RasterizedImageDataLoader.java index b77a75fcbe90..e68db1fb1b83 100644 --- a/platform/core-ui/src/ui/RasterizedImageDataLoader.java +++ b/platform/core-ui/src/ui/RasterizedImageDataLoader.java @@ -25,7 +25,6 @@ import java.io.IOException; import java.lang.ref.WeakReference; import java.net.MalformedURLException; import java.net.URL; -import java.util.Arrays; import java.util.List; final class RasterizedImageDataLoader implements ImageDataLoader { @@ -64,8 +63,10 @@ final class RasterizedImageDataLoader implements ImageDataLoader { int cacheKey, int imageFlags) { String effectivePath = normalizePath(patched.first); - WeakReference<ClassLoader> effectiveClassLoaderRef = patched.second == null ? originalClassLoaderRef : new WeakReference<>(patched.second); - return new RasterizedImageDataLoader(effectivePath, effectiveClassLoaderRef, originalPath, originalClassLoaderRef, cacheKey, imageFlags); + WeakReference<ClassLoader> effectiveClassLoaderRef = + patched.second == null ? originalClassLoaderRef : new WeakReference<>(patched.second); + return new RasterizedImageDataLoader(effectivePath, effectiveClassLoaderRef, originalPath, originalClassLoaderRef, cacheKey, + imageFlags); } @Override @@ -81,14 +82,21 @@ final class RasterizedImageDataLoader implements ImageDataLoader { } // use cache key only if path to image is not customized - if (originalPath == path) { - boolean isSvg = cacheKey != 0; - // use cache key only if path to image is not customized - return loadRasterized(path, filters, classLoader, flags, scaleContext, isSvg, cacheKey, imageFlags, false); + try { + //noinspection StringEquality + if (originalPath == path) { + boolean isSvg = cacheKey != 0; + // use cache key only if path to image is not customized + return loadRasterized(path, filters, classLoader, flags, scaleContext, isSvg, cacheKey, imageFlags, false); + } + else { + boolean isSvg = path.endsWith(".svg"); + return loadRasterized(path, filters, classLoader, flags, scaleContext, isSvg, 0, imageFlags, true); + } } - else { - boolean isSvg = path.endsWith(".svg"); - return loadRasterized(path, filters, classLoader, flags, scaleContext, isSvg, 0, imageFlags, true); + catch (IOException e) { + Logger.getInstance(RasterizedImageDataLoader.class).debug(e); + return null; } } @@ -103,6 +111,7 @@ final class RasterizedImageDataLoader implements ImageDataLoader { ClassLoader classLoader = classLoaderRef.get(); Pair<String, ClassLoader> patched = transform.patchPath(originalPath, classLoader); if (patched == null) { + //noinspection StringEquality if (path != this.originalPath && this.originalPath.equals(normalizePath(originalPath))) { return new RasterizedImageDataLoader(this.originalPath, this.originalClassLoaderRef, this.originalPath, this.originalClassLoaderRef, @@ -146,7 +155,7 @@ final class RasterizedImageDataLoader implements ImageDataLoader { boolean isSvg, int rasterizedCacheKey, @MagicConstant(flagsFromClass = ImageDescriptor.class) int imageFlags, - boolean patched) { + boolean patched) throws IOException { long loadingStart = StartUpMeasurer.getCurrentTimeIfEnabled(); // Prefer retina images for HiDPI scale, because downscaling @@ -186,14 +195,17 @@ final class RasterizedImageDataLoader implements ImageDataLoader { } } - List<Pair<String, Float>> effectivePaths; + // todo remove it, not used + ImageLoader.Dimension2DDouble originalUserSize = new ImageLoader.Dimension2DDouble(0, 0); if (patched) { + List<Pair<String, Float>> effectivePaths; + Pair<String, Float> retinaDark = new Pair<>(name + "@2x_dark." + ext, isSvg ? scale : 2); Pair<String, Float> dark = new Pair<>(name + "_dark." + ext, isSvg ? scale : 1); Pair<String, Float> retina = new Pair<>(name + "@2x." + ext, isSvg ? scale : 2); Pair<String, Float> plain = new Pair<>(path, isSvg ? scale : 1); if (isRetina && isDark) { - effectivePaths = Arrays.asList(retinaDark, dark, retina, plain); + effectivePaths = List.of(retinaDark, dark, retina, plain); } else if (isDark) { effectivePaths = List.of(dark, plain); @@ -201,16 +213,11 @@ final class RasterizedImageDataLoader implements ImageDataLoader { else { effectivePaths = isRetina ? List.of(retina, plain) : List.of(plain); } - } - else { - effectivePaths = List.of(new Pair<>(effectivePath, imageScale)); - } - ImageLoader.Dimension2DDouble originalUserSize = new ImageLoader.Dimension2DDouble(0, 0); - try { long start = StartUpMeasurer.getCurrentTimeIfEnabled(); Image image = null; - for (Pair<String, Float> effPath: effectivePaths) { + boolean isUpScaleNeeded = !isSvg; + for (Pair<String, Float> effPath : effectivePaths) { String pathToImage = effPath.first; float imgScale = effPath.second; if (isSvg) { @@ -221,13 +228,38 @@ final class RasterizedImageDataLoader implements ImageDataLoader { image = ImageLoader.loadPngFromClassResource(pathToImage, null, classLoader, imgScale, originalUserSize); } - if (image != null) break; + if (image != null) { + if (isUpScaleNeeded) { + isUpScaleNeeded = effPath == plain || effPath == dark; + } + break; + } } if (start != -1) { IconLoadMeasurer.loadFromResources.end(start); + IconLoadMeasurer.addLoading(isSvg, loadingStart); } - if (loadingStart != -1) { + + if (image == null) { + return null; + } + return ImageLoader.convertImage(image, filters, flags, scaleContext, isUpScaleNeeded, StartupUiUtil.isJreHiDPI(scaleContext), + imageScale, isSvg); + } + else { + long start = StartUpMeasurer.getCurrentTimeIfEnabled(); + Image image; + if (isSvg) { + image = SVGLoader.loadFromClassResource(null, classLoader, effectivePath, rasterizedCacheKey, imageScale, isEffectiveDark, + originalUserSize); + } + else { + image = ImageLoader.loadPngFromClassResource(effectivePath, null, classLoader, imageScale, originalUserSize); + } + + if (start != -1) { + IconLoadMeasurer.loadFromResources.end(start); IconLoadMeasurer.addLoading(isSvg, loadingStart); } @@ -237,9 +269,5 @@ final class RasterizedImageDataLoader implements ImageDataLoader { return ImageLoader.convertImage(image, filters, flags, scaleContext, !isSvg, StartupUiUtil.isJreHiDPI(scaleContext), imageScale, isSvg); } - catch (IOException e) { - Logger.getInstance(RasterizedImageDataLoader.class).debug(e); - return null; - } } } diff --git a/platform/diff-api/resources/messages/DiffBundle.properties b/platform/diff-api/resources/messages/DiffBundle.properties index 173bc8b811c4..1927c632938c 100644 --- a/platform/diff-api/resources/messages/DiffBundle.properties +++ b/platform/diff-api/resources/messages/DiffBundle.properties @@ -116,6 +116,7 @@ settings.external.diff.table.difftool.column=Diff Tool settings.external.diff.table.mergetool.column=Merge Tool settings.external.diff.table.remove.dialog.title=Remove External Diff Tool settings.external.diff.table.remove.dialog.message=Are you sure you want to delete the entry? +settings.external.diff.comboBox.value.unknown.filetype.text={0} (Unknown) settings.external.tool.tree.remove.group.warning.title=Unable to Delete a Tool Group settings.external.tool.tree.remove.group.warning.message=Select the tool to be removed diff --git a/platform/diff-api/src/com/intellij/diff/chains/DiffRequestChain.java b/platform/diff-api/src/com/intellij/diff/chains/DiffRequestChain.java index 0c0f2daa6667..46e4a9a4b1ef 100644 --- a/platform/diff-api/src/com/intellij/diff/chains/DiffRequestChain.java +++ b/platform/diff-api/src/com/intellij/diff/chains/DiffRequestChain.java @@ -10,17 +10,21 @@ import org.jetbrains.annotations.NotNull; import java.util.List; /** - * Represents list of changed files (ex: singular commit). + * Represents a list of changed files (ex: singular commit). * The list is not supposed to be changed and can be shown multiple times. * <p> - * Use {@link AsyncDiffRequestChain} to load requests asynchronously after showing UI - * Use {@link com.intellij.openapi.vcs.changes.ui.ChangeDiffRequestChain} for chains with common "Go to change" navigation popup. + * Use {@link SimpleDiffRequestChain} and {@link com.intellij.openapi.vcs.changes.ui.ChangeDiffRequestChain} as typical implementations. + * <p> + * Use {@link AsyncDiffRequestChain} instead if loading the list of changed files is a slow operation * - * @see DiffRequestChainBase + * @see DiffRequestSelectionChain * @see com.intellij.diff.DiffManager#showDiff(Project, DiffRequestChain, DiffDialogHints) * @see com.intellij.diff.impl.CacheDiffRequestChainProcessor */ public interface DiffRequestChain extends UserDataHolder { + /** + * NB: if you're calling this method for an unknown chain type, you should be ready to handle {@link AsyncDiffRequestChain}. + */ @NotNull @RequiresEdt List<? extends DiffRequestProducer> getRequests(); @@ -34,5 +38,6 @@ public interface DiffRequestChain extends UserDataHolder { */ @Deprecated(forRemoval = true) @RequiresEdt - void setIndex(int index); + default void setIndex(int index) { + } } diff --git a/platform/diff-api/src/com/intellij/diff/chains/DiffRequestChainBase.java b/platform/diff-api/src/com/intellij/diff/chains/DiffRequestChainBase.java index a159cb74eaf7..4dd491562f4c 100644 --- a/platform/diff-api/src/com/intellij/diff/chains/DiffRequestChainBase.java +++ b/platform/diff-api/src/com/intellij/diff/chains/DiffRequestChainBase.java @@ -17,6 +17,10 @@ package com.intellij.diff.chains; import com.intellij.openapi.util.UserDataHolderBase; +/** + * @deprecated Do not use: see {@link #setIndex(int)} deprecation. + */ +@Deprecated public abstract class DiffRequestChainBase extends UserDataHolderBase implements DiffRequestChain { private int myIndex; diff --git a/platform/diff-api/src/com/intellij/diff/chains/DiffRequestSelectionChain.java b/platform/diff-api/src/com/intellij/diff/chains/DiffRequestSelectionChain.java new file mode 100644 index 000000000000..2ac84ef3aca1 --- /dev/null +++ b/platform/diff-api/src/com/intellij/diff/chains/DiffRequestSelectionChain.java @@ -0,0 +1,27 @@ +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.diff.chains; + +import com.intellij.openapi.ListSelection; +import com.intellij.util.concurrency.annotations.RequiresEdt; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * Represents a chain that is backed by {@link ListSelection} class. + */ +public interface DiffRequestSelectionChain extends DiffRequestChain { + @NotNull + @RequiresEdt + ListSelection<? extends DiffRequestProducer> getListSelection(); + + @Override + default @NotNull List<? extends DiffRequestProducer> getRequests() { + return getListSelection().getList(); + } + + @Override + default int getIndex() { + return getListSelection().getSelectedIndex(); + } +} diff --git a/platform/diff-api/src/com/intellij/diff/chains/SimpleDiffRequestChain.java b/platform/diff-api/src/com/intellij/diff/chains/SimpleDiffRequestChain.java index 84dddc051ea3..a1efb9c0b496 100644 --- a/platform/diff-api/src/com/intellij/diff/chains/SimpleDiffRequestChain.java +++ b/platform/diff-api/src/com/intellij/diff/chains/SimpleDiffRequestChain.java @@ -16,11 +16,12 @@ package com.intellij.diff.chains; import com.intellij.diff.requests.DiffRequest; +import com.intellij.openapi.ListSelection; import com.intellij.openapi.diff.DiffBundle; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.util.UserDataHolder; -import com.intellij.util.containers.ContainerUtil; +import com.intellij.openapi.util.UserDataHolderBase; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -28,18 +29,22 @@ import java.util.Collections; import java.util.List; import java.util.Objects; -public class SimpleDiffRequestChain extends DiffRequestChainBase { - @NotNull private final List<? extends DiffRequestProducer> myRequests; +public class SimpleDiffRequestChain extends UserDataHolderBase implements DiffRequestSelectionChain { + @NotNull private final ListSelection<? extends DiffRequestProducer> myRequests; public SimpleDiffRequestChain(@NotNull DiffRequest request) { this(Collections.singletonList(request)); } public SimpleDiffRequestChain(@NotNull List<? extends DiffRequest> requests) { - myRequests = ContainerUtil.map(requests, request -> new DiffRequestProducerWrapper(request)); + this(requests, 0); } - private SimpleDiffRequestChain(@NotNull List<? extends DiffRequestProducer> requests, @Nullable Object constructorFlag) { + public SimpleDiffRequestChain(@NotNull List<? extends DiffRequest> requests, int selectedIndex) { + myRequests = ListSelection.createAt(requests, selectedIndex).map(request -> new DiffRequestProducerWrapper(request)); + } + + private SimpleDiffRequestChain(@NotNull ListSelection<? extends DiffRequestProducer> requests, @Nullable Object constructorFlag) { assert constructorFlag == null; myRequests = requests; } @@ -53,14 +58,15 @@ public class SimpleDiffRequestChain extends DiffRequestChainBase { } public static SimpleDiffRequestChain fromProducers(@NotNull List<? extends DiffRequestProducer> producers, int selectedIndex) { - SimpleDiffRequestChain chain = new SimpleDiffRequestChain(producers, null); - if (selectedIndex > 0) chain.setIndex(selectedIndex); - return chain; + return fromProducers(ListSelection.createAt(producers, selectedIndex)); + } + + public static SimpleDiffRequestChain fromProducers(@NotNull ListSelection<? extends DiffRequestProducer> producers) { + return new SimpleDiffRequestChain(producers, null); } @Override - @NotNull - public List<? extends DiffRequestProducer> getRequests() { + public @NotNull ListSelection<? extends DiffRequestProducer> getListSelection() { return myRequests; } diff --git a/platform/platform-api/src/com/intellij/openapi/ListSelection.java b/platform/diff-api/src/com/intellij/openapi/ListSelection.java index 1e400a409017..02adcdfda46d 100644 --- a/platform/platform-api/src/com/intellij/openapi/ListSelection.java +++ b/platform/diff-api/src/com/intellij/openapi/ListSelection.java @@ -1,10 +1,11 @@ -// Copyright 2000-2020 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.openapi; import com.intellij.util.NullableFunction; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.swing.*; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -16,8 +17,13 @@ import java.util.List; public final class ListSelection<T> { @NotNull private final List<T> myList; private final int mySelectedIndex; + private final boolean myExplicitSelection; private ListSelection(@NotNull List<T> list, int selectedIndex) { + this(list, selectedIndex, false); + } + + private ListSelection(@NotNull List<T> list, int selectedIndex, boolean isExplicit) { myList = list; if (selectedIndex >= 0 && selectedIndex < list.size()) { mySelectedIndex = selectedIndex; @@ -25,6 +31,7 @@ public final class ListSelection<T> { else { mySelectedIndex = 0; } + myExplicitSelection = isExplicit; } @NotNull @@ -68,7 +75,7 @@ public final class ListSelection<T> { /** * Map all elements in the list and remove elements for which converter returned null. - * If selected element was removed, select remaining element before it. + * If the selected element was removed, select the last remaining element before it. */ @NotNull public <V> ListSelection<V> map(@NotNull NullableFunction<? super T, ? extends V> convertor) { @@ -79,6 +86,34 @@ public final class ListSelection<T> { V out = convertor.fun(myList.get(i)); if (out != null) result.add(out); } - return new ListSelection<>(result, newSelectionIndex); + + return new ListSelection<>(result, newSelectionIndex, myExplicitSelection); + } + + @NotNull + public ListSelection<T> asExplicitSelection() { + return withExplicitSelection(true); + } + + /** + * @return true if selection was performed explicitly (ex: via multiple selection in JTree) + * <p> + * Ex: see {@link com.intellij.openapi.vcs.changes.ui.VcsTreeModelData#getListSelectionOrAll(JTree)}, + * that might implicitly expand empty or single selection. + */ + @NotNull + public ListSelection<T> withExplicitSelection(boolean value) { + return new ListSelection<>(myList, mySelectedIndex, value); + } + + @NotNull + public List<T> getExplicitSelection() { + if (myList.isEmpty()) return Collections.emptyList(); + if (myExplicitSelection) return myList; + return Collections.singletonList(myList.get(mySelectedIndex)); + } + + public boolean isExplicitSelection() { + return myExplicitSelection; } } diff --git a/platform/diff-impl/intellij.platform.diff.impl.iml b/platform/diff-impl/intellij.platform.diff.impl.iml index 5d1b8d7fe421..afc78f576e8d 100644 --- a/platform/diff-impl/intellij.platform.diff.impl.iml +++ b/platform/diff-impl/intellij.platform.diff.impl.iml @@ -23,5 +23,6 @@ <orderEntry type="library" name="fastutil-min" level="project" /> <orderEntry type="module" module-name="intellij.platform.ide.util.io.impl" /> <orderEntry type="library" name="kotlinx-coroutines-jdk8" level="project" /> + <orderEntry type="library" name="StreamEx" level="project" /> </component> </module>
\ No newline at end of file diff --git a/platform/diff-impl/src/com/intellij/diff/DiffManagerImpl.java b/platform/diff-impl/src/com/intellij/diff/DiffManagerImpl.java index 4974d894857e..0e4c0c4c45b9 100644 --- a/platform/diff-impl/src/com/intellij/diff/DiffManagerImpl.java +++ b/platform/diff-impl/src/com/intellij/diff/DiffManagerImpl.java @@ -2,7 +2,6 @@ package com.intellij.diff; import com.intellij.diff.chains.DiffRequestChain; -import com.intellij.diff.chains.DiffRequestProducer; import com.intellij.diff.chains.SimpleDiffRequestChain; import com.intellij.diff.contents.DiffContent; import com.intellij.diff.editor.ChainDiffVirtualFile; @@ -23,17 +22,13 @@ import com.intellij.diff.util.DiffUtil; import com.intellij.openapi.Disposable; import com.intellij.openapi.diff.DiffBundle; import com.intellij.openapi.fileTypes.FileType; -import com.intellij.openapi.fileTypes.FileTypeManager; -import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.WindowWrapper; import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.util.concurrency.annotations.RequiresEdt; -import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -56,13 +51,10 @@ public class DiffManagerImpl extends DiffManagerEx { @Override public void showDiff(@Nullable Project project, @NotNull DiffRequestChain requests, @NotNull DiffDialogHints hints) { - List<String> files = ContainerUtil.map(requests.getRequests(), DiffRequestProducer::getName); - FileType fileType = determineFileType(files); - - ExternalDiffSettings.ExternalTool diffTool = ExternalDiffSettings.findDiffTool(fileType); - if (ExternalDiffTool.isEnabled() && diffTool != null) { - ExternalDiffTool.show(project, requests, hints, diffTool); - return; + if (ExternalDiffTool.isEnabled()) { + if (ExternalDiffTool.showIfNeeded(project, requests, hints)) { + return; + } } showDiffBuiltin(project, requests, hints); @@ -166,14 +158,4 @@ public class DiffManagerImpl extends DiffManagerEx { public void showMergeBuiltin(@Nullable Project project, @NotNull MergeRequestProducer requestProducer, @NotNull DiffDialogHints hints) { new MergeWindow.ForProducer(project, requestProducer, hints).show(); } - - private static FileType determineFileType(@NotNull List<String> files) { - FileTypeManager fileTypeManager = FileTypeManager.getInstance(); - - return files.stream() - .filter(filePath -> !FileUtilRt.getExtension(filePath).equals("tmp")) - .map(filePath -> fileTypeManager.getFileTypeByFileName(filePath)) - .findAny() - .orElse(FileTypes.UNKNOWN); - } } diff --git a/platform/diff-impl/src/com/intellij/diff/actions/impl/MutableDiffRequestChain.kt b/platform/diff-impl/src/com/intellij/diff/actions/impl/MutableDiffRequestChain.kt index efad29f6e56e..f1bf3df9f9f3 100644 --- a/platform/diff-impl/src/com/intellij/diff/actions/impl/MutableDiffRequestChain.kt +++ b/platform/diff-impl/src/com/intellij/diff/actions/impl/MutableDiffRequestChain.kt @@ -4,7 +4,7 @@ package com.intellij.diff.actions.impl import com.intellij.diff.DiffContext import com.intellij.diff.DiffContextEx import com.intellij.diff.DiffRequestFactory -import com.intellij.diff.chains.DiffRequestChainBase +import com.intellij.diff.chains.DiffRequestChain import com.intellij.diff.chains.DiffRequestProducer import com.intellij.diff.contents.DiffContent import com.intellij.diff.contents.FileContent @@ -25,44 +25,33 @@ import com.intellij.openapi.project.DumbAwareAction import com.intellij.openapi.util.Key import com.intellij.openapi.util.NlsActions import com.intellij.openapi.util.UserDataHolder +import com.intellij.openapi.util.UserDataHolderBase import javax.swing.JComponent -class MutableDiffRequestChain : DiffRequestChainBase { +class MutableDiffRequestChain( + var content1: DiffContent, + var baseContent: DiffContent?, + var content2: DiffContent +) : UserDataHolderBase(), DiffRequestChain { + private val producer = MyDiffRequestProducer() private val requestUserData: MutableMap<Key<*>, Any> = mutableMapOf() - var content1: DiffContent - var content2: DiffContent - var baseContent: DiffContent? = null - var windowTitle: String? = null - var title1: String? = null - var title2: String? = null - var baseTitle: String? = null + var title1: String? = getTitleFor(content1) + var title2: String? = getTitleFor(content2) + var baseTitle: String? = baseContent?.let { getTitleFor(it) } var baseColorMode: ThreeSideDiffColors = ThreeSideDiffColors.LEFT_TO_RIGHT - constructor(content1: DiffContent, content2: DiffContent) { - this.content1 = content1 - this.content2 = content2 - title1 = getTitleFor(content1) - title2 = getTitleFor(content2) - } - - constructor(content1: DiffContent, baseContent: DiffContent?, content2: DiffContent) { - this.content1 = content1 - this.content2 = content2 - this.baseContent = baseContent - title1 = getTitleFor(content1) - title2 = getTitleFor(content2) - baseTitle = if (baseContent != null) getTitleFor(baseContent) else null - } + constructor(content1: DiffContent, content2: DiffContent) : this(content1, null, content2) fun <T : Any> putRequestUserData(key: Key<T>, value: T) { requestUserData.put(key, value) } override fun getRequests(): List<DiffRequestProducer> = listOf(producer) + override fun getIndex(): Int = 0 private inner class MyDiffRequestProducer : DiffRequestProducer { override fun getName(): String { diff --git a/platform/diff-impl/src/com/intellij/diff/chains/AsyncDiffRequestChain.java b/platform/diff-impl/src/com/intellij/diff/chains/AsyncDiffRequestChain.java index 63f194fd1902..37b53da57d42 100644 --- a/platform/diff-impl/src/com/intellij/diff/chains/AsyncDiffRequestChain.java +++ b/platform/diff-impl/src/com/intellij/diff/chains/AsyncDiffRequestChain.java @@ -8,20 +8,24 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.ListSelection; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.util.BackgroundTaskUtil; +import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.util.EventDispatcher; import com.intellij.util.concurrency.annotations.RequiresBackgroundThread; import com.intellij.util.concurrency.annotations.RequiresEdt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Collections; import java.util.EventListener; -import java.util.List; -public abstract class AsyncDiffRequestChain extends DiffRequestChainBase { +/** + * Allows loading requests asynchronously after showing diff UI, without the need for modal progress + * + * @see com.intellij.openapi.vcs.changes.ui.ChangeDiffRequestChain.Async + */ +public abstract class AsyncDiffRequestChain extends UserDataHolderBase implements DiffRequestSelectionChain { private final EventDispatcher<Listener> myDispatcher = EventDispatcher.create(Listener.class); - private volatile List<? extends DiffRequestProducer> myRequests = null; + private volatile ListSelection<? extends DiffRequestProducer> myRequests = null; @Nullable private ProgressIndicator myIndicator; private int myAssignments = 0; @@ -34,12 +38,11 @@ public abstract class AsyncDiffRequestChain extends DiffRequestChainBase { myDispatcher.removeListener(listener); } - @NotNull @Override - public List<? extends DiffRequestProducer> getRequests() { - List<? extends DiffRequestProducer> requests = myRequests; + public @NotNull ListSelection<? extends DiffRequestProducer> getListSelection() { + ListSelection<? extends DiffRequestProducer> requests = myRequests; if (requests == null) { - return Collections.singletonList(new DiffRequestProducerWrapper(new LoadingDiffRequest())); + return ListSelection.createSingleton(new DiffRequestProducerWrapper(new LoadingDiffRequest())); } return requests; } @@ -91,8 +94,7 @@ public abstract class AsyncDiffRequestChain extends DiffRequestChainBase { private void applyLoadedChanges(@NotNull ListSelection<? extends DiffRequestProducer> producers) { if (myRequests != null) return; - myRequests = producers.getList(); - setIndex(producers.getSelectedIndex()); + myRequests = producers; myIndicator = null; myDispatcher.getMulticaster().onRequestsLoaded(); diff --git a/platform/diff-impl/src/com/intellij/diff/settings/ExternalToolsTablePanel.kt b/platform/diff-impl/src/com/intellij/diff/settings/ExternalToolsTablePanel.kt index 06ca2297102b..d30e0ada2439 100644 --- a/platform/diff-impl/src/com/intellij/diff/settings/ExternalToolsTablePanel.kt +++ b/platform/diff-impl/src/com/intellij/diff/settings/ExternalToolsTablePanel.kt @@ -74,7 +74,7 @@ internal class ExternalToolsTablePanel(private val models: ExternalToolsModels) } private fun addData() { - val fileTypes = FileTypeManager.getInstance().registeredFileTypes.map { it.displayName }.toSet() + val fileTypes = FileTypeManager.getInstance().registeredFileTypes.map { it.name }.toSet() val configuredFileTypes = models.tableModel.items.map { it.fileTypeName }.toSet() val availableFileTypes = fileTypes - configuredFileTypes @@ -96,7 +96,6 @@ internal class ExternalToolsTablePanel(private val models: ExternalToolsModels) class FileTypeColumn(private val models: ExternalToolsModels) : ColumnInfo<ExternalToolConfiguration, String>( DiffBundle.message("settings.external.diff.table.filetype.column") ) { - private val fileTypes = FileTypeManager.getInstance().registeredFileTypes.map { it.displayName }.toSet() override fun valueOf(externalToolConfiguration: ExternalToolConfiguration): String { return externalToolConfiguration.fileTypeName @@ -113,6 +112,7 @@ internal class ExternalToolsTablePanel(private val models: ExternalToolsModels) override fun isCellEditable(item: ExternalToolConfiguration): Boolean = true private fun createComboBoxRendererAndEditor(): ComboBoxTableRenderer<String> { + val fileTypes = FileTypeManager.getInstance().registeredFileTypes.map { it.name }.toSet() val configuredFileTypes = models.tableModel.items.map { it.fileTypeName }.toSet() val availableFileTypes = fileTypes - configuredFileTypes @@ -120,7 +120,13 @@ internal class ExternalToolsTablePanel(private val models: ExternalToolsModels) } private class FileTypeCellComboBox(values: Array<String>) : ComboBoxTableRenderer<String>(values) { - private val fileTypeManager = FileTypeManager.getInstance() + private val fileTypes = FileTypeManager.getInstance().registeredFileTypes.associateBy { type -> type.name } + + override fun getTextFor(value: String): String { + // renderer for DEFAULT_TOOL_NAME is overridden + return fileTypes[value]?.displayName + ?: DiffBundle.message("settings.external.diff.comboBox.value.unknown.filetype.text", value) + } override fun getTableCellRendererComponent(table: JTable, value: Any, isSelected: Boolean, hasFocus: Boolean, @@ -142,7 +148,7 @@ internal class ExternalToolsTablePanel(private val models: ExternalToolsModels) return super.getTableCellEditorComponent(table, value, isSelected, row, column) } - override fun getIconFor(value: String): Icon? = fileTypeManager.findFileTypeByName(value)?.icon + override fun getIconFor(value: String): Icon? = fileTypes[value]?.icon } } diff --git a/platform/diff-impl/src/com/intellij/diff/settings/ExternalToolsTreePanel.kt b/platform/diff-impl/src/com/intellij/diff/settings/ExternalToolsTreePanel.kt index f8ac861a6e49..1637f05561eb 100644 --- a/platform/diff-impl/src/com/intellij/diff/settings/ExternalToolsTreePanel.kt +++ b/platform/diff-impl/src/com/intellij/diff/settings/ExternalToolsTreePanel.kt @@ -323,9 +323,11 @@ internal class ExternalToolsTreePanel(private val models: ExternalToolsModels) : testThreeSideDiffButton.isVisible = !isMergeGroup testMergeButton.isVisible = isMergeGroup - argumentPatternField.text = - if (isMergeGroup) MERGE_TOOL_DEFAULT_ARGUMENT_PATTERN - else DIFF_TOOL_DEFAULT_ARGUMENT_PATTERN + if (!isEditMode) { + argumentPatternField.text = + if (isMergeGroup) MERGE_TOOL_DEFAULT_ARGUMENT_PATTERN + else DIFF_TOOL_DEFAULT_ARGUMENT_PATTERN + } argumentPatternDescription.text = if (isMergeGroup) createDescription(ExternalToolGroup.MERGE_TOOL) diff --git a/platform/diff-impl/src/com/intellij/diff/tools/external/ExternalDiffTool.java b/platform/diff-impl/src/com/intellij/diff/tools/external/ExternalDiffTool.java index 3558ab9ad7f9..1c3643482ece 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/external/ExternalDiffTool.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/external/ExternalDiffTool.java @@ -13,6 +13,7 @@ import com.intellij.notification.NotificationType; import com.intellij.openapi.ListSelection; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.diff.DiffBundle; +import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; @@ -21,16 +22,19 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.NlsContexts; import com.intellij.openapi.util.UserDataHolderBase; +import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.util.text.HtmlBuilder; import com.intellij.openapi.util.text.HtmlChunk; import com.intellij.util.ThrowableConvertor; +import com.intellij.util.concurrency.annotations.RequiresBackgroundThread; +import com.intellij.util.concurrency.annotations.RequiresEdt; import com.intellij.util.containers.ContainerUtil; +import one.util.streamex.StreamEx; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.util.ArrayList; -import java.util.Collections; import java.util.List; public final class ExternalDiffTool { @@ -44,27 +48,47 @@ public final class ExternalDiffTool { return isEnabled() && ExternalDiffSettings.isNotBuiltinDiffTool(); } - public static void show(@Nullable final Project project, - @NotNull final DiffRequestChain chain, - @NotNull final DiffDialogHints hints, - @NotNull final ExternalDiffSettings.ExternalTool externalDiffTool) { + public static boolean wantShowExternalToolFor(@NotNull List<? extends DiffRequestProducer> diffProducers) { + if (isDefault()) return true; + + FileTypeManager fileTypeManager = FileTypeManager.getInstance(); + return diffProducers.stream() + .map(DiffRequestProducer::getName) + .filter(filePath -> !FileUtilRt.getExtension(filePath).equals("tmp")) + .map(filePath -> fileTypeManager.getFileTypeByFileName(filePath)) + .distinct() + .anyMatch(fileType -> ExternalDiffSettings.findDiffTool(fileType) != null); + } + + public static boolean showIfNeeded(@Nullable Project project, + @NotNull DiffRequestChain chain, + @NotNull DiffDialogHints hints) { + return show(project, hints, indicator -> { + List<? extends DiffRequestProducer> producers = loadProducersFromChain(chain); + if (!wantShowExternalToolFor(producers)) return null; + return collectRequests(project, producers, indicator); + }); + } + + public static void show(@Nullable Project project, + @NotNull List<? extends DiffRequestProducer> requestProducers, + @NotNull DiffDialogHints hints) { + show(project, hints, indicator -> { + return collectRequests(project, requestProducers, indicator); + }); + } + + private static boolean show(@Nullable Project project, + @NotNull DiffDialogHints hints, + @NotNull ThrowableConvertor<? super ProgressIndicator, List<DiffRequest>, ? extends Exception> requestsProducer) { try { - final List<DiffRequest> requests = loadRequestsUnderProgress(project, chain); - if (requests == null) return; - - List<DiffRequest> showInBuiltin = new ArrayList<>(); - for (DiffRequest request : requests) { - if (canShow(request)) { - showRequest(project, request, externalDiffTool); - } - else { - showInBuiltin.add(request); - } - } + List<DiffRequest> requests = computeWithModalProgress(project, + DiffBundle.message("progress.title.loading.requests"), + requestsProducer); + if (requests == null) return false; - if (!showInBuiltin.isEmpty()) { - DiffManagerEx.getInstance().showDiffBuiltin(project, new SimpleDiffRequestChain(showInBuiltin), hints); - } + showRequests(project, requests, hints); + return true; } catch (ProcessCanceledException ignore) { } @@ -72,36 +96,57 @@ public final class ExternalDiffTool { LOG.warn(e); Messages.showErrorDialog(project, e.getMessage(), DiffBundle.message("can.t.show.diff.in.external.tool")); } + return false; } - @Nullable - private static List<DiffRequest> loadRequestsUnderProgress(@Nullable Project project, - @NotNull DiffRequestChain chain) throws Throwable { - if (chain instanceof AsyncDiffRequestChain) { - return computeWithModalProgress(project, DiffBundle.message("progress.title.loading.requests"), indicator -> { - ListSelection<? extends DiffRequestProducer> listSelection = ((AsyncDiffRequestChain)chain).loadRequestsInBackground(); - return collectRequests(project, listSelection.getList(), listSelection.getSelectedIndex(), indicator); - }); + @RequiresEdt + private static void showRequests(@Nullable Project project, + @NotNull List<DiffRequest> requests, + @NotNull DiffDialogHints hints) throws IOException, ExecutionException { + List<DiffRequest> showInBuiltin = new ArrayList<>(); + for (DiffRequest request : requests) { + boolean success = tryShowRequestInExternal(project, request); + if (!success) { + showInBuiltin.add(request); + } } - else { - List<? extends DiffRequestProducer> allProducers = chain.getRequests(); - int index = chain.getIndex(); - return computeWithModalProgress(project, DiffBundle.message("progress.title.loading.requests"), indicator -> { - return collectRequests(project, allProducers, index, indicator); - }); + if (!showInBuiltin.isEmpty()) { + DiffManagerEx.getInstance().showDiffBuiltin(project, new SimpleDiffRequestChain(showInBuiltin), hints); } } + private static boolean tryShowRequestInExternal(@Nullable Project project, @NotNull DiffRequest request) + throws IOException, ExecutionException { + if (!canShow(request)) return false; + + List<DiffContent> contents = ((ContentDiffRequest)request).getContents(); + ExternalDiffSettings.ExternalTool externalTool = StreamEx.of(contents) + .map(content -> content.getContentType()) + .nonNull() + .map(fileType -> ExternalDiffSettings.findDiffTool(fileType)) + .nonNull() + .findFirst().orElse(null); + if (externalTool == null) return false; + + showRequest(project, request, externalTool); + return true; + } + @NotNull - private static List<DiffRequest> collectRequests(@Nullable Project project, - @NotNull List<? extends DiffRequestProducer> allProducers, - int index, - @NotNull ProgressIndicator indicator) { - // TODO: show all changes on explicit selection (not only `chain.getIndex()` one) - if (allProducers.isEmpty()) return Collections.emptyList(); - List<? extends DiffRequestProducer> producers = Collections.singletonList(allProducers.get(index)); - return collectRequests(project, producers, indicator); + @RequiresBackgroundThread + private static List<? extends DiffRequestProducer> loadProducersFromChain(@NotNull DiffRequestChain chain) { + ListSelection<? extends DiffRequestProducer> listSelection; + if (chain instanceof AsyncDiffRequestChain) { + listSelection = ((AsyncDiffRequestChain)chain).loadRequestsInBackground(); + } + else if (chain instanceof DiffRequestSelectionChain) { + listSelection = ((DiffRequestSelectionChain)chain).getListSelection(); + } + else { + listSelection = ListSelection.createAt(chain.getRequests(), chain.getIndex()); + } + return listSelection.getExplicitSelection(); } @NotNull @@ -126,7 +171,8 @@ public final class ExternalDiffTool { if (!errorRequests.isEmpty()) { HtmlBuilder message = new HtmlBuilder() .appendWithSeparators(HtmlChunk.br(), ContainerUtil.map(errorRequests, producer -> HtmlChunk.text(producer.getName()))); - new Notification("Diff Changes Loading Error", DiffBundle.message("can.t.load.some.changes"), message.toString(), NotificationType.ERROR).notify(project); + new Notification("Diff Changes Loading Error", DiffBundle.message("can.t.load.some.changes"), message.toString(), + NotificationType.ERROR).notify(project); } return requests; @@ -134,7 +180,8 @@ public final class ExternalDiffTool { private static <T> T computeWithModalProgress(@Nullable Project project, @NotNull @NlsContexts.DialogTitle String title, - @NotNull ThrowableConvertor<? super ProgressIndicator, T, ? extends Exception> computable) throws Exception { + @NotNull ThrowableConvertor<? super ProgressIndicator, T, ? extends Exception> computable) + throws Exception { return ProgressManager.getInstance().run(new Task.WithResult<T, Exception>(project, title, true) { @Override protected T compute(@NotNull ProgressIndicator indicator) throws Exception { @@ -145,7 +192,7 @@ public final class ExternalDiffTool { public static void showRequest(@Nullable Project project, @NotNull DiffRequest request, - @NotNull final ExternalDiffSettings.ExternalTool externalDiffTool) throws ExecutionException, IOException { + @NotNull ExternalDiffSettings.ExternalTool externalDiffTool) throws ExecutionException, IOException { request.onAssigned(true); try { List<DiffContent> contents = ((ContentDiffRequest)request).getContents(); diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/ui/BranchActionGroupPopup.java b/platform/dvcs-impl/src/com/intellij/dvcs/ui/BranchActionGroupPopup.java index f640def66f5d..38b45621c586 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/ui/BranchActionGroupPopup.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/ui/BranchActionGroupPopup.java @@ -322,7 +322,6 @@ public final class BranchActionGroupPopup extends FlatSpeedSearchPopup { mySpeedSearch.updatePattern(newFilter.trim()); return; } - getList().setSelectedIndex(0); super.onSpeedSearchPatternChanged(); ScrollingUtil.ensureSelectionExists(getList()); } diff --git a/platform/editor-ui-api/src/com/intellij/ide/projectView/TreeStructureProvider.java b/platform/editor-ui-api/src/com/intellij/ide/projectView/TreeStructureProvider.java index b0cb137bd4db..3a86c5f55dca 100644 --- a/platform/editor-ui-api/src/com/intellij/ide/projectView/TreeStructureProvider.java +++ b/platform/editor-ui-api/src/com/intellij/ide/projectView/TreeStructureProvider.java @@ -1,4 +1,4 @@ -// Copyright 2000-2020 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-2022 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ide.projectView; import com.intellij.ide.util.treeView.AbstractTreeNode; @@ -9,7 +9,9 @@ import org.jetbrains.annotations.Nullable; import java.util.Collection; /** - * Allows a plugin to modify the structure of a project as displayed in the project view. + * Allows modifying the structure of a project as displayed in the project view. + * <p/> + * Can implement {@link com.intellij.openapi.project.DumbAware} additionally. * * @see ProjectViewNodeDecorator */ @@ -17,7 +19,7 @@ public interface TreeStructureProvider { ProjectExtensionPointName<TreeStructureProvider> EP = new ProjectExtensionPointName<>("com.intellij.treeStructureProvider"); /** - * Allows a plugin to modify the list of children displayed for the specified node in the + * Allows modifying the list of children displayed for the specified node in the * project view. * * @param parent the parent node. @@ -25,17 +27,19 @@ public interface TreeStructureProvider { * Elements of the collection are of type {@link ProjectViewNode}. * @param settings the current project view settings. * @return the modified collection of child nodes, or {@code children} if no modifications - * are required. + * are required. */ @NotNull - Collection<AbstractTreeNode<?>> modify(@NotNull AbstractTreeNode<?> parent, @NotNull Collection<AbstractTreeNode<?>> children, ViewSettings settings); + Collection<AbstractTreeNode<?>> modify(@NotNull AbstractTreeNode<?> parent, + @NotNull Collection<AbstractTreeNode<?>> children, + ViewSettings settings); /** * Returns a user data object of the specified type for the specified selection in the * project view. * * @param selected the list of nodes currently selected in the project view. - * @param dataId the identifier of the requested data object (for example, as defined in + * @param dataId the identifier of the requested data object (for example, as defined in * {@link com.intellij.openapi.actionSystem.PlatformDataKeys}) * @return the data object, or null if no data object can be returned by this provider. * @see com.intellij.openapi.actionSystem.DataProvider diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/EditorSettings.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/EditorSettings.java index ded01c0e3bd2..70107ad1c044 100644 --- a/platform/editor-ui-api/src/com/intellij/openapi/editor/EditorSettings.java +++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/EditorSettings.java @@ -1,4 +1,4 @@ -// Copyright 2000-2020 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.openapi.editor; import com.intellij.lang.Language; @@ -40,7 +40,7 @@ public interface EditorSettings { /** * Explicitly sets soft margins (visual indent guides) to be used in the editor instead of obtaining them from code style settings via * {@code CodeStyleSettings.getSoftMargins()} method. It is important to distinguish and empty list from {@code null} value: the first - * will define no soft margins for the eidtor while the latter will restore the default behavior of using them from code style settings. + * will define no soft margins for the editor while the latter will restore the default behavior of using them from code style settings. * @param softMargins A list of soft margins or {@code null} to use margins from code style settings. */ void setSoftMargins(@Nullable List<Integer> softMargins); diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/EditorColorPalette.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/EditorColorPalette.java index 0218c450c28b..e68c68619bf2 100644 --- a/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/EditorColorPalette.java +++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/EditorColorPalette.java @@ -1,4 +1,4 @@ -// Copyright 2000-2020 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.openapi.editor.colors; import com.intellij.openapi.editor.markup.TextAttributes; @@ -61,7 +61,7 @@ public abstract class EditorColorPalette { * Collects colors from known color setup pages. * * @param attrColorReader the function to extract the color from attribute (ex. foreground or background) - * @return the pallete with collected colors + * @return the palette with collected colors */ public EditorColorPalette collectColors(@NotNull Function<? super TextAttributes, ? extends Color> attrColorReader) { return collectColorsWithFilter(attrColorReader, false); @@ -73,7 +73,7 @@ public abstract class EditorColorPalette { * @param attrColorReader the function to extract the color from attribute (ex. foreground or background) * @param filterOutRainbowAttrKeys the flag to filter out the attributes that can be overwritten by semantic highlighting * or not conflicting with semantic highlighting - * @return the pallete with collected colors + * @return the palette with collected colors */ public EditorColorPalette collectColorsWithFilter(@NotNull Function<? super TextAttributes, ? extends Color> attrColorReader, boolean filterOutRainbowAttrKeys) { diff --git a/platform/execution-impl/src/com/intellij/execution/impl/RCInArbitraryFileManager.kt b/platform/execution-impl/src/com/intellij/execution/impl/RCInArbitraryFileManager.kt index ff555033dd6e..a773d0584f73 100644 --- a/platform/execution-impl/src/com/intellij/execution/impl/RCInArbitraryFileManager.kt +++ b/platform/execution-impl/src/com/intellij/execution/impl/RCInArbitraryFileManager.kt @@ -1,4 +1,4 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.execution.impl import com.intellij.configurationStore.digest @@ -274,4 +274,14 @@ internal class RCInArbitraryFileManager(private val project: Project) { file.getOutputStream(this@RCInArbitraryFileManager).use { byteOut.writeTo(it) } } } + + /** + * This function should be called with RunManagerImpl.lock.write + */ + internal fun clearAllAndReturnFilePaths(): Collection<String> { + val filePaths = filePathToRunConfigs.keys.toList() + filePathToRunConfigs.clear() + filePathToDigests.clear() + return filePaths + } } diff --git a/platform/execution-impl/src/com/intellij/execution/impl/RunManagerImpl.kt b/platform/execution-impl/src/com/intellij/execution/impl/RunManagerImpl.kt index 448a6c198ff7..50d2950aad55 100644 --- a/platform/execution-impl/src/com/intellij/execution/impl/RunManagerImpl.kt +++ b/platform/execution-impl/src/com/intellij/execution/impl/RunManagerImpl.kt @@ -1,4 +1,4 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. @file:Suppress("ReplaceGetOrSet", "ReplacePutWithAssignment") package com.intellij.execution.impl @@ -54,7 +54,6 @@ import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.locks.ReentrantReadWriteLock import javax.swing.Icon -import kotlin.collections.HashMap import kotlin.collections.component1 import kotlin.collections.component2 import kotlin.concurrent.read @@ -709,22 +708,31 @@ open class RunManagerImpl @JvmOverloads constructor(val project: Project, shared return methodElement } - @Suppress("unused") /** * used by MPS. Do not use if not approved. */ fun reloadSchemes() { + var arbitraryFilePaths: Collection<String> lock.write { // not really required, but hot swap friendly - 1) factory is used a key, 2) developer can change some defaults. templateDifferenceHelper.clearCache() templateIdToConfiguration.clear() listManager.idToSettings.clear() + arbitraryFilePaths = rcInArbitraryFileManager.clearAllAndReturnFilePaths() recentlyUsedTemporaries.clear() stringIdToBeforeRunProvider.drop() } + workspaceSchemeManager.reload() projectSchemeManager.reload() + reloadRunConfigsFromArbitraryFiles(arbitraryFilePaths) + } + + private fun reloadRunConfigsFromArbitraryFiles(filePaths: Collection<String>) { + for (filePath in filePaths) { + updateRunConfigsFromArbitraryFiles(emptyList(), filePaths) + } } protected open fun addExtensionPointListeners() { diff --git a/platform/execution-impl/src/com/intellij/execution/impl/statistics/RunConfigurationTypeLanguageExtension.java b/platform/execution-impl/src/com/intellij/execution/impl/statistics/RunConfigurationTypeLanguageExtension.java index 8d31578acc84..dea3c407f6bb 100644 --- a/platform/execution-impl/src/com/intellij/execution/impl/statistics/RunConfigurationTypeLanguageExtension.java +++ b/platform/execution-impl/src/com/intellij/execution/impl/statistics/RunConfigurationTypeLanguageExtension.java @@ -1,11 +1,10 @@ -// Copyright 2000-2020 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.execution.impl.statistics; import com.intellij.internal.statistic.eventLog.events.EventField; import com.intellij.internal.statistic.eventLog.events.EventFields; import com.intellij.internal.statistic.service.fus.collectors.FeatureUsageCollectorExtension; -import java.util.Collections; import java.util.List; public class RunConfigurationTypeLanguageExtension implements FeatureUsageCollectorExtension { @@ -21,6 +20,6 @@ public class RunConfigurationTypeLanguageExtension implements FeatureUsageCollec @Override public List<EventField> getExtensionFields() { - return Collections.singletonList(EventFields.Language); + return List.of(EventFields.Language, RunConfigurationUsageTriggerCollector.ALTERNATIVE_JRE_VERSION); } } diff --git a/platform/execution-impl/src/com/intellij/execution/impl/statistics/RunConfigurationTypeUsagesCollector.java b/platform/execution-impl/src/com/intellij/execution/impl/statistics/RunConfigurationTypeUsagesCollector.java index 3494489e1045..eea914ff290d 100644 --- a/platform/execution-impl/src/com/intellij/execution/impl/statistics/RunConfigurationTypeUsagesCollector.java +++ b/platform/execution-impl/src/com/intellij/execution/impl/statistics/RunConfigurationTypeUsagesCollector.java @@ -1,4 +1,4 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.execution.impl.statistics; import com.intellij.execution.RunManager; @@ -33,7 +33,7 @@ import java.util.*; public final class RunConfigurationTypeUsagesCollector extends ProjectUsagesCollector { public static final String CONFIGURED_IN_PROJECT = "configured.in.project"; - public static final EventLogGroup GROUP = new EventLogGroup("run.configuration.type", 10); + public static final EventLogGroup GROUP = new EventLogGroup("run.configuration.type", 11); public static final StringEventField ID_FIELD = EventFields.StringValidatedByCustomRule("id", "run_config_id"); public static final StringEventField FACTORY_FIELD = EventFields.StringValidatedByCustomRule("factory", "run_config_factory"); private static final IntEventField COUNT_FIELD = EventFields.Int("count"); diff --git a/platform/execution-impl/src/com/intellij/execution/impl/statistics/RunConfigurationUsageLanguageExtension.java b/platform/execution-impl/src/com/intellij/execution/impl/statistics/RunConfigurationUsageLanguageExtension.java index 70217c62fdb3..a1c92a27c6a9 100644 --- a/platform/execution-impl/src/com/intellij/execution/impl/statistics/RunConfigurationUsageLanguageExtension.java +++ b/platform/execution-impl/src/com/intellij/execution/impl/statistics/RunConfigurationUsageLanguageExtension.java @@ -1,11 +1,10 @@ -// Copyright 2000-2020 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.execution.impl.statistics; import com.intellij.internal.statistic.eventLog.events.EventField; import com.intellij.internal.statistic.eventLog.events.EventFields; import com.intellij.internal.statistic.service.fus.collectors.FeatureUsageCollectorExtension; -import java.util.Collections; import java.util.List; public class RunConfigurationUsageLanguageExtension implements FeatureUsageCollectorExtension { @@ -21,6 +20,6 @@ public class RunConfigurationUsageLanguageExtension implements FeatureUsageColle @Override public List<EventField> getExtensionFields() { - return Collections.singletonList(EventFields.Language); + return List.of(EventFields.Language, RunConfigurationUsageTriggerCollector.ALTERNATIVE_JRE_VERSION); } } diff --git a/platform/execution-impl/src/com/intellij/execution/impl/statistics/RunConfigurationUsageTriggerCollector.java b/platform/execution-impl/src/com/intellij/execution/impl/statistics/RunConfigurationUsageTriggerCollector.java index 2b07741da353..ac311acc66a8 100644 --- a/platform/execution-impl/src/com/intellij/execution/impl/statistics/RunConfigurationUsageTriggerCollector.java +++ b/platform/execution-impl/src/com/intellij/execution/impl/statistics/RunConfigurationUsageTriggerCollector.java @@ -1,4 +1,4 @@ -// Copyright 2000-2020 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.execution.impl.statistics; import com.intellij.execution.Executor; @@ -32,7 +32,8 @@ import static com.intellij.execution.impl.statistics.RunConfigurationTypeUsagesC public final class RunConfigurationUsageTriggerCollector extends CounterUsagesCollector { public static final String GROUP_NAME = "run.configuration.exec"; - private static final EventLogGroup GROUP = new EventLogGroup(GROUP_NAME, 63); + private static final EventLogGroup GROUP = new EventLogGroup(GROUP_NAME, 65); + public static final IntEventField ALTERNATIVE_JRE_VERSION = EventFields.Int("alternative_jre_version"); private static final ObjectEventField ADDITIONAL_FIELD = EventFields.createAdditionalDataField(GROUP_NAME, "started"); private static final StringEventField EXECUTOR = EventFields.StringValidatedByCustomRule("executor", "run_config_executor"); /** diff --git a/platform/execution-impl/src/com/intellij/terminal/JBTerminalPanel.java b/platform/execution-impl/src/com/intellij/terminal/JBTerminalPanel.java index 38c3b2714c88..5f0bdc81496c 100644 --- a/platform/execution-impl/src/com/intellij/terminal/JBTerminalPanel.java +++ b/platform/execution-impl/src/com/intellij/terminal/JBTerminalPanel.java @@ -354,10 +354,13 @@ public class JBTerminalPanel extends TerminalPanel implements FocusListener, Dis @Override public boolean dispatch(@NotNull AWTEvent e) { - return e instanceof KeyEvent && dispatchKeyEvent((KeyEvent)e); + if (e instanceof KeyEvent) { + dispatchKeyEvent((KeyEvent)e); + } + return false; } - private boolean dispatchKeyEvent(@NotNull KeyEvent e) { + private void dispatchKeyEvent(@NotNull KeyEvent e) { if (!skipKeyEvent(e)) { if (!JBTerminalPanel.this.isFocusOwner()) { if (LOG.isDebugEnabled()) { @@ -365,15 +368,13 @@ public class JBTerminalPanel extends TerminalPanel implements FocusListener, Dis getDebugTerminalPanelName() + ", unregistering"); } unregister(); - return false; + return; } if (LOG.isDebugEnabled()) { LOG.debug("Consuming " + KeyStroke.getKeyStrokeForEvent(e) + ", registered:" + myRegistered); } JBTerminalPanel.this.dispatchEvent(e); - return true; } - return false; } void register() { diff --git a/plugins/dependency-updater/intellij.externalSystem.dependencyUpdater.iml b/platform/external-system-api/dependency-updater/intellij.platform.externalSystem.dependencyUpdater.iml index 64e23898e88a..ab9608a14b8d 100644 --- a/plugins/dependency-updater/intellij.externalSystem.dependencyUpdater.iml +++ b/platform/external-system-api/dependency-updater/intellij.platform.externalSystem.dependencyUpdater.iml @@ -9,10 +9,10 @@ <orderEntry type="inheritedJdk" /> <orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="module" module-name="intellij.platform.core" /> - <orderEntry type="module" module-name="intellij.platform.util" /> - <orderEntry type="module" module-name="intellij.platform.ide" /> + <orderEntry type="module" module-name="intellij.platform.core.ui" /> <orderEntry type="module" module-name="intellij.platform.lang" /> + <orderEntry type="module" module-name="intellij.platform.ide" /> <orderEntry type="module" module-name="intellij.platform.ide.impl" /> - <orderEntry type="module" module-name="intellij.platform.core.ui" /> + <orderEntry type="module" module-name="intellij.platform.util" /> </component> </module>
\ No newline at end of file diff --git a/plugins/dependency-updater/intellij.externalSystem.dependencyUpdater.tests.iml b/platform/external-system-api/dependency-updater/intellij.platform.externalSystem.dependencyUpdater.tests.iml index bbff114fca30..723fbecf4615 100644 --- a/plugins/dependency-updater/intellij.externalSystem.dependencyUpdater.tests.iml +++ b/platform/external-system-api/dependency-updater/intellij.platform.externalSystem.dependencyUpdater.tests.iml @@ -10,15 +10,15 @@ </content> <orderEntry type="inheritedJdk" /> <orderEntry type="sourceFolder" forTests="false" /> - <orderEntry type="module" module-name="intellij.externalSystem.dependencyUpdater" scope="TEST" /> + <orderEntry type="module" module-name="intellij.platform.externalSystem.dependencyUpdater" scope="TEST" /> + <orderEntry type="module" module-name="intellij.java" scope="TEST" /> + <orderEntry type="module" module-name="intellij.groovy.psi" scope="TEST" /> <orderEntry type="module" module-name="intellij.gradle" scope="TEST" /> <orderEntry type="module" module-name="intellij.gradle.java" scope="TEST" /> - <orderEntry type="module" module-name="intellij.platform.testFramework" scope="TEST" /> - <orderEntry type="module" module-name="intellij.java" scope="TEST" /> <orderEntry type="module" module-name="intellij.gradle.tests" scope="TEST" /> <orderEntry type="module" module-name="intellij.gradle.dependencyUpdater" scope="TEST" /> <orderEntry type="module" module-name="intellij.maven" scope="TEST" /> - <orderEntry type="module" module-name="intellij.groovy.psi" scope="TEST" /> <orderEntry type="module" module-name="intellij.maven.testFramework" scope="TEST" /> + <orderEntry type="module" module-name="intellij.platform.testFramework" scope="TEST" /> </component> </module>
\ No newline at end of file diff --git a/plugins/dependency-updater/resources/META-INF/plugin.xml b/platform/external-system-api/dependency-updater/resources/META-INF/ExternalSystemDependencyUpdater.xml index 1d897adb8cec..c6afc56791d5 100644 --- a/plugins/dependency-updater/resources/META-INF/plugin.xml +++ b/platform/external-system-api/dependency-updater/resources/META-INF/ExternalSystemDependencyUpdater.xml @@ -1,13 +1,4 @@ -<idea-plugin implementation-detail="true"> - <id>com.intellij.externalSystem.dependencyUpdater</id> - <name>Dependency Management Api for External Build Tools</name> - <vendor>JetBrains</vendor> - <description> - <![CDATA[ - Technical plugin, provides dependency management for external build tools - ]]> - </description> - +<idea-plugin> <extensions defaultExtensionNs="com.intellij"> <projectService serviceImplementation="com.intellij.externalSystem.DependencyModifierService" /> </extensions> diff --git a/plugins/dependency-updater/resources/messages/DependencyUpdaterBundle.properties b/platform/external-system-api/dependency-updater/resources/messages/DependencyUpdaterBundle.properties index bce9d06032b8..bce9d06032b8 100644 --- a/plugins/dependency-updater/resources/messages/DependencyUpdaterBundle.properties +++ b/platform/external-system-api/dependency-updater/resources/messages/DependencyUpdaterBundle.properties diff --git a/plugins/dependency-updater/src/com/intellij/buildsystem/model/BatchOperations.kt b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/BatchOperations.kt index a366002940ed..a366002940ed 100644 --- a/plugins/dependency-updater/src/com/intellij/buildsystem/model/BatchOperations.kt +++ b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/BatchOperations.kt diff --git a/plugins/dependency-updater/src/com/intellij/buildsystem/model/BuildDependency.kt b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/BuildDependency.kt index a08949887f16..a08949887f16 100644 --- a/plugins/dependency-updater/src/com/intellij/buildsystem/model/BuildDependency.kt +++ b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/BuildDependency.kt diff --git a/plugins/dependency-updater/src/com/intellij/buildsystem/model/BuildDependencyRepository.kt b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/BuildDependencyRepository.kt index b7e910e88f76..b7e910e88f76 100644 --- a/plugins/dependency-updater/src/com/intellij/buildsystem/model/BuildDependencyRepository.kt +++ b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/BuildDependencyRepository.kt diff --git a/plugins/dependency-updater/src/com/intellij/buildsystem/model/BuildManager.kt b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/BuildManager.kt index f0b7bb4dec75..f0b7bb4dec75 100644 --- a/plugins/dependency-updater/src/com/intellij/buildsystem/model/BuildManager.kt +++ b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/BuildManager.kt diff --git a/plugins/dependency-updater/src/com/intellij/buildsystem/model/BuildScriptEntryMetadata.kt b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/BuildScriptEntryMetadata.kt index e39f4b216610..e39f4b216610 100644 --- a/plugins/dependency-updater/src/com/intellij/buildsystem/model/BuildScriptEntryMetadata.kt +++ b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/BuildScriptEntryMetadata.kt diff --git a/plugins/dependency-updater/src/com/intellij/buildsystem/model/BuildSystem.kt b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/BuildSystem.kt index f655437b6a3c..f655437b6a3c 100644 --- a/plugins/dependency-updater/src/com/intellij/buildsystem/model/BuildSystem.kt +++ b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/BuildSystem.kt diff --git a/plugins/dependency-updater/src/com/intellij/buildsystem/model/BuildSystemExceptions.kt b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/BuildSystemExceptions.kt index 6200f27f8131..6200f27f8131 100644 --- a/plugins/dependency-updater/src/com/intellij/buildsystem/model/BuildSystemExceptions.kt +++ b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/BuildSystemExceptions.kt diff --git a/plugins/dependency-updater/src/com/intellij/buildsystem/model/DeclaredDependency.kt b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/DeclaredDependency.kt index 1e15020e5a8b..1e15020e5a8b 100644 --- a/plugins/dependency-updater/src/com/intellij/buildsystem/model/DeclaredDependency.kt +++ b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/DeclaredDependency.kt diff --git a/plugins/dependency-updater/src/com/intellij/buildsystem/model/DependencyInfo.kt b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/DependencyInfo.kt index 382da20ad265..382da20ad265 100644 --- a/plugins/dependency-updater/src/com/intellij/buildsystem/model/DependencyInfo.kt +++ b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/DependencyInfo.kt diff --git a/plugins/dependency-updater/src/com/intellij/buildsystem/model/OperationFailure.kt b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/OperationFailure.kt index 3181f0fc063d..3181f0fc063d 100644 --- a/plugins/dependency-updater/src/com/intellij/buildsystem/model/OperationFailure.kt +++ b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/OperationFailure.kt diff --git a/plugins/dependency-updater/src/com/intellij/buildsystem/model/OperationItem.kt b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/OperationItem.kt index e3cffa04459f..e3cffa04459f 100644 --- a/plugins/dependency-updater/src/com/intellij/buildsystem/model/OperationItem.kt +++ b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/OperationItem.kt diff --git a/plugins/dependency-updater/src/com/intellij/buildsystem/model/OperationType.kt b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/OperationType.kt index a8acc0e9a3c5..a8acc0e9a3c5 100644 --- a/plugins/dependency-updater/src/com/intellij/buildsystem/model/OperationType.kt +++ b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/OperationType.kt diff --git a/plugins/dependency-updater/src/com/intellij/buildsystem/model/RepositoryInfo.kt b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/RepositoryInfo.kt index 22d82497623a..22d82497623a 100644 --- a/plugins/dependency-updater/src/com/intellij/buildsystem/model/RepositoryInfo.kt +++ b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/RepositoryInfo.kt diff --git a/plugins/dependency-updater/src/com/intellij/buildsystem/model/unified/UnifiedCoordinates.kt b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/unified/UnifiedCoordinates.kt index 6bf54418e796..6bf54418e796 100644 --- a/plugins/dependency-updater/src/com/intellij/buildsystem/model/unified/UnifiedCoordinates.kt +++ b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/unified/UnifiedCoordinates.kt diff --git a/plugins/dependency-updater/src/com/intellij/buildsystem/model/unified/UnifiedDependency.kt b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/unified/UnifiedDependency.kt index 1dc5525a57f9..1dc5525a57f9 100644 --- a/plugins/dependency-updater/src/com/intellij/buildsystem/model/unified/UnifiedDependency.kt +++ b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/unified/UnifiedDependency.kt diff --git a/plugins/dependency-updater/src/com/intellij/buildsystem/model/unified/UnifiedDependencyConverter.kt b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/unified/UnifiedDependencyConverter.kt index 95a2752fe24a..95a2752fe24a 100644 --- a/plugins/dependency-updater/src/com/intellij/buildsystem/model/unified/UnifiedDependencyConverter.kt +++ b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/unified/UnifiedDependencyConverter.kt diff --git a/plugins/dependency-updater/src/com/intellij/buildsystem/model/unified/UnifiedDependencyRepository.kt b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/unified/UnifiedDependencyRepository.kt index 2d8039e57217..2d8039e57217 100644 --- a/plugins/dependency-updater/src/com/intellij/buildsystem/model/unified/UnifiedDependencyRepository.kt +++ b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/unified/UnifiedDependencyRepository.kt diff --git a/plugins/dependency-updater/src/com/intellij/buildsystem/model/unified/UnifiedDependencyRepositoryConverter.kt b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/unified/UnifiedDependencyRepositoryConverter.kt index 313a975a73d7..313a975a73d7 100644 --- a/plugins/dependency-updater/src/com/intellij/buildsystem/model/unified/UnifiedDependencyRepositoryConverter.kt +++ b/platform/external-system-api/dependency-updater/src/com/intellij/buildsystem/model/unified/UnifiedDependencyRepositoryConverter.kt diff --git a/plugins/dependency-updater/src/com/intellij/externalSystem/DependencyModifierService.kt b/platform/external-system-api/dependency-updater/src/com/intellij/externalSystem/DependencyModifierService.kt index 08f45aca5a5d..08f45aca5a5d 100644 --- a/plugins/dependency-updater/src/com/intellij/externalSystem/DependencyModifierService.kt +++ b/platform/external-system-api/dependency-updater/src/com/intellij/externalSystem/DependencyModifierService.kt diff --git a/plugins/dependency-updater/src/com/intellij/externalSystem/DependencyUpdaterBundle.java b/platform/external-system-api/dependency-updater/src/com/intellij/externalSystem/DependencyUpdaterBundle.java index 82e88a68e58e..82e88a68e58e 100644 --- a/plugins/dependency-updater/src/com/intellij/externalSystem/DependencyUpdaterBundle.java +++ b/platform/external-system-api/dependency-updater/src/com/intellij/externalSystem/DependencyUpdaterBundle.java diff --git a/plugins/dependency-updater/src/com/intellij/externalSystem/ExternalDependencyModificator.java b/platform/external-system-api/dependency-updater/src/com/intellij/externalSystem/ExternalDependencyModificator.java index 8b7dfaa4db69..8b7dfaa4db69 100644 --- a/plugins/dependency-updater/src/com/intellij/externalSystem/ExternalDependencyModificator.java +++ b/platform/external-system-api/dependency-updater/src/com/intellij/externalSystem/ExternalDependencyModificator.java diff --git a/plugins/dependency-updater/testData/gradle/expected/addCentralRepositoryAsMethodCall.gradle b/platform/external-system-api/dependency-updater/testData/gradle/expected/addCentralRepositoryAsMethodCall.gradle index 52fefce48018..52fefce48018 100644 --- a/plugins/dependency-updater/testData/gradle/expected/addCentralRepositoryAsMethodCall.gradle +++ b/platform/external-system-api/dependency-updater/testData/gradle/expected/addCentralRepositoryAsMethodCall.gradle diff --git a/plugins/dependency-updater/testData/gradle/expected/addDependency.gradle b/platform/external-system-api/dependency-updater/testData/gradle/expected/addDependency.gradle index d0799fb06910..d0799fb06910 100644 --- a/plugins/dependency-updater/testData/gradle/expected/addDependency.gradle +++ b/platform/external-system-api/dependency-updater/testData/gradle/expected/addDependency.gradle diff --git a/plugins/dependency-updater/testData/gradle/expected/addRepository.gradle b/platform/external-system-api/dependency-updater/testData/gradle/expected/addRepository.gradle index e7eff8f758f6..e7eff8f758f6 100644 --- a/plugins/dependency-updater/testData/gradle/expected/addRepository.gradle +++ b/platform/external-system-api/dependency-updater/testData/gradle/expected/addRepository.gradle diff --git a/plugins/dependency-updater/testData/gradle/expected/removeDependency.gradle b/platform/external-system-api/dependency-updater/testData/gradle/expected/removeDependency.gradle index e4bbfcec9de4..e4bbfcec9de4 100644 --- a/plugins/dependency-updater/testData/gradle/expected/removeDependency.gradle +++ b/platform/external-system-api/dependency-updater/testData/gradle/expected/removeDependency.gradle diff --git a/plugins/dependency-updater/testData/gradle/expected/updateDependencyLongNotation.gradle b/platform/external-system-api/dependency-updater/testData/gradle/expected/updateDependencyLongNotation.gradle index f6b57210fe12..f6b57210fe12 100644 --- a/plugins/dependency-updater/testData/gradle/expected/updateDependencyLongNotation.gradle +++ b/platform/external-system-api/dependency-updater/testData/gradle/expected/updateDependencyLongNotation.gradle diff --git a/plugins/dependency-updater/testData/gradle/expected/updateDependencyShortNotation.gradle b/platform/external-system-api/dependency-updater/testData/gradle/expected/updateDependencyShortNotation.gradle index ba5421a1c925..ba5421a1c925 100644 --- a/plugins/dependency-updater/testData/gradle/expected/updateDependencyShortNotation.gradle +++ b/platform/external-system-api/dependency-updater/testData/gradle/expected/updateDependencyShortNotation.gradle diff --git a/plugins/dependency-updater/testData/gradle/expected/updateDependencyWithExtVariableLongNotation.gradle b/platform/external-system-api/dependency-updater/testData/gradle/expected/updateDependencyWithExtVariableLongNotation.gradle index 586d51adfb2f..586d51adfb2f 100644 --- a/plugins/dependency-updater/testData/gradle/expected/updateDependencyWithExtVariableLongNotation.gradle +++ b/platform/external-system-api/dependency-updater/testData/gradle/expected/updateDependencyWithExtVariableLongNotation.gradle diff --git a/plugins/dependency-updater/testData/gradle/expected/updateDependencyWithVariableLongNotation.gradle b/platform/external-system-api/dependency-updater/testData/gradle/expected/updateDependencyWithVariableLongNotation.gradle index 795b0d6b9687..795b0d6b9687 100644 --- a/plugins/dependency-updater/testData/gradle/expected/updateDependencyWithVariableLongNotation.gradle +++ b/platform/external-system-api/dependency-updater/testData/gradle/expected/updateDependencyWithVariableLongNotation.gradle diff --git a/plugins/dependency-updater/testData/gradle/projects/addCentralRepositoryAsMethodCall.gradle b/platform/external-system-api/dependency-updater/testData/gradle/projects/addCentralRepositoryAsMethodCall.gradle index bbfeb03c2232..bbfeb03c2232 100644 --- a/plugins/dependency-updater/testData/gradle/projects/addCentralRepositoryAsMethodCall.gradle +++ b/platform/external-system-api/dependency-updater/testData/gradle/projects/addCentralRepositoryAsMethodCall.gradle diff --git a/plugins/dependency-updater/testData/gradle/projects/addDependency.gradle b/platform/external-system-api/dependency-updater/testData/gradle/projects/addDependency.gradle index bbfeb03c2232..bbfeb03c2232 100644 --- a/plugins/dependency-updater/testData/gradle/projects/addDependency.gradle +++ b/platform/external-system-api/dependency-updater/testData/gradle/projects/addDependency.gradle diff --git a/plugins/dependency-updater/testData/gradle/projects/addRepository.gradle b/platform/external-system-api/dependency-updater/testData/gradle/projects/addRepository.gradle index bbfeb03c2232..bbfeb03c2232 100644 --- a/plugins/dependency-updater/testData/gradle/projects/addRepository.gradle +++ b/platform/external-system-api/dependency-updater/testData/gradle/projects/addRepository.gradle diff --git a/plugins/dependency-updater/testData/gradle/projects/doNotAddRepositoryIfExists.gradle b/platform/external-system-api/dependency-updater/testData/gradle/projects/doNotAddRepositoryIfExists.gradle index e7eff8f758f6..e7eff8f758f6 100644 --- a/plugins/dependency-updater/testData/gradle/projects/doNotAddRepositoryIfExists.gradle +++ b/platform/external-system-api/dependency-updater/testData/gradle/projects/doNotAddRepositoryIfExists.gradle diff --git a/plugins/dependency-updater/testData/gradle/projects/getDependencies.gradle b/platform/external-system-api/dependency-updater/testData/gradle/projects/getDependencies.gradle index 1e9061121d67..1e9061121d67 100644 --- a/plugins/dependency-updater/testData/gradle/projects/getDependencies.gradle +++ b/platform/external-system-api/dependency-updater/testData/gradle/projects/getDependencies.gradle diff --git a/plugins/dependency-updater/testData/gradle/projects/removeDependency.gradle b/platform/external-system-api/dependency-updater/testData/gradle/projects/removeDependency.gradle index 47d2ce3ca271..47d2ce3ca271 100644 --- a/plugins/dependency-updater/testData/gradle/projects/removeDependency.gradle +++ b/platform/external-system-api/dependency-updater/testData/gradle/projects/removeDependency.gradle diff --git a/plugins/dependency-updater/testData/gradle/projects/updateDependencyLongNotation.gradle b/platform/external-system-api/dependency-updater/testData/gradle/projects/updateDependencyLongNotation.gradle index 63dfef4d22dc..63dfef4d22dc 100644 --- a/plugins/dependency-updater/testData/gradle/projects/updateDependencyLongNotation.gradle +++ b/platform/external-system-api/dependency-updater/testData/gradle/projects/updateDependencyLongNotation.gradle diff --git a/plugins/dependency-updater/testData/gradle/projects/updateDependencyShortNotation.gradle b/platform/external-system-api/dependency-updater/testData/gradle/projects/updateDependencyShortNotation.gradle index 47d2ce3ca271..47d2ce3ca271 100644 --- a/plugins/dependency-updater/testData/gradle/projects/updateDependencyShortNotation.gradle +++ b/platform/external-system-api/dependency-updater/testData/gradle/projects/updateDependencyShortNotation.gradle diff --git a/plugins/dependency-updater/testData/gradle/projects/updateDependencyWithExtVariableLongNotation.gradle b/platform/external-system-api/dependency-updater/testData/gradle/projects/updateDependencyWithExtVariableLongNotation.gradle index 64df867dc683..64df867dc683 100644 --- a/plugins/dependency-updater/testData/gradle/projects/updateDependencyWithExtVariableLongNotation.gradle +++ b/platform/external-system-api/dependency-updater/testData/gradle/projects/updateDependencyWithExtVariableLongNotation.gradle diff --git a/plugins/dependency-updater/testData/gradle/projects/updateDependencyWithVariableLongNotation.gradle b/platform/external-system-api/dependency-updater/testData/gradle/projects/updateDependencyWithVariableLongNotation.gradle index 21271eed520a..21271eed520a 100644 --- a/plugins/dependency-updater/testData/gradle/projects/updateDependencyWithVariableLongNotation.gradle +++ b/platform/external-system-api/dependency-updater/testData/gradle/projects/updateDependencyWithVariableLongNotation.gradle diff --git a/plugins/dependency-updater/testData/maven/expected/addDependency/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/expected/addDependency/pom.xml index ae0a951bc240..ae0a951bc240 100644 --- a/plugins/dependency-updater/testData/maven/expected/addDependency/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/expected/addDependency/pom.xml diff --git a/plugins/dependency-updater/testData/maven/expected/addDependencyToExistingList/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/expected/addDependencyToExistingList/pom.xml index 4318870ad251..4318870ad251 100644 --- a/plugins/dependency-updater/testData/maven/expected/addDependencyToExistingList/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/expected/addDependencyToExistingList/pom.xml diff --git a/plugins/dependency-updater/testData/maven/expected/addRepository/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/expected/addRepository/pom.xml index d6a857f353ae..d6a857f353ae 100644 --- a/plugins/dependency-updater/testData/maven/expected/addRepository/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/expected/addRepository/pom.xml diff --git a/plugins/dependency-updater/testData/maven/expected/removeDependency/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/expected/removeDependency/pom.xml index e4de81ffa6d3..e4de81ffa6d3 100644 --- a/plugins/dependency-updater/testData/maven/expected/removeDependency/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/expected/removeDependency/pom.xml diff --git a/plugins/dependency-updater/testData/maven/expected/removeRepository/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/expected/removeRepository/pom.xml index 7586728a57bc..7586728a57bc 100644 --- a/plugins/dependency-updater/testData/maven/expected/removeRepository/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/expected/removeRepository/pom.xml diff --git a/plugins/dependency-updater/testData/maven/expected/shouldAddDependencyToManagedTag/m1/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/expected/shouldAddDependencyToManagedTag/m1/pom.xml index 041fdb66ea3d..041fdb66ea3d 100644 --- a/plugins/dependency-updater/testData/maven/expected/shouldAddDependencyToManagedTag/m1/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/expected/shouldAddDependencyToManagedTag/m1/pom.xml diff --git a/plugins/dependency-updater/testData/maven/expected/shouldAddDependencyToManagedTag/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/expected/shouldAddDependencyToManagedTag/pom.xml index 9b7d3f3a4c51..9b7d3f3a4c51 100644 --- a/plugins/dependency-updater/testData/maven/expected/shouldAddDependencyToManagedTag/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/expected/shouldAddDependencyToManagedTag/pom.xml diff --git a/plugins/dependency-updater/testData/maven/expected/shouldRemoveDependencyIfManaged/m1/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/expected/shouldRemoveDependencyIfManaged/m1/pom.xml index 161b50e57f3c..161b50e57f3c 100644 --- a/plugins/dependency-updater/testData/maven/expected/shouldRemoveDependencyIfManaged/m1/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/expected/shouldRemoveDependencyIfManaged/m1/pom.xml diff --git a/plugins/dependency-updater/testData/maven/expected/shouldRemoveDependencyIfManaged/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/expected/shouldRemoveDependencyIfManaged/pom.xml index 9b7d3f3a4c51..9b7d3f3a4c51 100644 --- a/plugins/dependency-updater/testData/maven/expected/shouldRemoveDependencyIfManaged/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/expected/shouldRemoveDependencyIfManaged/pom.xml diff --git a/plugins/dependency-updater/testData/maven/expected/updateDependency/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/expected/updateDependency/pom.xml index 28a81056d882..28a81056d882 100644 --- a/plugins/dependency-updater/testData/maven/expected/updateDependency/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/expected/updateDependency/pom.xml diff --git a/plugins/dependency-updater/testData/maven/expected/updateDependencyNoScope/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/expected/updateDependencyNoScope/pom.xml index 6f77a6d26f9d..6f77a6d26f9d 100644 --- a/plugins/dependency-updater/testData/maven/expected/updateDependencyNoScope/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/expected/updateDependencyNoScope/pom.xml diff --git a/plugins/dependency-updater/testData/maven/expected/updateDependencyRemoveScope/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/expected/updateDependencyRemoveScope/pom.xml index 6f77a6d26f9d..6f77a6d26f9d 100644 --- a/plugins/dependency-updater/testData/maven/expected/updateDependencyRemoveScope/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/expected/updateDependencyRemoveScope/pom.xml diff --git a/plugins/dependency-updater/testData/maven/expected/updateDependencyWithProperty/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/expected/updateDependencyWithProperty/pom.xml index 8fbd93ee8c59..8fbd93ee8c59 100644 --- a/plugins/dependency-updater/testData/maven/expected/updateDependencyWithProperty/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/expected/updateDependencyWithProperty/pom.xml diff --git a/plugins/dependency-updater/testData/maven/expected/updateDependencyWithPropertyNoScope/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/expected/updateDependencyWithPropertyNoScope/pom.xml index d7559837b602..d7559837b602 100644 --- a/plugins/dependency-updater/testData/maven/expected/updateDependencyWithPropertyNoScope/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/expected/updateDependencyWithPropertyNoScope/pom.xml diff --git a/plugins/dependency-updater/testData/maven/expected/updateDependencyWithPropertyRemoveScope/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/expected/updateDependencyWithPropertyRemoveScope/pom.xml index 0f1fa52f18f8..0f1fa52f18f8 100644 --- a/plugins/dependency-updater/testData/maven/expected/updateDependencyWithPropertyRemoveScope/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/expected/updateDependencyWithPropertyRemoveScope/pom.xml diff --git a/plugins/dependency-updater/testData/maven/expected/updateManagedDependency/m1/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/expected/updateManagedDependency/m1/pom.xml index f66aa140856d..f66aa140856d 100644 --- a/plugins/dependency-updater/testData/maven/expected/updateManagedDependency/m1/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/expected/updateManagedDependency/m1/pom.xml diff --git a/plugins/dependency-updater/testData/maven/expected/updateManagedDependency/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/expected/updateManagedDependency/pom.xml index ca07df5d77fe..ca07df5d77fe 100644 --- a/plugins/dependency-updater/testData/maven/expected/updateManagedDependency/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/expected/updateManagedDependency/pom.xml diff --git a/plugins/dependency-updater/testData/maven/expected/updateManagedDependencyNoScope/m1/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/expected/updateManagedDependencyNoScope/m1/pom.xml index 9c0d03897add..9c0d03897add 100644 --- a/plugins/dependency-updater/testData/maven/expected/updateManagedDependencyNoScope/m1/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/expected/updateManagedDependencyNoScope/m1/pom.xml diff --git a/plugins/dependency-updater/testData/maven/expected/updateManagedDependencyNoScope/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/expected/updateManagedDependencyNoScope/pom.xml index ca07df5d77fe..ca07df5d77fe 100644 --- a/plugins/dependency-updater/testData/maven/expected/updateManagedDependencyNoScope/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/expected/updateManagedDependencyNoScope/pom.xml diff --git a/plugins/dependency-updater/testData/maven/expected/updateManagedDependencyRemoveScope/m1/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/expected/updateManagedDependencyRemoveScope/m1/pom.xml index 9c0d03897add..9c0d03897add 100644 --- a/plugins/dependency-updater/testData/maven/expected/updateManagedDependencyRemoveScope/m1/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/expected/updateManagedDependencyRemoveScope/m1/pom.xml diff --git a/plugins/dependency-updater/testData/maven/expected/updateManagedDependencyRemoveScope/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/expected/updateManagedDependencyRemoveScope/pom.xml index ca07df5d77fe..ca07df5d77fe 100644 --- a/plugins/dependency-updater/testData/maven/expected/updateManagedDependencyRemoveScope/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/expected/updateManagedDependencyRemoveScope/pom.xml diff --git a/plugins/dependency-updater/testData/maven/projects/addDependency/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/projects/addDependency/pom.xml index 475ccf0e1aa6..475ccf0e1aa6 100644 --- a/plugins/dependency-updater/testData/maven/projects/addDependency/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/projects/addDependency/pom.xml diff --git a/plugins/dependency-updater/testData/maven/projects/addDependencyToExistingList/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/projects/addDependencyToExistingList/pom.xml index e4de81ffa6d3..e4de81ffa6d3 100644 --- a/plugins/dependency-updater/testData/maven/projects/addDependencyToExistingList/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/projects/addDependencyToExistingList/pom.xml diff --git a/plugins/dependency-updater/testData/maven/projects/addRepository/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/projects/addRepository/pom.xml index 7586728a57bc..7586728a57bc 100644 --- a/plugins/dependency-updater/testData/maven/projects/addRepository/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/projects/addRepository/pom.xml diff --git a/plugins/dependency-updater/testData/maven/projects/getDependencies/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/projects/getDependencies/pom.xml index 1470791c1549..1470791c1549 100644 --- a/plugins/dependency-updater/testData/maven/projects/getDependencies/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/projects/getDependencies/pom.xml diff --git a/plugins/dependency-updater/testData/maven/projects/removeDependency/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/projects/removeDependency/pom.xml index c74b21125ade..c74b21125ade 100644 --- a/plugins/dependency-updater/testData/maven/projects/removeDependency/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/projects/removeDependency/pom.xml diff --git a/plugins/dependency-updater/testData/maven/projects/removeRepository/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/projects/removeRepository/pom.xml index 78579ebddf72..78579ebddf72 100644 --- a/plugins/dependency-updater/testData/maven/projects/removeRepository/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/projects/removeRepository/pom.xml diff --git a/plugins/dependency-updater/testData/maven/projects/shouldAddDependencyToManagedTag/m1/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/projects/shouldAddDependencyToManagedTag/m1/pom.xml index 161b50e57f3c..161b50e57f3c 100644 --- a/plugins/dependency-updater/testData/maven/projects/shouldAddDependencyToManagedTag/m1/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/projects/shouldAddDependencyToManagedTag/m1/pom.xml diff --git a/plugins/dependency-updater/testData/maven/projects/shouldAddDependencyToManagedTag/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/projects/shouldAddDependencyToManagedTag/pom.xml index 9b7d3f3a4c51..9b7d3f3a4c51 100644 --- a/plugins/dependency-updater/testData/maven/projects/shouldAddDependencyToManagedTag/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/projects/shouldAddDependencyToManagedTag/pom.xml diff --git a/plugins/dependency-updater/testData/maven/projects/shouldRemoveDependencyIfManaged/m1/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/projects/shouldRemoveDependencyIfManaged/m1/pom.xml index 17c08ec9a47a..17c08ec9a47a 100644 --- a/plugins/dependency-updater/testData/maven/projects/shouldRemoveDependencyIfManaged/m1/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/projects/shouldRemoveDependencyIfManaged/m1/pom.xml diff --git a/plugins/dependency-updater/testData/maven/projects/shouldRemoveDependencyIfManaged/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/projects/shouldRemoveDependencyIfManaged/pom.xml index 9b7d3f3a4c51..9b7d3f3a4c51 100644 --- a/plugins/dependency-updater/testData/maven/projects/shouldRemoveDependencyIfManaged/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/projects/shouldRemoveDependencyIfManaged/pom.xml diff --git a/plugins/dependency-updater/testData/maven/projects/updateDependency/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/projects/updateDependency/pom.xml index 4318870ad251..4318870ad251 100644 --- a/plugins/dependency-updater/testData/maven/projects/updateDependency/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/projects/updateDependency/pom.xml diff --git a/plugins/dependency-updater/testData/maven/projects/updateDependencyNoScope/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/projects/updateDependencyNoScope/pom.xml index 1d3190a1d667..1d3190a1d667 100644 --- a/plugins/dependency-updater/testData/maven/projects/updateDependencyNoScope/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/projects/updateDependencyNoScope/pom.xml diff --git a/plugins/dependency-updater/testData/maven/projects/updateDependencyRemoveScope/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/projects/updateDependencyRemoveScope/pom.xml index 4318870ad251..4318870ad251 100644 --- a/plugins/dependency-updater/testData/maven/projects/updateDependencyRemoveScope/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/projects/updateDependencyRemoveScope/pom.xml diff --git a/plugins/dependency-updater/testData/maven/projects/updateDependencyWithProperty/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/projects/updateDependencyWithProperty/pom.xml index 27193612672e..27193612672e 100644 --- a/plugins/dependency-updater/testData/maven/projects/updateDependencyWithProperty/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/projects/updateDependencyWithProperty/pom.xml diff --git a/plugins/dependency-updater/testData/maven/projects/updateDependencyWithPropertyNoScope/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/projects/updateDependencyWithPropertyNoScope/pom.xml index 6789b8b4bf6c..6789b8b4bf6c 100644 --- a/plugins/dependency-updater/testData/maven/projects/updateDependencyWithPropertyNoScope/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/projects/updateDependencyWithPropertyNoScope/pom.xml diff --git a/plugins/dependency-updater/testData/maven/projects/updateDependencyWithPropertyRemoveScope/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/projects/updateDependencyWithPropertyRemoveScope/pom.xml index 27193612672e..27193612672e 100644 --- a/plugins/dependency-updater/testData/maven/projects/updateDependencyWithPropertyRemoveScope/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/projects/updateDependencyWithPropertyRemoveScope/pom.xml diff --git a/plugins/dependency-updater/testData/maven/projects/updateManagedDependency/m1/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/projects/updateManagedDependency/m1/pom.xml index 8c9979577f1b..8c9979577f1b 100644 --- a/plugins/dependency-updater/testData/maven/projects/updateManagedDependency/m1/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/projects/updateManagedDependency/m1/pom.xml diff --git a/plugins/dependency-updater/testData/maven/projects/updateManagedDependency/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/projects/updateManagedDependency/pom.xml index ca07df5d77fe..ca07df5d77fe 100644 --- a/plugins/dependency-updater/testData/maven/projects/updateManagedDependency/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/projects/updateManagedDependency/pom.xml diff --git a/plugins/dependency-updater/testData/maven/projects/updateManagedDependencyNoScope/m1/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/projects/updateManagedDependencyNoScope/m1/pom.xml index 43d7daabd598..43d7daabd598 100644 --- a/plugins/dependency-updater/testData/maven/projects/updateManagedDependencyNoScope/m1/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/projects/updateManagedDependencyNoScope/m1/pom.xml diff --git a/plugins/dependency-updater/testData/maven/projects/updateManagedDependencyNoScope/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/projects/updateManagedDependencyNoScope/pom.xml index ca07df5d77fe..ca07df5d77fe 100644 --- a/plugins/dependency-updater/testData/maven/projects/updateManagedDependencyNoScope/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/projects/updateManagedDependencyNoScope/pom.xml diff --git a/plugins/dependency-updater/testData/maven/projects/updateManagedDependencyRemoveScope/m1/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/projects/updateManagedDependencyRemoveScope/m1/pom.xml index 8c9979577f1b..8c9979577f1b 100644 --- a/plugins/dependency-updater/testData/maven/projects/updateManagedDependencyRemoveScope/m1/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/projects/updateManagedDependencyRemoveScope/m1/pom.xml diff --git a/plugins/dependency-updater/testData/maven/projects/updateManagedDependencyRemoveScope/pom.xml b/platform/external-system-api/dependency-updater/testData/maven/projects/updateManagedDependencyRemoveScope/pom.xml index ca07df5d77fe..ca07df5d77fe 100644 --- a/plugins/dependency-updater/testData/maven/projects/updateManagedDependencyRemoveScope/pom.xml +++ b/platform/external-system-api/dependency-updater/testData/maven/projects/updateManagedDependencyRemoveScope/pom.xml diff --git a/plugins/dependency-updater/testSrc/com/intellij/externalSystem/GradleDependencyUpdaterTest.java b/platform/external-system-api/dependency-updater/testSrc/com/intellij/externalSystem/GradleDependencyUpdaterTest.java index 00a06543ce5f..00a06543ce5f 100644 --- a/plugins/dependency-updater/testSrc/com/intellij/externalSystem/GradleDependencyUpdaterTest.java +++ b/platform/external-system-api/dependency-updater/testSrc/com/intellij/externalSystem/GradleDependencyUpdaterTest.java diff --git a/plugins/dependency-updater/testSrc/com/intellij/externalSystem/GradleDependencyUpdaterTestBase.java b/platform/external-system-api/dependency-updater/testSrc/com/intellij/externalSystem/GradleDependencyUpdaterTestBase.java index 8484a7efda41..5b1ddab168ca 100644 --- a/plugins/dependency-updater/testSrc/com/intellij/externalSystem/GradleDependencyUpdaterTestBase.java +++ b/platform/external-system-api/dependency-updater/testSrc/com/intellij/externalSystem/GradleDependencyUpdaterTestBase.java @@ -39,7 +39,7 @@ public abstract class GradleDependencyUpdaterTestBase extends GradleImportingTes @Override public void setUp() throws Exception { super.setUp(); - myTestDataDir = PathManagerEx.findFileUnderCommunityHome("plugins/dependency-updater/testData/gradle"); + myTestDataDir = PathManagerEx.findFileUnderCommunityHome("platform/external-system-api/dependency-updater/testData/gradle"); assertTrue(myTestDataDir.isDirectory()); myModifierService = DependencyModifierService.getInstance(myProject); Assume.assumeTrue(myLanguageName.equals(GROOVY_LANGUAGE)); diff --git a/plugins/dependency-updater/testSrc/com/intellij/externalSystem/GradleRepositoriesUpdaterTest.java b/platform/external-system-api/dependency-updater/testSrc/com/intellij/externalSystem/GradleRepositoriesUpdaterTest.java index 3e23eb05dda8..3e23eb05dda8 100644 --- a/plugins/dependency-updater/testSrc/com/intellij/externalSystem/GradleRepositoriesUpdaterTest.java +++ b/platform/external-system-api/dependency-updater/testSrc/com/intellij/externalSystem/GradleRepositoriesUpdaterTest.java diff --git a/plugins/dependency-updater/testSrc/com/intellij/externalSystem/MavenDependencyUpdaterTest.java b/platform/external-system-api/dependency-updater/testSrc/com/intellij/externalSystem/MavenDependencyUpdaterTest.java index 66dc3b5d10bc..66dc3b5d10bc 100644 --- a/plugins/dependency-updater/testSrc/com/intellij/externalSystem/MavenDependencyUpdaterTest.java +++ b/platform/external-system-api/dependency-updater/testSrc/com/intellij/externalSystem/MavenDependencyUpdaterTest.java diff --git a/plugins/dependency-updater/testSrc/com/intellij/externalSystem/MavenDependencyUpdaterTestBase.java b/platform/external-system-api/dependency-updater/testSrc/com/intellij/externalSystem/MavenDependencyUpdaterTestBase.java index 891eb5f8607b..1df2785b6c58 100644 --- a/plugins/dependency-updater/testSrc/com/intellij/externalSystem/MavenDependencyUpdaterTestBase.java +++ b/platform/external-system-api/dependency-updater/testSrc/com/intellij/externalSystem/MavenDependencyUpdaterTestBase.java @@ -35,7 +35,7 @@ abstract public class MavenDependencyUpdaterTestBase extends MavenImportingTestC @Override public void setUp() throws Exception { super.setUp(); - myTestDataDir = PathManagerEx.findFileUnderCommunityHome("plugins/dependency-updater/testData/maven"); + myTestDataDir = PathManagerEx.findFileUnderCommunityHome("platform/external-system-api/dependency-updater/testData/maven"); assertTrue(myTestDataDir.isDirectory()); myProjectDataDir = new File(new File(myTestDataDir, "projects"), getTestName(true)); myExpectedDataDir = new File(new File(myTestDataDir, "expected"), getTestName(true)); diff --git a/platform/external-system-api/intellij.platform.externalSystem.iml b/platform/external-system-api/intellij.platform.externalSystem.iml index dd76337b92cf..442117e2a55c 100644 --- a/platform/external-system-api/intellij.platform.externalSystem.iml +++ b/platform/external-system-api/intellij.platform.externalSystem.iml @@ -20,5 +20,6 @@ <orderEntry type="module" module-name="intellij.platform.util.ui" /> <orderEntry type="module" module-name="intellij.platform.concurrency" /> <orderEntry type="module" module-name="intellij.platform.ide.util.io" /> + <orderEntry type="module" module-name="intellij.platform.externalSystem.dependencyUpdater" /> </component> </module>
\ No newline at end of file diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/wizard/MavenizedNewProjectWizardStep.kt b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/wizard/MavenizedNewProjectWizardStep.kt index 88aeb5984d59..f1d263b21681 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/wizard/MavenizedNewProjectWizardStep.kt +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/wizard/MavenizedNewProjectWizardStep.kt @@ -8,9 +8,7 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemBundle import com.intellij.openapi.externalSystem.util.ui.DataView import com.intellij.openapi.observable.util.trim import com.intellij.openapi.ui.ValidationInfo -import com.intellij.openapi.ui.validation.CHECK_ARTIFACT_ID_FORMAT -import com.intellij.openapi.ui.validation.CHECK_GROUP_ID_FORMAT -import com.intellij.openapi.ui.validation.CHECK_NON_EMPTY +import com.intellij.openapi.ui.validation.* import com.intellij.openapi.util.io.FileUtil import com.intellij.ui.SimpleListCellRenderer import com.intellij.ui.SortedComboBoxModel @@ -36,9 +34,9 @@ abstract class MavenizedNewProjectWizardStep<Data : Any, ParentStep>(val parentS final override val versionProperty = propertyGraph.lazyProperty(::suggestVersionByParent) final override var parent by parentProperty - final override var groupId by groupIdProperty.trim() - final override var artifactId by artifactIdProperty.trim() - final override var version by versionProperty.trim() + final override var groupId by groupIdProperty + final override var artifactId by artifactIdProperty + final override var version by versionProperty val parents by lazy { parentsData.map(::createView) } val parentsData by lazy { findAllParents() } @@ -77,16 +75,16 @@ abstract class MavenizedNewProjectWizardStep<Data : Any, ParentStep>(val parentS with(builder) { row(ExternalSystemBundle.message("external.system.mavenized.structure.wizard.group.id.label")) { textField() - .bindText(groupIdProperty) + .bindText(groupIdProperty.trim()) .columns(COLUMNS_MEDIUM) - .textValidation(CHECK_NON_EMPTY, CHECK_GROUP_ID_FORMAT) + .trimmedTextValidation(CHECK_NON_EMPTY, CHECK_GROUP_ID) .validation { validateGroupId() } }.bottomGap(BottomGap.SMALL) row(ExternalSystemBundle.message("external.system.mavenized.structure.wizard.artifact.id.label")) { textField() - .bindText(artifactIdProperty) + .bindText(artifactIdProperty.trim()) .columns(COLUMNS_MEDIUM) - .textValidation(CHECK_NON_EMPTY, CHECK_ARTIFACT_ID_FORMAT) + .trimmedTextValidation(CHECK_NON_EMPTY, CHECK_ARTIFACT_ID) .validation { validateArtifactId() } }.bottomGap(BottomGap.SMALL) } diff --git a/platform/feedback/src/com/intellij/feedback/FeedbackTypes.kt b/platform/feedback/src/com/intellij/feedback/FeedbackTypes.kt index 18bab6d12ed9..e9a12cd1cfcc 100644 --- a/platform/feedback/src/com/intellij/feedback/FeedbackTypes.kt +++ b/platform/feedback/src/com/intellij/feedback/FeedbackTypes.kt @@ -12,6 +12,7 @@ import com.intellij.notification.NotificationAction import com.intellij.openapi.application.ex.ApplicationInfoEx import com.intellij.openapi.project.Project import com.intellij.openapi.ui.DialogWrapper +import com.intellij.util.PlatformUtils enum class FeedbackTypes { PROJECT_CREATION_FEEDBACK { @@ -24,12 +25,17 @@ enum class FeedbackTypes { val projectCreationInfoState = ProjectCreationInfoService.getInstance().state return isIntellijIdeaEAP() && + checkIdeIsSuitable() && checkIdeVersionIsSuitable() && checkProjectCreationFeedbackNotSent(projectCreationInfoState) && checkProjectCreated(projectCreationInfoState) && checkNotificationNumberNotExceeded(projectCreationInfoState) } + private fun checkIdeIsSuitable(): Boolean { + return PlatformUtils.isIdeaUltimate() || PlatformUtils.isIdeaCommunity() + } + private fun checkProjectCreationFeedbackNotSent(state: ProjectCreationInfoState): Boolean { return !state.feedbackSent } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/ReaderModeListener.kt b/platform/lang-impl/src/com/intellij/codeInsight/actions/ReaderModeListener.kt index edd57943f84c..985039e70140 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/actions/ReaderModeListener.kt +++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/ReaderModeListener.kt @@ -1,4 +1,4 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.actions import com.intellij.application.options.colors.ReaderModeStatsCollector @@ -57,7 +57,9 @@ class ReaderModeSettingsListener : ReaderModeListener { } override fun modeChanged(project: Project) { - applyToAllEditors(project) + if (!project.isDefault) { + applyToAllEditors(project) + } } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficLightRenderer.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficLightRenderer.java index a76413ef6da2..a879e280f720 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficLightRenderer.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficLightRenderer.java @@ -269,25 +269,6 @@ public class TrafficLightRenderer implements ErrorStripeRenderer, Disposable { String title; String details; boolean isDumb = DumbService.isDumb(myProject); - if (status.errorAnalyzingFinished) { - if (isDumb) { - title = DaemonBundle.message("shallow.analysis.completed"); - details = DaemonBundle.message("shallow.analysis.completed.details"); - } - else if (getPsiFile() != null - && HighlightingSettingsPerFile.getInstance(myProject).getHighlightingSettingForRoot(getPsiFile()) == FileHighlightingSetting.ESSENTIAL) { - title = DaemonBundle.message("essential.analysis.completed"); - details = DaemonBundle.message("essential.analysis.completed.details"); - } - else { - title = ""; - details = ""; - } - } - else { - title = DaemonBundle.message("performing.code.analysis"); - details = ""; - } List<SeverityStatusItem> statusItems = new ArrayList<>(); int[] errorCounts = status.errorCounts; @@ -310,6 +291,26 @@ public class TrafficLightRenderer implements ErrorStripeRenderer, Disposable { } } + if (status.errorAnalyzingFinished) { + if (isDumb) { + title = DaemonBundle.message("shallow.analysis.completed"); + details = DaemonBundle.message("shallow.analysis.completed.details"); + } + else if (getPsiFile() != null + && HighlightingSettingsPerFile.getInstance(myProject).getHighlightingSettingForRoot(getPsiFile()) == FileHighlightingSetting.ESSENTIAL) { + title = DaemonBundle.message("essential.analysis.completed"); + details = DaemonBundle.message("essential.analysis.completed.details"); + } + else { + title = statusItems.isEmpty() ? DaemonBundle.message("no.errors.or.warnings.found") : ""; + details = ""; + } + } + else { + title = DaemonBundle.message("performing.code.analysis"); + details = ""; + } + if (!statusItems.isEmpty()) { AnalyzerStatus result = new AnalyzerStatus(statusItems.get(0).getIcon(), title, "", this::createUIController). withNavigation(). @@ -357,7 +358,7 @@ public class TrafficLightRenderer implements ErrorStripeRenderer, Disposable { boolean mergeEditor = editor.getUserData(DiffUserDataKeys.MERGE_EDITOR_FLAG) == Boolean.TRUE; return editor.getEditorKind() == EditorKind.DIFF && !mergeEditor ? new SimplifiedUIController() : new DefaultUIController(); } - + protected abstract class AbstractUIController implements UIController { private final boolean inLibrary; private final List<LanguageHighlightLevel> myLevelList; diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleTokenUtil.java b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleTokenUtil.java index a81de3e33126..0c798cd18c26 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleTokenUtil.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleTokenUtil.java @@ -133,7 +133,12 @@ class ConsoleTokenUtil { if (mergeWithThePreviousSameTypeToken && startOffset > 0) { RangeMarker prevMarker = findTokenMarker(editor, project, startOffset - 1); ConsoleViewContentType prevMarkerType = prevMarker == null ? null : getTokenType(prevMarker); - if (contentType.equals(prevMarkerType)) { + int prevMarkerEndOffset = prevMarkerType == null ? -1 : prevMarker.getEndOffset(); + if (contentType.equals(prevMarkerType) && + prevMarkerEndOffset >= 0 && + prevMarkerEndOffset < editor.getDocument().getTextLength() && + // must not merge tokens with end line because user input should be separated by new lines + editor.getDocument().getCharsSequence().charAt(prevMarkerEndOffset - 1) != '\n') { startOffset = prevMarker.getStartOffset(); prevMarker.dispose(); } diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java index 01346c34e974..bf538aead23b 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java @@ -1422,7 +1422,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo int newEndOffset = document.getTextLength() - oldDocLength + offset; // take care of trim document if (ConsoleTokenUtil.findTokenMarker(getEditor(), getProject(), newEndOffset) == null) { - ConsoleTokenUtil.createTokenRangeHighlighter(getEditor(), getProject(), ConsoleViewContentType.USER_INPUT, newStartOffset, newEndOffset, true); + ConsoleTokenUtil.createTokenRangeHighlighter(getEditor(), getProject(), ConsoleViewContentType.USER_INPUT, newStartOffset, newEndOffset, !text.equals("\n")); } moveScrollRemoveSelection(editor, newEndOffset); diff --git a/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkManager.java b/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkManager.java index 350bd77f5931..37d8cae98266 100644 --- a/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkManager.java +++ b/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkManager.java @@ -157,9 +157,6 @@ public final class BookmarkManager implements PersistentStateComponent<Element> public void addEditorBookmark(@NotNull Editor editor, int lineIndex) { ApplicationManager.getApplication().assertIsDispatchThread(); Document document = editor.getDocument(); - - if (lineIndex >= document.getLineCount()) return; // Android Studio: avoid IndexOutOfBoundsException - PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document); if (psiFile == null) return; diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/ProjectViewNodeDecorator.java b/platform/lang-impl/src/com/intellij/ide/projectView/ProjectViewNodeDecorator.java index ff7978aeadea..6f94396c0ab5 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/ProjectViewNodeDecorator.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/ProjectViewNodeDecorator.java @@ -1,4 +1,4 @@ -// Copyright 2000-2021 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-2022 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ide.projectView; @@ -7,7 +7,7 @@ import com.intellij.packageDependencies.ui.PackageDependenciesNode; import com.intellij.ui.ColoredTreeCellRenderer; /** - * Allows to modify the presentation of project view and package dependencies view nodes. + * Allows modifying the presentation of project view and package dependencies view nodes. * * @see TreeStructureProvider */ diff --git a/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/UnknownSdkFixAction.java b/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/UnknownSdkFixAction.java index 46ae3b7c1bd8..0761f4c494de 100644 --- a/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/UnknownSdkFixAction.java +++ b/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/UnknownSdkFixAction.java @@ -65,8 +65,8 @@ public interface UnknownSdkFixAction { void onSdkResolved(@NotNull Sdk sdk); /** - * One of the final events of the reoslution. It is caleld when a given SDK - * failed to be resolved + * One of the final events of the resolution. It is called when a given SDK + * failed to be resolved. * @see #onSdkResolved(Sdk) */ void onResolveFailed(); diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/projectRoot/SdkDownloadTracker.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/projectRoot/SdkDownloadTracker.java index a56cc3b5f34f..bf49435adf7c 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/projectRoot/SdkDownloadTracker.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/projectRoot/SdkDownloadTracker.java @@ -13,11 +13,14 @@ import com.intellij.openapi.progress.*; import com.intellij.openapi.progress.util.ProgressIndicatorBase; import com.intellij.openapi.progress.util.ProgressIndicatorListener; import com.intellij.openapi.progress.util.RelayUiToDelegateIndicator; +import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; +import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.projectRoots.ProjectJdkTable; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.SdkModificator; import com.intellij.openapi.projectRoots.SdkType; +import com.intellij.openapi.roots.impl.ProjectRootManagerImpl; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.NlsContexts; @@ -436,6 +439,14 @@ public class SdkDownloadTracker { } sdkType.setupSdkPaths(sdk); + + for (Project project: ProjectManager.getInstance().getOpenProjects()) { + final var rootManager = ProjectRootManagerImpl.getInstanceImpl(project); + final Sdk projectSdk = rootManager.getProjectSdk(); + if (projectSdk != null && projectSdk.getName().equals(sdk.getName())) { + rootManager.projectJdkChanged(); + } + } } catch (Exception e) { LOG.warn("Failed to set up SDK " + sdk + ". " + e.getMessage(), e); diff --git a/platform/lang-impl/src/com/intellij/util/indexing/diagnostic/ProjectIndexingHistoryFusReporterListener.kt b/platform/lang-impl/src/com/intellij/util/indexing/diagnostic/ProjectIndexingHistoryFusReporterListener.kt index 0777ec172ce7..b3643550c5ce 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/diagnostic/ProjectIndexingHistoryFusReporterListener.kt +++ b/platform/lang-impl/src/com/intellij/util/indexing/diagnostic/ProjectIndexingHistoryFusReporterListener.kt @@ -10,6 +10,7 @@ import com.intellij.internal.statistic.utils.StatisticsUtil import com.intellij.openapi.fileTypes.FileType import com.intellij.openapi.fileTypes.FileTypeManager import com.intellij.openapi.project.Project +import com.intellij.util.indexing.diagnostic.dto.toMillis import java.util.concurrent.TimeUnit import kotlin.math.roundToLong @@ -48,7 +49,8 @@ class ProjectIndexingHistoryFusReporterListener : ProjectIndexingHistoryListener projectIndexingHistory.project, projectIndexingHistory.indexingSessionId, projectIndexingHistory.times.wasFullIndexing, - TimeUnit.NANOSECONDS.toMillis(projectIndexingHistory.times.totalUpdatingTime), + projectIndexingHistory.times.totalUpdatingTime.toMillis(), + projectIndexingHistory.times.indexingDuration.toMillis(), scanningTime, numberOfFileProviders, numberOfScannedFiles, @@ -76,13 +78,14 @@ class ProjectIndexingHistoryFusReporterListener : ProjectIndexingHistoryListener } object ProjectIndexingHistoryFusReporter : CounterUsagesCollector() { - private val GROUP = EventLogGroup("indexing.statistics", 4) + private val GROUP = EventLogGroup("indexing.statistics", 5) override fun getGroup() = GROUP private val indexingSessionId = EventFields.Long("indexing_session_id") private val isFullIndexing = EventFields.Boolean("is_full") + private val totalTime = EventFields.Long("total_time") private val indexingTime = EventFields.Long("indexing_time") private val scanningTime = EventFields.Long("scanning_time") private val numberOfFileProviders = EventFields.Int("number_of_file_providers") @@ -109,6 +112,7 @@ object ProjectIndexingHistoryFusReporter : CounterUsagesCollector() { "finished", indexingSessionId, isFullIndexing, + totalTime, indexingTime, scanningTime, numberOfFileProviders, @@ -131,6 +135,7 @@ object ProjectIndexingHistoryFusReporter : CounterUsagesCollector() { project: Project, indexingSessionId: Long, wasFullIndexing: Boolean, + totalTime: Long, indexingTime: Long, scanningTime: Long, numberOfFileProviders: Int, @@ -146,6 +151,7 @@ object ProjectIndexingHistoryFusReporter : CounterUsagesCollector() { project, this.indexingSessionId.with(indexingSessionId), this.isFullIndexing.with(wasFullIndexing), + this.totalTime.with(totalTime), this.indexingTime.with(indexingTime), this.scanningTime.with(scanningTime), this.numberOfFileProviders.with(numberOfFileProviders), diff --git a/platform/lvcs-impl/resources/META-INF/lvcs.xml b/platform/lvcs-impl/resources/META-INF/lvcs.xml index 1f3ed07a0535..5c0d698ccbb2 100644 --- a/platform/lvcs-impl/resources/META-INF/lvcs.xml +++ b/platform/lvcs-impl/resources/META-INF/lvcs.xml @@ -31,6 +31,10 @@ <reference id="LocalHistory.PutLabel"/> <add-to-group group-id="Vcs.Operations.Popup" anchor="after" relative-to-action="ShowAnnotateOperationsPopupGroup"/> </group> + + <action internal="true" id="ValidateLocalHistory" class="com.intellij.history.integration.ValidateHistoryAction"> + <add-to-group group-id="Internal.VFS"/> + </action> </actions> <extensions defaultExtensionNs="com.intellij"> <undoProvider implementation="com.intellij.openapi.command.impl.FileUndoProvider"/> diff --git a/platform/platform-api/resources/messages/UIBundle.properties b/platform/platform-api/resources/messages/UIBundle.properties index 39d345db2fcf..d8dbdfe8aa8a 100644 --- a/platform/platform-api/resources/messages/UIBundle.properties +++ b/platform/platform-api/resources/messages/UIBundle.properties @@ -279,12 +279,11 @@ label.project.wizard.empty.project.generator.full.description=A basic project th kotlin.dsl.validation.missing.value=Field must be set kotlin.dsl.validation.no.whitespaces=Whitespaces are not allowed here kotlin.dsl.validation.no.reserved.words=Parts 'con', 'prn', 'aux', 'nul', 'com0', ..., 'com9' and 'lpt0', ..., 'lpt9' are not allowed here +kotlin.dsl.validation.name.leading.symbols=Must start with Latin character or '_' kotlin.dsl.validation.name.allowed.symbols=Only Latin characters, digits, '_', '-' and '.' are allowed here kotlin.dsl.validation.groupId.leading.trailing.dot=Must not start or end with '.' kotlin.dsl.validation.groupId.double.dot=Must not contain '..' sequences -kotlin.dsl.validation.groupId.part.allowed.symbols=Part ''{0}'' is incorrect, it must start with Latin character or ''_'' -kotlin.dsl.validation.artifactId.allowed.symbols=Only lowercase Latin characters, digits, '-', '_' and '.' are allowed here -kotlin.dsl.validation.artifactId.leading.symbols=Must start with lowercase Latin character +kotlin.dsl.validation.groupId.part.allowed.symbols=Part ''{0}'' is incorrect, it must start with Latin character or '_' list.caption.group.generators=Generators list.caption.group.templates=Templates diff --git a/platform/platform-api/src/com/intellij/openapi/ui/validation/OperationUtil.kt b/platform/platform-api/src/com/intellij/openapi/ui/validation/OperationUtil.kt index ec4deb0434fa..47ccaf934719 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/validation/OperationUtil.kt +++ b/platform/platform-api/src/com/intellij/openapi/ui/validation/OperationUtil.kt @@ -121,6 +121,12 @@ fun <T, R> DialogValidation.WithParameter<R>.transformParameter(transform: T.() } /** + * Transforms string validation into validation with trimmed string parameter. + */ +fun DialogValidation.WithParameter<() -> String>.trimParameter() = + transformParameter<() -> String, () -> String> { { invoke().trim() } } + +/** * Transforms string validation into validation for [JTextComponent]. */ fun DialogValidation.WithParameter<() -> String>.forTextComponent() = diff --git a/platform/platform-api/src/com/intellij/openapi/ui/validation/ValidationUtil.kt b/platform/platform-api/src/com/intellij/openapi/ui/validation/ValidationUtil.kt index 361e25290fbc..bcda4a1ad744 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/validation/ValidationUtil.kt +++ b/platform/platform-api/src/com/intellij/openapi/ui/validation/ValidationUtil.kt @@ -10,9 +10,9 @@ import java.nio.file.Path * Created validation with parameter that produces error if [getMessage] returns non-null value. */ fun <T> validationErrorFor(getMessage: (T) -> @NlsContexts.DialogMessage String?) = - DialogValidation.WithParameter<T> { + DialogValidation.WithParameter<() -> T> { DialogValidation { - val message = getMessage(it) + val message = getMessage(it()) if (message != null) { ValidationInfo(message) } @@ -29,24 +29,10 @@ fun <T1, T2> validationErrorFor(getMessage: (T1, T2) -> @NlsContexts.DialogMessa validationErrorWithTwoParametersFor(getMessage) { validationErrorFor(it) } /** - * Created validation with text parameter that produces error if [getMessage] returns non-null value. - * Note: Text parameter will be trimmed. - */ -fun validationTextErrorFor(getMessage: (String) -> @NlsContexts.DialogMessage String?) = - validationErrorFor<() -> String> { getter -> getMessage(getter().trim()) } - -/** - * Created validation with custom and text parameters that produces error if [getMessage] returns non-null value. - * Note: Text parameter will be trimmed. - */ -fun <T> validationTextErrorFor(getMessage: (T, String) -> @NlsContexts.DialogMessage String?) = - validationErrorWithTwoParametersFor(getMessage) { validationTextErrorFor(it) } - -/** * Created validation with [Path] parameter that produces error if [getMessage] returns non-null value. */ fun validationPathErrorFor(getMessage: (Path) -> @NlsContexts.DialogMessage String?) = - validationTextErrorFor { text -> getMessage(Path.of(text)) } + validationErrorFor<String> { getMessage(Path.of(it)) } /** * Created validation with custom and [Path] parameters that produces error if [getMessage] returns non-null value. @@ -58,7 +44,7 @@ fun <T> validationPathErrorFor(getMessage: (T, Path) -> @NlsContexts.DialogMessa * Created validation with [File] parameter that produces error if [getMessage] returns non-null value. */ fun validationFileErrorFor(getMessage: (File) -> @NlsContexts.DialogMessage String?) = - validationTextErrorFor { getMessage(File(it)) } + validationPathErrorFor { getMessage(it.toFile()) } /** * Created validation with custom and [File] parameters that produces error if [getMessage] returns non-null value. @@ -79,20 +65,6 @@ fun <T1, T2> validationErrorIf(message: @NlsContexts.DialogMessage String, isNot validationErrorFor(createMessageGetter(message, isNotValid)) /** - * Created validation with text parameter that produces error if [isNotValid] is true. - * Note: Text parameter will be trimmed. - */ -fun validationTextErrorIf(message: @NlsContexts.DialogMessage String, isNotValid: (String) -> Boolean) = - validationTextErrorFor(createMessageGetter(message, isNotValid)) - -/** - * Created validation with custom and text parameters that produces error if [isNotValid] is true. - * Note: Text parameter will be trimmed. - */ -fun <T> validationTextErrorIf(message: @NlsContexts.DialogMessage String, isNotValid: (T, String) -> Boolean) = - validationTextErrorFor(createMessageGetter(message, isNotValid)) - -/** * Create validation with two parameters from [validationBuilder] with one parameter. * Note: appended parameter is first. */ diff --git a/platform/platform-api/src/com/intellij/ui/ExperimentalUI.java b/platform/platform-api/src/com/intellij/ui/ExperimentalUI.java index 894c72e8cdbc..593476ea0e5f 100644 --- a/platform/platform-api/src/com/intellij/ui/ExperimentalUI.java +++ b/platform/platform-api/src/com/intellij/ui/ExperimentalUI.java @@ -2,8 +2,6 @@ package com.intellij.ui; import com.intellij.ide.ui.UISettings; -import com.intellij.openapi.application.Application; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.util.IconLoader; @@ -14,7 +12,6 @@ import com.intellij.openapi.util.registry.RegistryValueListener; import com.intellij.openapi.util.text.Strings; import com.intellij.util.EarlyAccessRegistryManager; import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -40,24 +37,19 @@ public final class ExperimentalUI { private static final String KEY = "ide.experimental.ui"; public static boolean isNewUI() { - return EarlyAccessRegistryManager.INSTANCE.getBoolean(KEY); + return false; } public static boolean isNewEditorTabs() { - return isEnabled("ide.experimental.ui.editor.tabs"); + return false; } public static boolean isNewVcsBranchPopup() { - return isEnabled("ide.experimental.ui.vcs.branch.popup"); + return false; } public static boolean isNewToolbar() { - return isEnabled("ide.experimental.ui.main.toolbar"); - } - - private static boolean isEnabled(@NonNls @NotNull String key) { - Application app = ApplicationManager.getApplication(); - return app != null && app.isEAP() && (isNewUI() || EarlyAccessRegistryManager.INSTANCE.getBoolean(key)); + return false; } @SuppressWarnings("unused") diff --git a/platform/platform-api/src/com/intellij/ui/jcef/JBCefApp.java b/platform/platform-api/src/com/intellij/ui/jcef/JBCefApp.java index 0b1697e51529..71c1a27a2a27 100644 --- a/platform/platform-api/src/com/intellij/ui/jcef/JBCefApp.java +++ b/platform/platform-api/src/com/intellij/ui/jcef/JBCefApp.java @@ -225,7 +225,7 @@ public final class JBCefApp { } /** - * Returns {@code JBCefApp} instance. If the app has not yet been initialized + * Returns {@code JBCefApp} instance. If the app has not yet been initialized, * then starts up CEF and initializes the app. * * @throws IllegalStateException when JCEF initialization is not possible in current env @@ -281,10 +281,10 @@ public final class JBCefApp { /** * Returns whether JCEF is supported. For that: * <ul> - * <li> It should be available in the running JBR. - * <li> It should have a compatible version. + * <li>It should be available in the running JBR.</li> + * <li>It should have a compatible version.</li> * </ul> - * In order to assuredly meet the above requirements the IDE should run with a bundled JBR. + * In order to assuredly meet the above requirements, the IDE should run with a bundled JBR. */ public static boolean isSupported() { boolean testModeEnabled = RegistryManager.getInstance().is("ide.browser.jcef.testMode.enabled"); @@ -367,8 +367,8 @@ public final class JBCefApp { } /** - * Returns true if the off-screen rendering mode is enabled. - * <p></p> + * Returns {@code true} if the off-screen rendering mode is enabled. + * <p> * This mode allows for browser creation in either windowed or off-screen rendering mode. * * @see JBCefOsrHandlerBrowser @@ -501,10 +501,10 @@ public final class JBCefApp { /** * Returns normal (unscaled) size of the provided scaled size if IDE-managed HiDPI mode is enabled. - * In JRE-managed HiDPI mode the method has no effect. - * <p></p> + * In JRE-managed HiDPI mode, the method has no effect. + * <p> * This method should be applied to size values (for instance, font size) previously scaled (explicitly or implicitly) - * via {@link com.intellij.ui.scale.JBUIScale#scale(int)}, before the values are used in html (in CSS, for instance). + * via {@link com.intellij.ui.scale.JBUIScale#scale(int)}, before the values are used in HTML (in CSS, for instance). * * @see com.intellij.ui.scale.ScaleType */ diff --git a/platform/platform-api/src/com/intellij/ui/jcef/JBCefBrowser.java b/platform/platform-api/src/com/intellij/ui/jcef/JBCefBrowser.java index c735b55e4ed5..13455c6670a8 100644 --- a/platform/platform-api/src/com/intellij/ui/jcef/JBCefBrowser.java +++ b/platform/platform-api/src/com/intellij/ui/jcef/JBCefBrowser.java @@ -1,4 +1,4 @@ -// Copyright 2000-2021 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.ui.jcef; import com.intellij.openapi.actionSystem.ActionManager; @@ -38,9 +38,9 @@ import static com.intellij.ui.jcef.JBCefEventUtils.isUpDownKeyEvent; * <p> * Use {@link #loadURL(String)} or {@link #loadHTML(String)} for loading. * + * @author tav * @see #createBuilder * @see JBCefOsrHandlerBrowser - * @author tav */ public class JBCefBrowser extends JBCefBrowserBase { /** @@ -49,14 +49,14 @@ public class JBCefBrowser extends JBCefBrowserBase { public static class Properties extends JBCefBrowserBase.Properties { /** * Defines whether the browser component should take focus on navigation (loading a new URL). - * <p></p> + * <p> * Accepts {@link Boolean} values. The default value is {@link Boolean#FALSE}. */ public static final @NotNull String FOCUS_ON_NAVIGATION = "JBCefBrowser.focusOnNavigation"; /** * Defines whether the browser component should take focus on show. - * <p></p> + * <p> * Accepts {@link Boolean} values. The default value is {@link Boolean#FALSE}. */ public static final @NotNull String FOCUS_ON_SHOW ="JBCefBrowser.focusOnShow"; diff --git a/platform/platform-api/src/com/intellij/ui/jcef/JBCefBrowserBase.java b/platform/platform-api/src/com/intellij/ui/jcef/JBCefBrowserBase.java index 40b5f3122f96..a3337b3535b4 100644 --- a/platform/platform-api/src/com/intellij/ui/jcef/JBCefBrowserBase.java +++ b/platform/platform-api/src/com/intellij/ui/jcef/JBCefBrowserBase.java @@ -1,4 +1,4 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.ui.jcef; import com.intellij.credentialStore.Credentials; @@ -58,14 +58,14 @@ public abstract class JBCefBrowserBase implements JBCefDisposable { /** * Prevents the browser from providing credentials via the * {@link CefRequestHandler#getAuthCredentials(CefBrowser, String, boolean, String, int, String, String, CefAuthCallback)} callback. - * <p></p> + * <p> * Accepts {@link Boolean} values. Use the property to handle the callback on your own. */ public static final @NotNull String NO_DEFAULT_AUTH_CREDENTIALS = "JBCefBrowserBase.noDefaultAuthCredentials"; /** * Disables or enables a context menu on click. - * <p></p> + * <p> * Accepts {@link Boolean} values. */ public static final @NotNull String NO_CONTEXT_MENU = "JBCefBrowserBase.noContextMenu"; @@ -271,7 +271,7 @@ public abstract class JBCefBrowserBase implements JBCefDisposable { /** * Creates the native browser. - * <p></p> + * <p> * Normally the native browser is created when the browser's component is added to a UI hierarchy. * <p> * Prefer this method to {@link CefBrowser#createImmediately}. @@ -296,7 +296,7 @@ public abstract class JBCefBrowserBase implements JBCefDisposable { } /** - * Loads html content. + * Loads HTML content. * * @param html content to load * @param url a dummy URL that may affect restriction policy applied to the content @@ -311,7 +311,7 @@ public abstract class JBCefBrowserBase implements JBCefDisposable { } /** - * Loads html content. + * Loads HTML content. */ public final void loadHTML(@NotNull String html) { loadHTML(html, BLANK_URI); @@ -324,8 +324,8 @@ public abstract class JBCefBrowserBase implements JBCefDisposable { /** * Returns the browser currently in focus. - * <p></p> - * It is possible that at a certain moment the browser can be focused natively but can not yet have java focus. + * <p> + * It is possible that at a certain moment, the browser can be focused natively but can not yet have Java focus. */ public static @Nullable JBCefBrowserBase getFocusedBrowser() { return focusedBrowser; @@ -382,7 +382,7 @@ public abstract class JBCefBrowserBase implements JBCefDisposable { } /** - * Adds handler that opens any links clicked by user in external browser + * Adds handler that opens any links clicked by user in external browser. */ public void setOpenLinksInExternalBrowser(boolean openLinksInExternalBrowser) { if (openLinksInExternalBrowser) { @@ -448,7 +448,7 @@ public abstract class JBCefBrowserBase implements JBCefDisposable { /** * Returns whether {@link #createImmediately} has been called or the browser has already been created. - * <p></p> + * <p> * WARNING: Returns wrong result when {@link CefBrowser#createImmediately()} is called directly. */ boolean isCefBrowserCreateStarted() { @@ -504,11 +504,11 @@ public abstract class JBCefBrowserBase implements JBCefDisposable { } /** - * Sets (overrides) background color in the html page. - * <p></p> + * Sets (overrides) background color in the HTML page. + * <p> * The color is set for the currently displayed page and all the subsequently loaded pages. * - * @see <a href="https://www.w3schools.com/cssref/css_colors_legal.asp">css color format</a> + * @see <a href="https://www.w3schools.com/cssref/css_colors_legal.asp">CSS color format</a> * @param cssColor the color in CSS format */ public void setPageBackgroundColor(@NotNull String cssColor) { @@ -595,8 +595,8 @@ public abstract class JBCefBrowserBase implements JBCefDisposable { }; /** - * Returns an error page html. - * <p></p> + * Returns an error page HTML. + * <p> * To prevent showing the error page (e.g. filter out {@link CefLoadHandler.ErrorCode#ERR_ABORTED}) just return {@code null}. * To fallback to default error page return {@link ErrorPage#DEFAULT#create(CefLoadHandler.ErrorCode, String, String)}. */ @@ -606,11 +606,11 @@ public abstract class JBCefBrowserBase implements JBCefDisposable { /** * Sets the error page to display in the browser on load error. - * <p></p> + * <p> * By default, no error page is displayed. To enable displaying default error page pass {@link ErrorPage#DEFAULT}. * Passing {@code null} prevents the browser from displaying an error page. * - * @param errorPage the error page producer, or null + * @param errorPage the error page producer, or {@code null} */ public void setErrorPage(@Nullable ErrorPage errorPage) { myErrorPage = errorPage; diff --git a/platform/platform-api/src/com/intellij/ui/jcef/JBCefBrowserBuilder.java b/platform/platform-api/src/com/intellij/ui/jcef/JBCefBrowserBuilder.java index 9111f8e4dade..7272c49f43f2 100644 --- a/platform/platform-api/src/com/intellij/ui/jcef/JBCefBrowserBuilder.java +++ b/platform/platform-api/src/com/intellij/ui/jcef/JBCefBrowserBuilder.java @@ -1,4 +1,4 @@ -// Copyright 2000-2021 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.ui.jcef; import org.cef.browser.CefBrowser; @@ -8,8 +8,8 @@ import org.jetbrains.annotations.Nullable; /** * A builder for creating {@link JBCefBrowser}. * - * @see JBCefBrowser#createBuilder * @author tav + * @see JBCefBrowser#createBuilder */ public class JBCefBrowserBuilder { @Nullable JBCefClient myClient; @@ -22,11 +22,11 @@ public class JBCefBrowserBuilder { /** * Sets whether the browser is rendered off-screen. - * <p></p> - * When set to true a buffered rendering is used onto a lightweight Swing component. - * To override - use {@link #setOSRHandlerFactory(JBCefOSRHandlerFactory)}. - * <p></p> - * When not set (or false) the windowed mode is used to render the browser. + * <p> + * When set to {@code true} a buffered rendering is used onto a lightweight Swing component. + * To override, use {@link #setOSRHandlerFactory(JBCefOSRHandlerFactory)}. + * <p> + * When not set (or {@code false}) the windowed mode is used to render the browser. * * @see #setOSRHandlerFactory(JBCefOSRHandlerFactory) */ @@ -37,8 +37,8 @@ public class JBCefBrowserBuilder { /** * Sets the client. - * <p></p> - * When not set the default client is created (which will be disposed automatically). + * <p> + * When not set, the default client is created (which will be disposed automatically). * <p> * The disposal of the provided client is the responsibility of the caller. */ @@ -49,8 +49,8 @@ public class JBCefBrowserBuilder { /** * Sets the initial URL to load. - * <p></p> - * When not set no initial URL is loaded. + * <p> + * When not set, no initial URL is loaded. * * @see JBCefBrowserBase#loadURL(String) */ @@ -61,8 +61,8 @@ public class JBCefBrowserBuilder { /** * Sets the browser to wrap. - * <p></p> - * When not set the default browser is created. + * <p> + * When not set, the default browser is created. * <p> * Use this option to set a browser like DevTools. * @@ -75,8 +75,8 @@ public class JBCefBrowserBuilder { /** * Sets whether the native browser should be created immediately. - * <p></p> - * When not set (or false) the native browser is created when the browser's component is added to a UI hierarchy. + * <p> + * When not set (or {@code false{}}) the native browser is created when the browser's component is added to a UI hierarchy. * * @see CefBrowser#createImmediately * @see JBCefBrowserBase#getComponent @@ -88,7 +88,7 @@ public class JBCefBrowserBuilder { /** * Sets the OSR handler factory. - * <p></p> + * <p> * When not set the {@link JBCefOSRHandlerFactory#DEFAULT} factory is used. * <p> * Used only with off-screen rendering, otherwise ignored. @@ -102,8 +102,8 @@ public class JBCefBrowserBuilder { /** * Sets whether the "Open DevTools" item should be present in the context menu. - * <p></p> - * When not set the item is not present. + * <p> + * When not set, the item is not present. */ public @NotNull JBCefBrowserBuilder setEnableOpenDevToolsMenuItem(boolean enableOpenDevToolsMenuItem) { myEnableOpenDevToolsMenuItem = enableOpenDevToolsMenuItem; diff --git a/platform/platform-api/src/com/intellij/ui/jcef/JBCefClient.java b/platform/platform-api/src/com/intellij/ui/jcef/JBCefClient.java index 17b519b28505..38ce0c63697b 100644 --- a/platform/platform-api/src/com/intellij/ui/jcef/JBCefClient.java +++ b/platform/platform-api/src/com/intellij/ui/jcef/JBCefClient.java @@ -1,4 +1,4 @@ -// Copyright 2000-2021 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.ui.jcef; import com.intellij.application.options.RegistryManager; @@ -50,7 +50,7 @@ public final class JBCefClient implements JBCefDisposable { * corresponds to a single {@link JBCefJSQuery} instance. The pool is not created by default unless it is explicitly * requested via this property. The property should be added to a client before the first browser associated * with the client is added to a UI hierarchy, otherwise it will have no effect. - * + * <p> * When a {@link JBCefJSQuery} is disposed, its JS query function ({@link JBCefJSQuery#getFuncName}) is returned * to the pool as a free slot and is then reused by a newly created {@link JBCefJSQuery}. */ diff --git a/platform/platform-api/src/com/intellij/ui/jcef/JBCefCookieManager.java b/platform/platform-api/src/com/intellij/ui/jcef/JBCefCookieManager.java index d80b7c562d73..3e7b355dc9a5 100644 --- a/platform/platform-api/src/com/intellij/ui/jcef/JBCefCookieManager.java +++ b/platform/platform-api/src/com/intellij/ui/jcef/JBCefCookieManager.java @@ -1,4 +1,4 @@ -// Copyright 2000-2021 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.ui.jcef; import com.intellij.openapi.diagnostic.Logger; @@ -70,7 +70,7 @@ public final class JBCefCookieManager { /** * Retrieves cookies asynchronously. * - * @param url filter by the given url scheme, host, domain and path. + * @param url filter by the given URL scheme, host, domain and path. * @param includeHttpOnly include only true HTTP-only cookies. * @return a future with the list of {@link JBCefCookie} which can be empty if cookies cannot be accessed or do not exist */ @@ -111,10 +111,10 @@ public final class JBCefCookieManager { } /** - * WARNING: the method can lead to a freeze when called from a browser callback. - * + * WARNING: The method can lead to a freeze when called from a browser callback. + * <p> * Gets cookies. Underlying native method is asynchronous. - * This method is executed with synchronization and can take up to `maxTimeToWait` ms. + * This method is executed with synchronization and can take up to {@code maxTimeToWait} ms. * * @param url filter by the given url scheme, host, domain and path. * @param includeHttpOnly include only true HTTP-only cookies. @@ -146,14 +146,14 @@ public final class JBCefCookieManager { * The method expects each attribute to be well-formed. It will check for disallowed characters * (e.g. the ';' character is disallowed within the cookie value attribute) and fail without setting * the cookie if such characters are found. - * - * It's recommended that a caller of the method either waits for the returned {@code future} to complete + * <p> + * It's recommended that a caller of the method either waits for the returned {@code Future} to complete * or cancels it when no confirmation of the success is required. Otherwise, it is possible that * the confirmation task performs infinitely in case something went wrong with the setting. * * @param url the cookie URL (should match the cookie's domain) * @param jbCefCookie the cookie - * @return a future with false if an invalid URL is specified or if cookies cannot be accessed. + * @return a future with {@code false} if an invalid URL is specified or if cookies cannot be accessed. */ public @NotNull Future<@NotNull Boolean> setCookie(@NotNull String url, @NotNull JBCefCookie jbCefCookie) { if (!checkArgs(url, jbCefCookie)) { @@ -191,14 +191,14 @@ public final class JBCefCookieManager { } /** - * WARNING: the method can lead to a freeze when called from a browser callback. - * + * WARNING: The method can lead to a freeze when called from a browser callback. + * <p> * Sets a cookie given a valid URL and explicit user-provided cookie attributes. * Underlying native method {@link CefCookieManager#setCookie(String, CefCookie)} is asynchronous. * This method is synchronous and will wait up to `maxTimeToWait` ms. * * @param maxTimeToWait time to wait setting cookie in ms, or default - * @return true if setting the cookie was successful. + * @return {@code true} if setting the cookie was successful. * * @deprecated use {@link #setCookie(String, JBCefCookie)} */ @@ -273,19 +273,19 @@ public final class JBCefCookieManager { } /** - * Deletes asynchronously all cookies that match the specified parameters. If both {@code url] and {@code cookieName} values + * Deletes asynchronously all cookies that match the specified parameters. If both {@code url} and {@code cookieName} values * are specified all host and domain cookies matching both will be deleted. If only {@code url} is * specified all host cookies (but not domain cookies) irrespective of path will be deleted. If * {@code url} is empty all cookies for all hosts and domains will be deleted. Cookies can alternately * be deleted using the visit*Cookies() methods. - * - * It's recommended that a caller of the method either waits for the returned {@code future} to complete + * <p> + * It's recommended that a caller of the method either waits for the returned {@code Future} to complete * or cancels it when no confirmation of the success is required. Otherwise, it is possible that * the confirmation task performs infinitely in case something went wrong with the deletion. * - * @param url The cookie URL to delete or null. - * @param cookieName The cookie name to delete or null. - * @return a future with false if a non-empty invalid URL is specified or if cookies cannot be accessed. + * @param url The cookie URL to delete or {@code null}. + * @param cookieName The cookie name to delete or {@code null}. + * @return a future with {@code false} if a non-empty invalid URL is specified or if cookies cannot be accessed. */ public @NotNull Future<@NotNull Boolean> deleteCookies(@Nullable String url, @Nullable String cookieName) { if (!myCefCookieManager.deleteCookies(url, cookieName)) { @@ -344,8 +344,8 @@ public final class JBCefCookieManager { /** * Deletes all host and domain cookies matching |url| and |cookieName| values. * - * @param doSync if false - underlying asynchronous native method {@link CefCookieManager#deleteCookies(String, String)} is used, - * true - synchronous {@link JBCefCookieManager#deleteCookies(String, String, IntFunction, Integer)}. + * @param doSync if {@code false}, underlying asynchronous native method {@link CefCookieManager#deleteCookies(String, String)} is used, + * {@code true} - synchronous {@link JBCefCookieManager#deleteCookies(String, String, IntFunction, Integer)}. * * @deprecated use {@link #deleteCookies(String, String)} */ diff --git a/platform/platform-api/src/com/intellij/ui/jcef/JBCefJSQuery.java b/platform/platform-api/src/com/intellij/ui/jcef/JBCefJSQuery.java index 4e4365104f6a..655757eda333 100644 --- a/platform/platform-api/src/com/intellij/ui/jcef/JBCefJSQuery.java +++ b/platform/platform-api/src/com/intellij/ui/jcef/JBCefJSQuery.java @@ -1,4 +1,4 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.ui.jcef; import com.intellij.openapi.diagnostic.Logger; @@ -46,8 +46,8 @@ public final class JBCefJSQuery implements JBCefDisposable { /** * Creates a unique JS query. * + * @param browser the associated CEF browser * @see JBCefClient.Properties#JS_QUERY_POOL_SIZE - * @param browser the associated cef browser */ @NotNull public static JBCefJSQuery create(@NotNull JBCefBrowserBase browser) { @@ -78,9 +78,9 @@ public final class JBCefJSQuery implements JBCefDisposable { } /** - * Returns the query callback to inject into JS code + * Returns the query callback to inject into JS code. * - * @param queryResult the result (JS variable name, or JS value in single quotes) that will be passed to the java handler {@link #addHandler(Function)} + * @param queryResult the result (JS variable name, or JS value in single quotes) that will be passed to the Java handler {@link #addHandler(Function)} */ @NotNull public String inject(@Nullable String queryResult) { @@ -88,11 +88,11 @@ public final class JBCefJSQuery implements JBCefDisposable { } /** - * Returns the query callback to inject into JS code + * Returns the query callback to inject into JS code. * - * @param queryResult the result (JS variable name, or JS value in single quotes) that will be passed to the java handler {@link #addHandler(Function)} - * @param onSuccessCallback JS callback in format: function(response) {} - * @param onFailureCallback JS callback in format: function(error_code, error_message) {} + * @param queryResult the result (JS variable name, or JS value in single quotes) that will be passed to the Java handler {@link #addHandler(Function)} + * @param onSuccessCallback JS callback in format: {@code function(response) {}} + * @param onFailureCallback JS callback in format: {@code function(error_code, error_message) {}} */ @NotNull public String inject(@Nullable String queryResult, @NotNull String onSuccessCallback, @NotNull String onFailureCallback) { diff --git a/platform/platform-api/src/com/intellij/ui/treeStructure/treetable/TreeTableModel.java b/platform/platform-api/src/com/intellij/ui/treeStructure/treetable/TreeTableModel.java index 9ed476c79d9e..2746c22ca330 100644 --- a/platform/platform-api/src/com/intellij/ui/treeStructure/treetable/TreeTableModel.java +++ b/platform/platform-api/src/com/intellij/ui/treeStructure/treetable/TreeTableModel.java @@ -1,4 +1,4 @@ -// Copyright 2000-2020 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.ui.treeStructure.treetable; import com.intellij.openapi.util.NlsContexts; @@ -8,7 +8,7 @@ import javax.swing.tree.TreeModel; /** * TreeTableModel is the model used by a JTreeTable. It extends TreeModel - * to add methods for getting inforamtion about the set of columns each + * to add methods for getting information about the set of columns each * node in the TreeTableModel may have. Each column, like a column in * a TableModel, has a name and a type associated with it. Each node in * the TreeTableModel can return a value for each of the columns and diff --git a/platform/platform-impl/src/com/intellij/ide/CommandLineProcessor.java b/platform/platform-impl/src/com/intellij/ide/CommandLineProcessor.java index c9a3fec987c9..d7c0580e986b 100644 --- a/platform/platform-impl/src/com/intellij/ide/CommandLineProcessor.java +++ b/platform/platform-impl/src/com/intellij/ide/CommandLineProcessor.java @@ -200,7 +200,7 @@ public final class CommandLineProcessor { private static CompletableFuture<CliResult> processInternalProtocol(String query) { try { QueryStringDecoder decoder = new QueryStringDecoder(query); - if ("open".equals(decoder.path())) { + if ("open".equals(StringUtil.trimEnd(decoder.path(), '/'))) { Map<String, List<String>> parameters = decoder.parameters(); String fileStr = ContainerUtil.getLastItem(parameters.get("file")); if (fileStr != null && !fileStr.isBlank()) { diff --git a/platform/platform-impl/src/com/intellij/ide/actions/NonEmptyActionGroup.java b/platform/platform-impl/src/com/intellij/ide/actions/NonEmptyActionGroup.java index 8d25588de790..5d33dca0ac88 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/NonEmptyActionGroup.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/NonEmptyActionGroup.java @@ -1,4 +1,4 @@ -// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.ide.actions; import com.intellij.openapi.actionSystem.AnActionEvent; @@ -8,7 +8,7 @@ import com.intellij.openapi.project.DumbAware; import org.jetbrains.annotations.NotNull; /** - * This group hides itself when there's no registered children. + * This group hides itself when there are no registered children. * * @see SmartPopupActionGroup * @see NonTrivialActionGroup diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/marketplace/MarketplacePluginDownloadService.kt b/platform/platform-impl/src/com/intellij/ide/plugins/marketplace/MarketplacePluginDownloadService.kt index 7844577038ad..26022491c25b 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/marketplace/MarketplacePluginDownloadService.kt +++ b/platform/platform-impl/src/com/intellij/ide/plugins/marketplace/MarketplacePluginDownloadService.kt @@ -126,7 +126,7 @@ open class MarketplacePluginDownloadService { LOG.info("Plugin's download percent is = %.2f".format(downloadPercent * 100)) if (downloadPercent > MAXIMUM_DOWNLOAD_PERCENT) { LOG.info(IdeBundle.message("too.large.download.size")) - return downloadPlugin(pluginFileUrl, indicator) + return downloadPlugin(pluginUrl, indicator) } val file = getPluginTempFile() @@ -136,7 +136,7 @@ open class MarketplacePluginDownloadService { val curFileHash = FileInputStream(file).use { input -> FileHash(input, newPluginHash.algorithm) } if (curFileHash != newPluginHash) { LOG.info(IdeBundle.message("hashes.doesnt.match")) - return downloadPlugin(pluginFileUrl, indicator) + return downloadPlugin(pluginUrl, indicator) } return if (pluginFileUrl.endsWith(".zip")) { @@ -148,7 +148,7 @@ open class MarketplacePluginDownloadService { } catch (e: Exception) { LOG.info(IdeBundle.message("error.download.plugin.via.blockmap"), e) - return downloadPlugin(pluginFileUrl, indicator) + return downloadPlugin(pluginUrl, indicator) } } diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java index 9d78c4bc7145..402b1cfd2981 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java @@ -640,7 +640,7 @@ public class DarculaComboBoxUI extends BasicComboBoxUI implements Border, ErrorB @Override public boolean isFocusTraversable(JComboBox<?> c) { - return !comboBox.isEditable() || !(editor instanceof ComboBoxCompositeEditor && ((ComboBoxCompositeEditor<?, ?>)editor).isEditable()); + return !comboBox.isEditable() || editor instanceof ComboBoxCompositeEditor && !((ComboBoxCompositeEditor<?, ?>)editor).isEditable(); } @Override diff --git a/platform/platform-impl/src/com/intellij/ide/wizard/NewProjectWizardBaseStep.kt b/platform/platform-impl/src/com/intellij/ide/wizard/NewProjectWizardBaseStep.kt index 75d1545fbb56..359ae4702447 100644 --- a/platform/platform-impl/src/com/intellij/ide/wizard/NewProjectWizardBaseStep.kt +++ b/platform/platform-impl/src/com/intellij/ide/wizard/NewProjectWizardBaseStep.kt @@ -87,10 +87,10 @@ class NewProjectWizardBaseStep(parent: NewProjectWizardStep) : AbstractNewProjec row(UIBundle.message("label.project.wizard.new.project.name")) { val locationProperty = pathProperty.joinCanonicalPath(nameProperty) textField() - .bindText(nameProperty) + .bindText(nameProperty.trim()) .columns(COLUMNS_MEDIUM) .validationRequestor(AFTER_GRAPH_PROPAGATION(propertyGraph)) - .textValidation(CHECK_NON_EMPTY, CHECK_MODULE_NAME(context.project)) + .trimmedTextValidation(CHECK_NON_EMPTY, CHECK_MODULE_NAME(context.project)) .applyIf(context.isCreatingNewProject) { validation(CHECK_PROJECT_PATH(context.project, locationProperty)) } .applyIf(!context.isCreatingNewProject) { validation(CHECK_MODULE_PATH(context.project, locationProperty)) } .focused() @@ -107,7 +107,7 @@ class NewProjectWizardBaseStep(parent: NewProjectWizardStep) : AbstractNewProjec textFieldWithBrowseButton(title, context.project, fileChooserDescriptor, fileChosen) .bindText(pathProperty.toUiPathProperty()) .horizontalAlign(HorizontalAlign.FILL) - .textValidation(CHECK_NON_EMPTY, CHECK_DIRECTORY) + .trimmedTextValidation(CHECK_NON_EMPTY, CHECK_DIRECTORY) .comment(commentProperty.get(), 100) .apply { commentProperty.afterChange { comment?.text = it } } } diff --git a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java index 03f677462c5c..8bcacaa90464 100644 --- a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java +++ b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java @@ -876,6 +876,7 @@ public final class StartupUtil { log.info("OS: " + SystemInfoRt.OS_NAME + " (" + SystemInfoRt.OS_VERSION + ", " + System.getProperty("os.arch") + ")"); log.info("JRE: " + System.getProperty("java.runtime.version", "-") + " (" + System.getProperty("java.vendor", "-") + ")"); log.info("JVM: " + System.getProperty("java.vm.version", "-") + " (" + System.getProperty("java.vm.name", "-") + ")"); + log.info("PID: " + ProcessHandle.current().pid()); if (SystemInfoRt.isXWindow) { String wmName = X11UiUtil.getWmName(); diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/persistence/ToolWindowCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/persistence/ToolWindowCollector.java index 0676b58e33e3..a7374f2592c8 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/persistence/ToolWindowCollector.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/actions/persistence/ToolWindowCollector.java @@ -67,22 +67,22 @@ public final class ToolWindowCollector { */ private static final Map<String, ToolWindowInfo> ourToolwindowWhitelist = new HashMap<>(); static { - ourToolwindowWhitelist.put(MESSAGES_WINDOW, new ToolWindowInfo("Messages")); - ourToolwindowWhitelist.put(DEBUG, new ToolWindowInfo("Debug")); - ourToolwindowWhitelist.put(RUN, new ToolWindowInfo("Run")); - ourToolwindowWhitelist.put(BuildContentManager.TOOL_WINDOW_ID, new ToolWindowInfo("Build")); - ourToolwindowWhitelist.put(FIND, new ToolWindowInfo("Find")); + ourToolwindowWhitelist.put(MESSAGES_WINDOW, new ToolWindowInfo(MESSAGES_WINDOW)); + ourToolwindowWhitelist.put(DEBUG, new ToolWindowInfo(DEBUG)); + ourToolwindowWhitelist.put(RUN, new ToolWindowInfo(RUN)); + ourToolwindowWhitelist.put(BuildContentManager.TOOL_WINDOW_ID, new ToolWindowInfo(BuildContentManager.TOOL_WINDOW_ID)); + ourToolwindowWhitelist.put(FIND, new ToolWindowInfo(FIND)); ourToolwindowWhitelist.put("CVS", new ToolWindowInfo("CVS")); - ourToolwindowWhitelist.put(HIERARCHY, new ToolWindowInfo("Hierarchy")); - ourToolwindowWhitelist.put(DEPENDENCIES, new ToolWindowInfo("Dependency_Viewer")); - ourToolwindowWhitelist.put(MODULES_DEPENDENCIES, new ToolWindowInfo("Module_Dependencies")); - ourToolwindowWhitelist.put(DUPLICATES, new ToolWindowInfo("Duplicates")); - ourToolwindowWhitelist.put(EXTRACT_METHOD, new ToolWindowInfo("Extract_Method")); - ourToolwindowWhitelist.put(DOCUMENTATION, new ToolWindowInfo("Documentation")); - ourToolwindowWhitelist.put(PREVIEW, new ToolWindowInfo("Preview")); - ourToolwindowWhitelist.put(RUN_DASHBOARD, new ToolWindowInfo("Run_Dashboard")); - ourToolwindowWhitelist.put(SERVICES, new ToolWindowInfo("Services")); - ourToolwindowWhitelist.put(ENDPOINTS, new ToolWindowInfo("Endpoints")); + ourToolwindowWhitelist.put(HIERARCHY, new ToolWindowInfo(HIERARCHY)); + ourToolwindowWhitelist.put(DEPENDENCIES, new ToolWindowInfo(DEPENDENCIES)); + ourToolwindowWhitelist.put(MODULES_DEPENDENCIES, new ToolWindowInfo(MODULES_DEPENDENCIES)); + ourToolwindowWhitelist.put(DUPLICATES, new ToolWindowInfo(DUPLICATES)); + ourToolwindowWhitelist.put(EXTRACT_METHOD, new ToolWindowInfo(EXTRACT_METHOD)); + ourToolwindowWhitelist.put(DOCUMENTATION, new ToolWindowInfo(DOCUMENTATION)); + ourToolwindowWhitelist.put(PREVIEW, new ToolWindowInfo(PREVIEW)); + ourToolwindowWhitelist.put(RUN_DASHBOARD, new ToolWindowInfo(RUN_DASHBOARD)); + ourToolwindowWhitelist.put(SERVICES, new ToolWindowInfo(SERVICES)); + ourToolwindowWhitelist.put(ENDPOINTS, new ToolWindowInfo(ENDPOINTS)); } private ToolWindowCollector() { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/HardReferencingRangeMarkerTree.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/HardReferencingRangeMarkerTree.java index 7a239895de6c..7829f44706a1 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/HardReferencingRangeMarkerTree.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/HardReferencingRangeMarkerTree.java @@ -2,17 +2,13 @@ package com.intellij.openapi.editor.impl; import com.intellij.openapi.editor.Document; -import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** * {@link RangeMarkerTree} with intervals which are not collected when no one holds a reference to them. */ -@ApiStatus.Internal -public class HardReferencingRangeMarkerTree<T extends RangeMarkerImpl> extends RangeMarkerTree<T> { - - @ApiStatus.Internal - public HardReferencingRangeMarkerTree(@NotNull Document document) { +class HardReferencingRangeMarkerTree<T extends RangeMarkerImpl> extends RangeMarkerTree<T> { + HardReferencingRangeMarkerTree(@NotNull Document document) { super(document); } diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/validation/validations.kt b/platform/platform-impl/src/com/intellij/openapi/ui/validation/validations.kt index 87fb06f0500c..a46fc973f39f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/ui/validation/validations.kt +++ b/platform/platform-impl/src/com/intellij/openapi/ui/validation/validations.kt @@ -10,18 +10,21 @@ import java.io.IOException import java.nio.file.InvalidPathException import java.nio.file.Path -val CHECK_NON_EMPTY = validationTextErrorIf(UIBundle.message("kotlin.dsl.validation.missing.value")) { it.isEmpty() } +val CHECK_NON_EMPTY = validationErrorIf<String>(UIBundle.message("kotlin.dsl.validation.missing.value")) { it.isEmpty() } -val CHECK_NO_WHITESPACES = validationTextErrorIf(UIBundle.message("kotlin.dsl.validation.no.whitespaces")) { ' ' in it } +val CHECK_NO_WHITESPACES = validationErrorIf<String>(UIBundle.message("kotlin.dsl.validation.no.whitespaces")) { ' ' in it } private val reservedWordsPattern = "(^|[ .])(con|prn|aux|nul|com\\d|lpt\\d)($|[ .])".toRegex(RegexOption.IGNORE_CASE) -val CHECK_NO_RESERVED_WORDS = validationTextErrorIf(UIBundle.message("kotlin.dsl.validation.no.reserved.words")) { +val CHECK_NO_RESERVED_WORDS = validationErrorIf<String>(UIBundle.message("kotlin.dsl.validation.no.reserved.words")) { reservedWordsPattern.find(it) != null } private val namePattern = "[a-zA-Z\\d\\s_.-]*".toRegex() -val CHECK_NAME_FORMAT = validationTextErrorIf(UIBundle.message("kotlin.dsl.validation.name.allowed.symbols")) { +private val firstSymbolNamePattern = "[a-zA-Z_].*".toRegex() +val CHECK_NAME_FORMAT = validationErrorIf<String>(UIBundle.message("kotlin.dsl.validation.name.allowed.symbols")) { !namePattern.matches(it) +} and validationErrorIf<String>(UIBundle.message("kotlin.dsl.validation.name.leading.symbols")) { + !firstSymbolNamePattern.matches(it) } val CHECK_NON_EMPTY_DIRECTORY = validationFileErrorFor { file -> @@ -32,7 +35,7 @@ val CHECK_NON_EMPTY_DIRECTORY = validationFileErrorFor { file -> else null }.asWarning().withOKEnabled() -val CHECK_DIRECTORY = validationTextErrorFor { text -> +val CHECK_DIRECTORY = validationErrorFor<String> { text -> runCatching { Path.of(text).toFile() } .mapCatching { file -> when { @@ -50,8 +53,7 @@ val CHECK_DIRECTORY = validationTextErrorFor { text -> } } -private val groupIdPartPattern = "[a-zA-Z_].*".toRegex() -val CHECK_GROUP_ID_FORMAT = CHECK_NO_WHITESPACES and CHECK_NAME_FORMAT and validationTextErrorFor { text -> +private val CHECK_GROUP_ID_FORMAT = validationErrorFor<String> { text -> if (text.startsWith('.') || text.endsWith('.')) { UIBundle.message("kotlin.dsl.validation.groupId.leading.trailing.dot") } @@ -59,29 +61,19 @@ val CHECK_GROUP_ID_FORMAT = CHECK_NO_WHITESPACES and CHECK_NAME_FORMAT and valid UIBundle.message("kotlin.dsl.validation.groupId.double.dot") } else { - text.split("\\.") - .find { !groupIdPartPattern.matches(it) } + text.split(".") + .find { !firstSymbolNamePattern.matches(it) } ?.let { UIBundle.message("kotlin.dsl.validation.groupId.part.allowed.symbols", it) } } } -private val artifactIdPattern = "[a-zA-Z\\d-_]*".toRegex() -private val firstSymbolArtifactIdPattern = "[a-zA-Z_].*".toRegex() -val CHECK_ARTIFACT_ID_FORMAT = validationTextErrorFor { text -> - if (!artifactIdPattern.matches(text)) { - UIBundle.message("kotlin.dsl.validation.artifactId.allowed.symbols") - } - else if (!firstSymbolArtifactIdPattern.matches(text)) { - UIBundle.message("kotlin.dsl.validation.artifactId.leading.symbols") - } - else { - null - } -} +val CHECK_GROUP_ID = CHECK_NO_WHITESPACES and CHECK_NAME_FORMAT and CHECK_GROUP_ID_FORMAT and CHECK_NO_RESERVED_WORDS + +val CHECK_ARTIFACT_ID = CHECK_NO_WHITESPACES and CHECK_NAME_FORMAT and CHECK_NO_RESERVED_WORDS private fun Project.getModules() = ModuleManager.getInstance(this).modules -val CHECK_FREE_MODULE_NAME = validationTextErrorFor<Project?> { project, name -> +val CHECK_FREE_MODULE_NAME = validationErrorFor<Project?, String> { project, name -> project?.getModules() ?.find { it.name == name } ?.let { UIBundle.message("label.project.wizard.new.module.name.exists.error", it.name) } @@ -103,7 +95,7 @@ val CHECK_FREE_PROJECT_PATH = validationPathErrorFor { path -> } } -val CHECK_MODULE_NAME = CHECK_NO_WHITESPACES and CHECK_NAME_FORMAT and CHECK_FREE_MODULE_NAME +val CHECK_MODULE_NAME = CHECK_NAME_FORMAT and CHECK_FREE_MODULE_NAME and CHECK_NO_RESERVED_WORDS val CHECK_MODULE_PATH = CHECK_DIRECTORY and CHECK_NON_EMPTY_DIRECTORY and CHECK_FREE_MODULE_PATH diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/TabContentLayout.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/TabContentLayout.java index 3378a40a215e..69be8f0b74ef 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/TabContentLayout.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/TabContentLayout.java @@ -264,7 +264,12 @@ class TabContentLayout extends ContentLayout implements MorePopupAware { selected = contentManager.getContents()[0]; } - result += selected == null ? 0 : contentToTabs.get(selected).getMinimumSize().width; + if (selected != null) { + ContentTabLabel label = contentToTabs.get(selected); + if (label != null) { + result += label.getMinimumSize().width; + } + } return result; } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java index 0968b96a60d9..a1b731334e5b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java @@ -25,9 +25,11 @@ import com.intellij.openapi.wm.ex.ProgressIndicatorEx; import com.intellij.openapi.wm.ex.StatusBarEx; import com.intellij.openapi.wm.impl.status.widget.StatusBarWidgetWrapper; import com.intellij.openapi.wm.impl.status.widget.StatusBarWidgetsActionGroup; +import com.intellij.ui.ClientProperty; import com.intellij.ui.ComponentUtil; import com.intellij.ui.ExperimentalUI; import com.intellij.ui.awt.RelativePoint; +import com.intellij.ui.awt.RelativeRectangle; import com.intellij.ui.components.panels.NonOpaquePanel; import com.intellij.ui.popup.NotificationPopup; import com.intellij.util.ArrayUtil; @@ -54,16 +56,16 @@ import java.util.function.Consumer; public class IdeStatusBarImpl extends JComponent implements Accessible, StatusBarEx, IdeEventQueue.EventDispatcher, DataProvider { private static final Logger LOG = Logger.getInstance(IdeStatusBarImpl.class); + public static final DataKey<String> HOVERED_WIDGET_ID = DataKey.create("HOVERED_WIDGET_ID"); public static final Key<WidgetEffect> WIDGET_EFFECT_KEY = Key.create("TextPanel.widgetEffect"); public static final String NAVBAR_WIDGET_KEY = "NavBar"; - private static final String WIDGET_ID = "STATUS_BAR_WIDGET_ID"; + private static final Key<String> WIDGET_ID = Key.create("STATUS_BAR_WIDGET_ID"); private static final int MIN_ICON_HEIGHT = JBUI.scale(18 + 1 + 1); private final InfoAndProgressPanel myInfoAndProgressPanel; - @NotNull - private final IdeFrame myFrame; + private final @NotNull IdeFrame myFrame; private enum Position {LEFT, RIGHT, CENTER} @@ -76,7 +78,7 @@ public class IdeStatusBarImpl extends JComponent implements Accessible, StatusBa private JPanel myLeftPanel; private JPanel myRightPanel; private JPanel myCenterPanel; - private Component myEffectComponent; + private JComponent myEffectComponent; private @NlsContexts.StatusBarText String myInfo; @@ -200,7 +202,7 @@ public class IdeStatusBarImpl extends JComponent implements Accessible, StatusBa return this; } if (HOVERED_WIDGET_ID.is(dataId)) { - return myEffectComponent instanceof JComponent ? ((JComponent)myEffectComponent).getClientProperty(WIDGET_ID) : null; + return ClientProperty.get(myEffectComponent, WIDGET_ID); } return null; } @@ -521,7 +523,7 @@ public class IdeStatusBarImpl extends JComponent implements Accessible, StatusBa } // wrap with a panel, so it will fill entire status bar height JComponent result = component instanceof JLabel ? new NonOpaquePanel(new BorderLayout(), component) : component; - result.putClientProperty(WIDGET_ID, widget.ID()); + ClientProperty.put(result, WIDGET_ID, widget.ID()); return result; } @@ -530,33 +532,33 @@ public class IdeStatusBarImpl extends JComponent implements Accessible, StatusBa LOG.error("Widget " + widget + " getPresentation() method must not return null"); } JComponent wrapper = StatusBarWidgetWrapper.wrap(Objects.requireNonNull(presentation)); - wrapper.putClientProperty(WIDGET_ID, widget.ID()); + ClientProperty.put(wrapper, WIDGET_ID, widget.ID()); wrapper.putClientProperty(UIUtil.CENTER_TOOLTIP_DEFAULT, Boolean.TRUE); return wrapper; } private void applyWidgetEffect(@Nullable JComponent component, @Nullable WidgetEffect widgetEffect) { - if (myEffectComponent != component || myEffectComponent == null || - ComponentUtil.getClientProperty((JComponent)myEffectComponent, WIDGET_EFFECT_KEY) != widgetEffect) { - - if (myEffectComponent != null) { - ComponentUtil.putClientProperty((JComponent)myEffectComponent, WIDGET_EFFECT_KEY, null); - } - - myEffectComponent = component; - // widgets shall not be opaque, as it may conflict with bg images - // the following code can be dropped in future - if (myEffectComponent != null) { - myEffectComponent.setBackground(null); - ComponentUtil.putClientProperty((JComponent)myEffectComponent, WIDGET_EFFECT_KEY, widgetEffect); - } - - if (component != null && component.isEnabled() && widgetEffect != null) { - component.setBackground(widgetEffect == WidgetEffect.HOVER ? - JBUI.CurrentTheme.StatusBar.Widget.HOVER_BACKGROUND: - JBUI.CurrentTheme.StatusBar.Widget.PRESSED_BACKGROUND); + if (myEffectComponent == component && + (myEffectComponent == null || + ClientProperty.get(myEffectComponent, WIDGET_EFFECT_KEY) == widgetEffect)) { + return; + } + if (myEffectComponent != null) { + ClientProperty.put(myEffectComponent, WIDGET_EFFECT_KEY, null); + repaint(new RelativeRectangle(myEffectComponent).getRectangleOn(this)); + } + myEffectComponent = component; + // widgets shall not be opaque, as it may conflict with bg images + // the following code can be dropped in future + if (myEffectComponent != null) { + myEffectComponent.setBackground(null); + ClientProperty.put(myEffectComponent, WIDGET_EFFECT_KEY, widgetEffect); + if (myEffectComponent.isEnabled() && widgetEffect != null) { + myEffectComponent.setBackground(widgetEffect == WidgetEffect.HOVER ? + JBUI.CurrentTheme.StatusBar.Widget.HOVER_BACKGROUND : + JBUI.CurrentTheme.StatusBar.Widget.PRESSED_BACKGROUND); } - repaint(); + repaint(new RelativeRectangle(myEffectComponent).getRectangleOn(this)); } } @@ -568,7 +570,7 @@ public class IdeStatusBarImpl extends JComponent implements Accessible, StatusBa Rectangle bounds = myEffectComponent.getBounds(); Point point = new RelativePoint(myEffectComponent.getParent(), bounds.getLocation()).getPoint(this); - var widgetEffect = ComponentUtil.getClientProperty((JComponent)myEffectComponent, WIDGET_EFFECT_KEY); + var widgetEffect = ClientProperty.get(myEffectComponent, WIDGET_EFFECT_KEY); var bg = widgetEffect == WidgetEffect.PRESSED ? JBUI.CurrentTheme.StatusBar.Widget.PRESSED_BACKGROUND : JBUI.CurrentTheme.StatusBar.Widget.HOVER_BACKGROUND; @@ -611,12 +613,12 @@ public class IdeStatusBarImpl extends JComponent implements Accessible, StatusBa } Point point = SwingUtilities.convertPoint(component, e.getPoint(), myRightPanel); - Component widget = myRightPanel.getComponentAt(point); + JComponent widget = ObjectUtils.tryCast(myRightPanel.getComponentAt(point), JComponent.class); if (e.getClickCount() == 0 || e.getID() == MouseEvent.MOUSE_RELEASED) { - applyWidgetEffect(widget != myRightPanel ? (JComponent)widget : null, WidgetEffect.HOVER); + applyWidgetEffect(widget != myRightPanel ? widget : null, WidgetEffect.HOVER); } else if (e.getClickCount() == 1 && e.getID() == MouseEvent.MOUSE_PRESSED) { - applyWidgetEffect(widget != myRightPanel ? (JComponent)widget : null, WidgetEffect.PRESSED); + applyWidgetEffect(widget != myRightPanel ? widget : null, WidgetEffect.PRESSED); } if (e.isConsumed() || widget == null) { @@ -664,6 +666,10 @@ public class IdeStatusBarImpl extends JComponent implements Accessible, StatusBa UIUtil.invokeLaterIfNeeded(() -> { WidgetBean bean = myWidgetMap.remove(id); if (bean != null) { + if (UIUtil.isAncestor(bean.component, myEffectComponent)) { + ClientProperty.put(myEffectComponent, WIDGET_EFFECT_KEY, null); + myEffectComponent = null; + } JPanel targetPanel = getTargetPanel(bean.position); targetPanel.remove(bean.component); targetPanel.revalidate(); diff --git a/platform/platform-impl/src/com/intellij/ui/dsl/builder/textField.kt b/platform/platform-impl/src/com/intellij/ui/dsl/builder/textField.kt index 3b91ebed1a7b..ab53eb7516a7 100644 --- a/platform/platform-impl/src/com/intellij/ui/dsl/builder/textField.kt +++ b/platform/platform-impl/src/com/intellij/ui/dsl/builder/textField.kt @@ -8,6 +8,7 @@ import com.intellij.openapi.observable.util.transform import com.intellij.openapi.observable.util.whenTextChanged import com.intellij.openapi.ui.validation.DialogValidation import com.intellij.openapi.ui.validation.forTextComponent +import com.intellij.openapi.ui.validation.trimParameter import com.intellij.ui.dsl.ValidationException import com.intellij.ui.dsl.builder.impl.CellImpl.Companion.installValidationRequestor import com.intellij.ui.dsl.catchValidationException @@ -131,5 +132,8 @@ private fun <T : JTextComponent> Cell<T>.bindIntText(prop: MutableProperty<Int>) { value -> catchValidationException { prop.set(component.getValidatedIntValue(value)) } }) } +fun <T : JTextComponent> Cell<T>.trimmedTextValidation(vararg validations: DialogValidation.WithParameter<() -> String>) = + textValidation(*validations.map2Array { it.trimParameter() }) + fun <T : JTextComponent> Cell<T>.textValidation(vararg validations: DialogValidation.WithParameter<() -> String>) = validation(*validations.map2Array { it.forTextComponent() }) diff --git a/platform/platform-impl/src/com/intellij/ui/dsl/builder/textFieldWithBrowseButton.kt b/platform/platform-impl/src/com/intellij/ui/dsl/builder/textFieldWithBrowseButton.kt index a61726d3e3bc..7467cae5ccd6 100644 --- a/platform/platform-impl/src/com/intellij/ui/dsl/builder/textFieldWithBrowseButton.kt +++ b/platform/platform-impl/src/com/intellij/ui/dsl/builder/textFieldWithBrowseButton.kt @@ -7,7 +7,9 @@ import com.intellij.openapi.observable.util.bind import com.intellij.openapi.ui.TextFieldWithBrowseButton import com.intellij.openapi.ui.validation.DialogValidation import com.intellij.openapi.ui.validation.forTextFieldWithBrowseButton +import com.intellij.openapi.ui.validation.trimParameter import com.intellij.ui.dsl.builder.impl.CellImpl.Companion.installValidationRequestor +import com.intellij.util.containers.map2Array import org.jetbrains.annotations.ApiStatus import kotlin.reflect.KMutableProperty0 @@ -42,5 +44,8 @@ private fun <T : TextFieldWithBrowseButton> Cell<T>.bindText(prop: MutableProper return bind(TextFieldWithBrowseButton::getText, TextFieldWithBrowseButton::setText, prop) } +fun <T : TextFieldWithBrowseButton> Cell<T>.trimmedTextValidation(vararg validations: DialogValidation.WithParameter<() -> String>) = + textValidation(*validations.map2Array { it.trimParameter() }) + fun <T : TextFieldWithBrowseButton> Cell<T>.textValidation(vararg validations: DialogValidation.WithParameter<() -> String>) = - validation(*validations.map { it.forTextFieldWithBrowseButton() }.toTypedArray())
\ No newline at end of file + validation(*validations.map2Array { it.forTextFieldWithBrowseButton() })
\ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java b/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java index 6d54ed1e8f38..2b6f6e2a7214 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java @@ -753,25 +753,21 @@ public class ListPopupImpl extends WizardPopup implements ListPopup, NextStepHan @Override protected void onSpeedSearchPatternChanged() { - Object before = myList.getSelectedValue(); myListModel.refilter(); if (myListModel.getSize() > 0) { if (!(shouldUseStatistics() && autoSelectUsingStatistics())) { - selectBestMatch(before); + selectBestMatch(); } } } - private void selectBestMatch(Object before) { + private void selectBestMatch() { int fullMatchIndex = myListModel.getClosestMatchIndex(); if (fullMatchIndex != -1 && isSelectableAt(fullMatchIndex)) { myList.setSelectedIndex(fullMatchIndex); } - - if (!myListModel.isVisible(before)) { + else { selectFirstSelectableItem(); - } else { - myList.setSelectedValue(before, true); } } diff --git a/platform/platform-impl/src/com/intellij/ui/tree/StructureTreeModel.java b/platform/platform-impl/src/com/intellij/ui/tree/StructureTreeModel.java index d69bc59c7d46..18226b557ff2 100644 --- a/platform/platform-impl/src/com/intellij/ui/tree/StructureTreeModel.java +++ b/platform/platform-impl/src/com/intellij/ui/tree/StructureTreeModel.java @@ -332,7 +332,7 @@ public class StructureTreeModel<Structure extends AbstractTreeStructure> @Override public final boolean isLeaf(Object object) { Node node = getNode(object, false); - return node == null || node.isLeaf(this::validateChildren); + return node == null || node.isModelLeaf(this::validateChildren); } @Override @@ -420,16 +420,19 @@ public class StructureTreeModel<Structure extends AbstractTreeStructure> } private static final class Node extends DefaultMutableTreeNode implements LeafState.Supplier { + /** + * {@link DefaultMutableTreeNode#children} is not used, all methods are overridden. + */ @SuppressWarnings("FieldNameHidesFieldInSuperclass") private final Reference<List<Node>> children = new Reference<>(); private LeafState leafState; // NB!: modify in #canReuse only private final int hashCode; - private Node(@NotNull AbstractTreeStructure structure, @NotNull Object element, NodeDescriptor<?> parent) { + Node(@NotNull AbstractTreeStructure structure, @NotNull Object element, NodeDescriptor<?> parent) { this(structure.createDescriptor(element, parent), structure.getLeafState(element), element.hashCode()); } - private Node(@NotNull NodeDescriptor descriptor, @NotNull LeafState leafState, int hashCode) { + Node(@NotNull NodeDescriptor descriptor, @NotNull LeafState leafState, int hashCode) { super(descriptor, leafState != LeafState.ALWAYS); this.hashCode = hashCode; setLeafState(leafState); @@ -545,12 +548,7 @@ public class StructureTreeModel<Structure extends AbstractTreeStructure> return getChildren().size(); } - @Override - public boolean isLeaf() { - return isLeaf(null); - } - - private boolean isLeaf(@Nullable Consumer<? super Node> validator) { + boolean isModelLeaf(@Nullable Consumer<? super Node> validator) { // root node should not be a leaf node when it is not visible in a tree // javax.swing.tree.VariableHeightLayoutCache.TreeStateNode.expand(boolean) if (null == getParent()) return false; diff --git a/platform/platform-resources-en/src/tips/ColorEditingInAndroid.html b/platform/platform-resources-en/src/tips/ColorEditingInAndroid.html deleted file mode 100644 index 665ea4efecc5..000000000000 --- a/platform/platform-resources-en/src/tips/ColorEditingInAndroid.html +++ /dev/null @@ -1,19 +0,0 @@ -<html> -<head> - <link rel="stylesheet" type="text/css" href="css/tips.css"> -</head> -<body> - - - <p><span class="product">&productName;</span> - simplifies your work - with colors in Android resource files. The <span class="code_emphasis">color</span> - properties have the icons of the corresponding color in the left gutter area of the editor. - </p> - <p>Click color icons to choose the desired color from the color picker.</p> - <p class="image"><img width="411" height="298" src="images/cssColor.png"></p> - - - -</body> -</html> diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index 2e50e2b2c7d9..de8c36d4da28 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -1386,7 +1386,7 @@ Android Studio: instead AndroidStudioStatisticsEventLoggerProvider is registered <listener class="com.intellij.util.EarlyAccessRegistryManager$MyListener" topic="com.intellij.openapi.util.registry.RegistryValueListener"/> <listener class="com.intellij.ide.ui.experimental.toolbar.ExperimentalToolbarSettings$ToolbarRegistryListener" topic="com.intellij.openapi.util.registry.RegistryValueListener"/> - <listener class="com.intellij.ui.ExperimentalUI$NewUiRegistryListener" topic="com.intellij.openapi.util.registry.RegistryValueListener"/> + <!-- <listener class="com.intellij.ui.ExperimentalUI$NewUiRegistryListener" topic="com.intellij.openapi.util.registry.RegistryValueListener"/> --> <listener class="com.intellij.ide.FrameStateManagerAppListener" topic="com.intellij.openapi.application.ApplicationActivationListener"/> </applicationListeners> diff --git a/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml b/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml index e32e43f54c91..3d35c1069cf3 100644 --- a/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml +++ b/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml @@ -39,6 +39,8 @@ <xi:include href="/META-INF/WorkspaceModelExtensions.xml"/> + <xi:include href="intellij.platform.feedback.xml"/> + <extensions defaultExtensionNs="com.intellij"> <applicationService serviceInterface="com.intellij.ide.RecentProjectsManager" serviceImplementation="com.intellij.ide.AttachedModuleAwareRecentProjectsManager" preload="notHeadless"/> @@ -156,4 +158,7 @@ <xi:include href="/META-INF/ExternalSystem.xml"> <xi:fallback/> </xi:include> + <xi:include href="/META-INF/ExternalSystemDependencyUpdater.xml"> + <xi:fallback/> + </xi:include> </idea-plugin>
\ No newline at end of file diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml index 25420b300271..fb97db4244e5 100644 --- a/platform/platform-resources/src/idea/LangActions.xml +++ b/platform/platform-resources/src/idea/LangActions.xml @@ -1671,5 +1671,33 @@ <action id="ForceIndexRescanning" internal="true" class="com.intellij.util.indexing.ForceIndexRescanningAction" icon="AllIcons.Actions.Refresh"/> <action id="ForceIndexRebuild" internal="true" class="com.intellij.util.indexing.ForceIndexRebuildAction" icon="AllIcons.Actions.Refresh"/> + + <group id="Internal.Dump" internal="true" popup="true"> + <action id="DumpExtensions" internal="true" class="com.intellij.internal.DumpExtensionsAction"/> + <action id="DumpInspectionDescriptions" internal="true" class="com.intellij.internal.DumpInspectionDescriptionsAction"/> + <action id="DumpIntentionsDescriptions" internal="true" class="com.intellij.internal.DumpIntentionsAction"/> + <action id="DumpConfigurationTypes" internal="true" class="com.intellij.internal.DumpConfigurationTypesAction"/> + <action id="DumpDirectoryIndex" internal="true" class="com.intellij.internal.DumpDirectoryInfoAction"/> + <action id="ScanSourceCommentsAction" internal="true" class="com.intellij.tools.ScanSourceCommentsAction"/> + <action id="DumpScreenConfiguration" class="com.intellij.internal.DumpScreenConfigurationAction"/> + <action id="DumpInvalidTipsOfTheDay" internal="true" class="com.intellij.ide.util.DumpInvalidTipsAction"/> + <add-to-group group-id="Internal" anchor="last"/> + </group> + <group id="Internal.VFS" popup="true" internal="true"> + <action id="VirtualFileInfo" internal="true" class="com.intellij.openapi.vfs.impl.local.VirtualFileInfoAction"/> + <separator/> + <action id="CheckVfsSanity" internal="true" class="com.intellij.openapi.vfs.newvfs.persistent.CheckSanityAction"/> + <action id="MarkVfsCorrupted" internal="true" class="com.intellij.openapi.vfs.newvfs.persistent.MarkVfsCorruptedAction"/> + <action id="LoadAllContent" internal="true" class="com.intellij.internal.LoadAllContentsAction"/> + <action id="LoadAllVFSContent" internal="true" class="com.intellij.internal.LoadAllVfsStoredContentsAction"/> + <action id="ComputeVFStatistics" internal="true" class="com.intellij.internal.ComputeVirtualFileNameStatAction"/> + <action id="DumpVfsInfoForExcludedFiles" internal="true" class="com.intellij.internal.DumpVfsInfoForExcludedFilesAction"/> + <action id="DumpWatchedRoots" internal="true" class="com.intellij.openapi.roots.impl.DumpWatchedRootsAction"/> + <separator/> + <action internal="true" id="PruneEmptyDirectories" class="com.intellij.ide.actions.PruneEmptyDirectoriesAction"/> + <action internal="true" id="FixLineSeparators" class="com.intellij.ide.actions.FixLineSeparatorsAction"/> + <separator/> + <add-to-group group-id="Internal" anchor="last"/> + </group> </actions> </idea-plugin> diff --git a/platform/platform-tests/testSrc/com/intellij/execution/impl/ConsoleViewImplTest.java b/platform/platform-tests/testSrc/com/intellij/execution/impl/ConsoleViewImplTest.java index 527d41f967f4..8a5cc842a617 100644 --- a/platform/platform-tests/testSrc/com/intellij/execution/impl/ConsoleViewImplTest.java +++ b/platform/platform-tests/testSrc/com/intellij/execution/impl/ConsoleViewImplTest.java @@ -936,4 +936,26 @@ public class ConsoleViewImplTest extends LightPlatformTestCase { new ExpectedHighlighter(0, 2, ConsoleViewContentType.USER_INPUT) ); } + + public void testEnterDuringTypingMustSeparateUserInputTokens() { + myConsole.type(myConsole.getEditor(), "2"); + myConsole.flushDeferredText(); + assertEquals("2", myConsole.getText()); + assertMarkersEqual(getAllRangeHighlighters(), + new ExpectedHighlighter(0, 1, ConsoleViewContentType.USER_INPUT) + ); + myConsole.type(myConsole.getEditor(), "\n"); + myConsole.flushDeferredText(); + myConsole.type(myConsole.getEditor(), "3"); + myConsole.flushDeferredText(); + myConsole.type(myConsole.getEditor(), "\n"); + myConsole.flushDeferredText(); + assertEquals("2\n3\n", myConsole.getText()); + assertMarkersEqual(getAllRangeHighlighters(), + new ExpectedHighlighter(0, 1, ConsoleViewContentType.USER_INPUT), + new ExpectedHighlighter(1, 2, ConsoleViewContentType.USER_INPUT), + new ExpectedHighlighter(2, 3, ConsoleViewContentType.USER_INPUT), + new ExpectedHighlighter(3, 4, ConsoleViewContentType.USER_INPUT) + ); + } } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java index fd6351aa8d36..22838ab055af 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java @@ -317,7 +317,7 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Pers projectJdkChanged(); } - protected void projectJdkChanged() { + public void projectJdkChanged() { incModificationCount(); mergeRootsChangesDuring(getActionToRunWhenProjectJdkChanges()); fireJdkChanged(); diff --git a/platform/remoteDev-util/src/com/intellij/remoteDev/downloader/CodeWithMeClientDownloader.kt b/platform/remoteDev-util/src/com/intellij/remoteDev/downloader/CodeWithMeClientDownloader.kt index b34438316483..edc1f8622f18 100644 --- a/platform/remoteDev-util/src/com/intellij/remoteDev/downloader/CodeWithMeClientDownloader.kt +++ b/platform/remoteDev-util/src/com/intellij/remoteDev/downloader/CodeWithMeClientDownloader.kt @@ -493,7 +493,7 @@ object CodeWithMeClientDownloader { if (SystemInfo.isMac) { val app = guestRoot.toFile().listFiles { file -> file.name.endsWith(".app") && file.isDirectory }!!.singleOrNull() if (app != null) { - return app.toPath() to listOf("open", "-n", "-a", app.toString(), "--args") + return app.toPath() to listOf("open", "-n", "-W", "-a", app.toString(), "--args") } } @@ -590,16 +590,22 @@ object CodeWithMeClientDownloader { super.processTerminated(event) LOG.info("Guest process terminated, exit code " + event.exitCode) - // if process exited abnormally but took longer than 10 seconds, it's likely to be an issue with connection instead of Mac-specific bug - if (event.exitCode != 0 && (System.currentTimeMillis() - lastProcessStartTime) < 10_000) { - if (attemptCount > 0) { - LOG.info("Previous attempt to start guest process failed, will try again in one second") - EdtScheduledExecutorService.getInstance().schedule({ doRunProcess() }, ModalityState.any(), 1, TimeUnit.SECONDS) + if (event.exitCode == 0) { + application.invokeLater { + processLifetimeDef.terminate() } - else { - LOG.warn("Running client process failed after specified number of attempts") - application.invokeLater { - processLifetimeDef.terminate() + } else { + // if process exited abnormally but took longer than 10 seconds, it's likely to be an issue with connection instead of Mac-specific bug + if ((System.currentTimeMillis() - lastProcessStartTime) < 10_000 ) { + if (attemptCount > 0) { + LOG.info("Previous attempt to start guest process failed, will try again in one second") + EdtScheduledExecutorService.getInstance().schedule({ doRunProcess() }, ModalityState.any(), 1, TimeUnit.SECONDS) + } + else { + LOG.warn("Running client process failed after specified number of attempts") + application.invokeLater { + processLifetimeDef.terminate() + } } } } diff --git a/platform/smRunner/intellij.platform.smRunner.iml b/platform/smRunner/intellij.platform.smRunner.iml index f583ace9c77a..2bd74c7b16ed 100644 --- a/platform/smRunner/intellij.platform.smRunner.iml +++ b/platform/smRunner/intellij.platform.smRunner.iml @@ -21,5 +21,6 @@ <orderEntry type="library" name="fastutil-min" level="project" /> <orderEntry type="module" module-name="intellij.platform.core.ui" /> <orderEntry type="module" module-name="intellij.platform.ide.util.io" /> + <orderEntry type="module" module-name="intellij.platform.diff" scope="TEST" /> </component> </module>
\ No newline at end of file diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java index 05ac6dfb4f84..76811a7114f4 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java @@ -1,4 +1,4 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.testFramework.fixtures; import com.intellij.codeInsight.completion.CompletionType; @@ -55,7 +55,6 @@ import java.util.function.Predicate; /** * @see <a href="https://jetbrains.org/intellij/sdk/docs/basics/testing_plugins/testing_plugins.html">Testing Plugins</a>. * @see IdeaTestFixtureFactory#createCodeInsightFixture(IdeaProjectTestFixture) - * @author Dmitry Avdeev */ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { String CARET_MARKER = EditorTestUtil.CARET_TAG; @@ -67,22 +66,16 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { String END_LINE_WARNING_MARKER = "EOLWarning"; /** - * Returns the in-memory editor instance. - * * @return the in-memory editor instance. */ Editor getEditor(); /** - * Returns the offset of the caret in the in-memory editor instance. - * * @return the offset of the caret in the in-memory editor instance. */ int getCaretOffset(); /** - * Returns the file currently loaded into the in-memory editor. - * * @return the file currently loaded into the in-memory editor. */ PsiFile getFile(); @@ -101,7 +94,9 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { /** * Copies a file from the testdata directory to the same relative path in the test project directory. * + * @param sourceFilePath path to the source file, relative to the testdata path. * @return the VirtualFile for the copied file in the test project directory. + * @see #copyFileToProject(String, String) */ @NotNull VirtualFile copyFileToProject(@TestDataFile @NotNull String sourceFilePath); @@ -132,6 +127,7 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { * * @param filePath path to the file, relative to the testdata path. * @return the PSI file for the copied and opened file. + * @see #configureByFiles(String...) */ PsiFile configureByFile(@TestDataFile @NotNull String filePath); @@ -148,7 +144,7 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { * Loads the specified text, treated as the contents of a file with the specified file type, into the in-memory * editor. * - * @param fileType the file type according to which which the text is interpreted. + * @param fileType the file type according to which the text is interpreted. * @param text the text to load into the in-memory editor. * @return the PSI file created from the specified text. */ @@ -198,8 +194,9 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { PsiFile addFileToProject(@NotNull String relativePath, @NotNull String fileText); /** - * Compares the contents of the in-memory editor with the specified file. The trailing whitespaces are not ignored - * by the comparison. + * Compares the contents of the in-memory editor with the specified file. + * <p> + * Trailing whitespaces are not ignored by the comparison, see {@link #checkResult(String, boolean)}. * * @param expectedFile path to file to check against, relative to the testdata path. */ @@ -209,7 +206,7 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { * Compares the contents of the in-memory editor with the specified file, optionally ignoring trailing whitespaces. * * @param expectedFile path to file to check against, relative to the testdata path. - * @param ignoreTrailingWhitespaces whether trailing whitespaces should be ignored by the comparison. + * @param ignoreTrailingWhitespaces whether the comparison should ignore trailing whitespaces. */ void checkResultByFile(@TestDataFile @NotNull String expectedFile, boolean ignoreTrailingWhitespaces); @@ -218,7 +215,7 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { * * @param filePath path to file to be checked, relative to the source root of the test project. * @param expectedFile path to file to check against, relative to the testdata path. - * @param ignoreTrailingWhitespaces whether trailing whitespaces should be ignored by the comparison. + * @param ignoreTrailingWhitespaces whether the comparison should ignore trailing whitespaces. */ void checkResultByFile(@NotNull String filePath, @TestDataFile @NotNull String expectedFile, @@ -249,6 +246,7 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { /** * Runs highlighting test for the given files. + * <p> * Checks for {@link #ERROR_MARKER} markers by default. * <p/> * Double quotes in "descr" attribute of markers must be escaped by either one or two backslashes @@ -257,7 +255,7 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { * @param checkWarnings enables {@link #WARNING_MARKER} support. * @param checkInfos enables {@link #INFO_MARKER} support. * @param checkWeakWarnings enables {@link #WEAK_WARNING_MARKER} support. - * @param filePaths the first file is tested only; the others are just copied along the first. + * @param filePaths the first file is tested only; the others are just copied along with the first. * @return highlighting duration in milliseconds. */ long testHighlighting(boolean checkWarnings, @@ -276,7 +274,7 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { @TestDataFile VirtualFile @NotNull ... files); /** - * Check highlighting of file already loaded by configure* methods + * Check highlighting of file already loaded by {@code configure*} methods. * * @return duration */ @@ -288,6 +286,7 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { /** * Runs highlighting test for the given files. + * <p> * The same as {@link #testHighlighting(boolean, boolean, boolean, String...)} with {@code checkInfos=false}. * * @param filePaths the first file is tested only; the others are just copied along with the first. @@ -318,28 +317,29 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { /** * Finds the reference in position marked by {@link #CARET_MARKER}. * - * @return null if no reference found. + * @return {@code null} if no reference found. * @see #getReferenceAtCaretPositionWithAssertion(String...) */ @Nullable PsiReference getReferenceAtCaretPosition(@TestDataFile String @NotNull ... filePaths); /** - * Finds the reference in position marked by {@link #CARET_MARKER}. + * Finds the required reference in position marked by {@link #CARET_MARKER}. + * <p> * Asserts that the reference exists. * - * @return founded reference + * @return found reference + * @throws AssertionError If no reference exists at the position. * @see #getReferenceAtCaretPosition(String...) */ @NotNull PsiReference getReferenceAtCaretPositionWithAssertion(@TestDataFile String @NotNull ... filePaths); /** - * Collects available intentions at caret position. + * Collects available intentions in position marked by {@link #CARET_MARKER}. * * @param filePaths the first file is tested only; the others are just copied along with the first. * @return available intentions. - * @see #CARET_MARKER */ @NotNull List<IntentionAction> getAvailableIntentions(@TestDataFile String @NotNull ... filePaths); @@ -351,20 +351,24 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { List<IntentionAction> getAvailableIntentions(); /** - * Returns all intentions or quick fixes which are available at the current caret position and whose text starts with the specified hint text. + * Returns all intentions or quick fixes which are available in position marked by {@link #CARET_MARKER}, + * and whose text starts with the specified hint text. * * @param hint the text that the intention text should begin with. - * @return the list of matching intentions + * @return the list of matching intentions. + * @see #findSingleIntention(String) */ @NotNull List<IntentionAction> filterAvailableIntentions(@NotNull String hint); /** - * Returns a single intention or quickfix which is available at the current caret position and whose text starts with the specified - * hint text. Throws an assertion if no such intentions are found or if multiple intentions match the hint text. + * Returns the single intention or quickfix which is available in position marked by {@link #CARET_MARKER} + * and whose text starts with the specified hint text. + * <p> + * Throws an assertion if no such intentions are found or if multiple intentions match the hint text. * * @param hint the text that the intention text should begin with. - * @return the matching intention + * @return the single matching intention/quickfix * @throws AssertionError if no intentions are found or if multiple intentions match the hint text. */ @NotNull @@ -375,14 +379,16 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { * in the in-memory editor and returns an intention action or quickfix with the name exactly matching the specified text. * * @param intentionName the text that the intention text should be equal to. - * @param filePaths the list of file path to copy to the test project directory. - * @return the first found intention or quickfix, or null if no matching intention actions are found. + * @param filePaths the list of file paths to copy to the test project directory. + * @return the first found intention or quickfix, or {@code null} if no matching intention actions are found. */ @Nullable IntentionAction getAvailableIntention(@NotNull String intentionName, @TestDataFile String @NotNull ... filePaths); /** - * Launches the given action. Use {@link #checkResultByFile(String)} to check the result. + * Launches the given intention action. + * <p> + * Use {@link #checkResultByFile(String)} to check the result. * * @param action the action to be launched. */ @@ -393,8 +399,9 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { void testCompletionTyping(String @NotNull [] filesBefore, @NotNull String toType, @NotNull @TestDataFile String fileAfter); /** - * Runs basic completion in caret position in fileBefore. - * Implies that there is only one completion variant and it was inserted automatically, and checks the result file text with fileAfter + * Runs basic completion in position marked by {@link #CARET_MARKER} in given file {@code fileBefore}. + * <p> + * Implies that there is only one completion variant, and it was inserted automatically and checks the result file text {@code fileAfter}. */ void testCompletion(@TestDataFile @NotNull String fileBefore, @NotNull @TestDataFile String fileAfter, @@ -406,21 +413,22 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { @TestDataFile String @NotNull ... additionalFiles); /** - * Runs basic completion in caret position in fileBefore. - * Checks that lookup is shown and it contains items with given lookup strings + * Runs basic completion in position marked by {@link #CARET_MARKER} in given file {@code fileBefore}. + * <p> + * Checks that lookup is shown, and it contains items with given lookup strings * * @param items most probably will contain > 1 items */ void testCompletionVariants(@NotNull @TestDataFile String fileBefore, String @NotNull ... items); /** - * Opens the specified file in the editor, Launches renaming refactoring on the PSI element at caret and checks the result. - * For new tests, please use{@link #testRenameUsingHandler(String, String, String, String...)} instead of this method. + * Opens the specified file in the editor, launches the rename refactoring on the PSI element in position marked by {@link #CARET_MARKER} and checks the result. + * <p> + * For new tests, please use {@link #testRenameUsingHandler} instead. * - * @param fileBefore original file path. Use {@link #CARET_MARKER} to mark the element to rename. + * @param fileBefore original file path. * @param fileAfter result file to be checked against. * @param newName new name for the element. - * @see #testRename(String, String) */ void testRename(@NotNull @TestDataFile String fileBefore, @NotNull @TestDataFile String fileAfter, @@ -428,10 +436,10 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { @TestDataFile String @NotNull ... additionalFiles); /** - * Opens the specified file in the editor, launches the rename refactoring using the rename handler (using the high-level + * Opens the specified file in the editor, launches the rename refactoring in position marked by {@link #CARET_MARKER} using the rename handler (using the high-level * rename API, as opposed to retrieving the PSI element at caret and invoking the PSI rename on it) and checks the result. * - * @param fileBefore original file path. Use {@link #CARET_MARKER} to mark the element to rename. + * @param fileBefore original file path. * @param fileAfter result file to be checked against. * @param newName new name for the element. * @see #testRename(String, String) @@ -443,13 +451,14 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { @TestDataFile String @NotNull ... additionalFiles); /** - * Launches the rename refactoring on the PSI element at caret and checks the result. For new tests, please use - * {@link #testRenameUsingHandler(String, String)} instead of this method. + * Launches the rename refactoring on the PSI element in position marked by {@link #CARET_MARKER} and checks the result. + * <p> + * For new tests, please use {@link #testRenameUsingHandler} instead. */ void testRename(@NotNull @TestDataFile String fileAfter, @NotNull String newName); /** - * launches the rename refactoring using the rename handler (using the high-level rename API, as opposed to + * Launches the rename refactoring in position marked by {@link #CARET_MARKER} using the rename handler (using the high-level rename API, as opposed to * retrieving the PSI element at caret and invoking the PSI rename on it) and checks the result. * * @see #renameElementAtCaretUsingHandler(String) @@ -457,8 +466,9 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { void testRenameUsingHandler(@NotNull @TestDataFile String fileAfter, @NotNull String newName); /** - * Invokes the Find Usages handler for the PSI element at caret and returns the usages returned by it. - * For new tests, please use {@link #testFindUsagesUsingAction} instead of this method. + * Invokes the Find Usages handler for the PSI element in position marked by {@link #CARET_MARKER} and returns the usages returned by it. + * <p> + * For new tests, please use {@link #testFindUsagesUsingAction} instead. */ @NotNull Collection<UsageInfo> testFindUsages(@TestDataFile String @NotNull ... fileNames); @@ -474,7 +484,7 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { Collection<UsageInfo> findUsages(@NotNull PsiElement to); /** - * @return a text representation of {@link com.intellij.usages.UsageView} created from the usages + * @return a text representation of {@link com.intellij.usages.UsageView} created from the usages. */ @NotNull String getUsageViewTreeTextRepresentation(@NotNull Collection<? extends UsageInfo> usages); @@ -484,7 +494,7 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { /** * @return a text representation of {@link com.intellij.usages.UsageView} created from usages of {@code to} * <p> - * The result of the method could be more verbose than {@code getUsageViewTreeTextRepresentation(findUsages(to))} + * The result of this method could be more verbose than {@code getUsageViewTreeTextRepresentation(findUsages(to))}. */ @NotNull String getUsageViewTreeTextRepresentation(@NotNull PsiElement to); @@ -496,15 +506,18 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { void moveFile(@NotNull @TestDataFile String filePath, @NotNull String to, @TestDataFile String @NotNull ... additionalFiles); /** - * Returns gutter renderer at the caret position. - * Use {@link #CARET_MARKER} to mark the element to check. + * Returns gutter renderer in position marked by {@link #CARET_MARKER}. * * @param filePath file path * @return gutter renderer at the caret position. + * @see #findGuttersAtCaret() */ @Nullable GutterMark findGutter(@NotNull @TestDataFile String filePath); + /** + * @see #findGutter(String) + */ @NotNull List<GutterMark> findGuttersAtCaret(); @@ -512,18 +525,18 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { PsiManager getPsiManager(); /** - * @return null if the only item was auto-completed + * @return {@code null} if the only item was auto-completed. * @see #completeBasicAllCarets(Character) */ LookupElement[] completeBasic(); /** - * @return null if the only item was auto-completed + * @return {@code null} if the only item was auto-completed. */ LookupElement[] complete(@NotNull CompletionType type); /** - * @return null if the only item was auto-completed + * @return {@code null} if the only item was auto-completed. */ LookupElement[] complete(@NotNull CompletionType type, int invocationCount); @@ -547,7 +560,7 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { void performEditorAction(@NotNull String actionId); /** - * If the action is visible and enabled, perform it + * If the action is visible and enabled, perform it. * * @return updated action's presentation */ @@ -558,7 +571,7 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { List<String> getCompletionVariants(@TestDataFile String @NotNull ... filesBefore); /** - * @return null if the only item was auto-completed + * @return {@code null} if the only item was auto-completed. */ LookupElement @Nullable [] getLookupElements(); @@ -575,16 +588,19 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { LookupEx getLookup(); /** - * Returns element at caret in the current file ({@link #configureByFile(String)}). - * This element must be {@link com.intellij.psi.PsiNamedElement} or has reference to something: - * it must valid target for rename/find usage action. See {@link com.intellij.codeInsight.TargetElementUtil}. + * Returns element in position marked by {@link #CARET_MARKER} in the current file ({@link #configureByFile(String)}). + * <p> + * This element must implement {@link com.intellij.psi.PsiNamedElement} or it has reference to something: + * it must be a valid target for rename/find usage action. + * See {@link com.intellij.codeInsight.TargetElementUtil}. + * <p> * For any other type of element use {@link PsiFile#findElementAt(int)} or {@link #findElementByText(String, Class)} */ @NotNull PsiElement getElementAtCaret(); /** - * Renames element at caret using direct call of {@link RenameProcessor#run()} + * Renames element in position marked by {@link #CARET_MARKER} using direct call of {@link RenameProcessor#run()} * * @param newName new name for the element. * @apiNote method {@link #renameElementAtCaretUsingHandler(String)} is more generic @@ -593,19 +609,20 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { void renameElementAtCaret(@NotNull String newName); /** - * Renames element at caret using injected {@link RenameHandler} + * Renames element in position marked by {@link #CARET_MARKER} using injected {@link RenameHandler}. + * <p> * Very close to {@link #renameElementAtCaret(String)} but uses handlers. * * @param newName new name for the element. - * @apiNote if the handler suggest some substitutions for the element with a dialog + * @apiNote if the handler suggests some substitutions for the element with a dialog * you can use {@link TestDialogManager#setTestDialog(TestDialog)} to provide YES/NO answer. - * Also makes sure that your rename handler properly processing name from {@link PsiElementRenameHandler#DEFAULT_NAME} + * Also makes sure that your rename handler properly processes name from {@link PsiElementRenameHandler#DEFAULT_NAME} * @see CodeInsightTestUtil#doInlineRename for more sophisticated in-place refactorings */ void renameElementAtCaretUsingHandler(@NotNull String newName); /** - * Renames element using direct call of {@link RenameProcessor#run()} + * Renames element using direct call of {@link RenameProcessor#run()}. * * @param element element to rename * @param newName new name for the element @@ -635,12 +652,13 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { void testRainbow(@NotNull String fileName, @NotNull String text, boolean isRainbowOn, boolean withColor); /** - * Misnamed, actually it checks only parameter hints + * Misnamed, actually it checks only parameter hints. + * @see #testInlays() */ void testInlays(); /** - * @param inlayPresenter function to render text of inlay. Inlays come to this function only if inlayFilter returned true + * @param inlayPresenter function to render text of inlay. Inlays come to this function only if {@code inlayFilter} returned {@code true}. * @param inlayFilter filter to check only required inlays */ void testInlays(Function<? super Inlay<?>, String> inlayPresenter, Predicate<? super Inlay<?>> inlayFilter); @@ -658,21 +676,23 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { /** * By default, if the caret in the text passed to {@link #configureByFile(String)} or {@link #configureByText} has an injected fragment - * at the caret, the test fixture puts the caret into the injected editor. This method allows to turn off this behavior. + * in position marked by {@link #CARET_MARKER}, the test fixture puts the caret into the injected editor. + * This method allows turning off this behavior. * - * @param caresAboutInjection true if the fixture should look for an injection at caret, false otherwise. + * @param caresAboutInjection {@code true} if the fixture should look for an injection at caret, {@code false} otherwise. */ void setCaresAboutInjection(boolean caresAboutInjection); /** * By default, {@link #doHighlighting} only collects highlight infos from {@link Document} markup model. - * Setting this flag will make this method also return highlight infos from {@link Editor#getMarkupModel}. + * Setting this flag will make it also return highlight infos from {@link Editor#getMarkupModel}. */ void setReadEditorMarkupModel(boolean readEditorMarkupModel); /** * Completes basically (see {@link #completeBasic()}) <strong>all</strong> - * carets (places marked with {@link #CARET_MARKER} in file. Example: + * carets (places marked with {@link #CARET_MARKER} in file). + * Example: * <pre> * PyC<caret> is IDE for Py<caret> * </pre> @@ -681,10 +701,10 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { * PyCharm is IDE for Python * </pre> * Actually, it works just like {@link #completeBasic()} but supports - * several {@link #CARET_MARKER} + * several {@link #CARET_MARKER}. * - * @param charToTypeAfterCompletion after completion this char will be typed if argument is not null. - * It could be used to complete suggestion with "\t" for example. + * @param charToTypeAfterCompletion after completion, this char will be typed if not {@code null}. + * It could be used to complete the suggestion with {@code '\t'} for example. * @return list of all completion elements just like in {@link #completeBasic()} * @see #completeBasic() */ @@ -693,27 +713,30 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { /** * Get elements found by the Goto Class action called with the given pattern - * @param pattern a pattern to search for elements - * @param searchEverywhere indicates whether "include non-project classes" checkbox is selected - * @param contextForSorting a PsiElement used for "proximity sorting" of the results. The sorting will be disabled if null given. - * @return a list of the results (likely PsiElements) found for the given pattern + * + * @param pattern pattern to search for elements. + * @param searchEverywhere indicates whether "include non-project classes" checkbox is selected. + * @param contextForSorting PsiElement used for "proximity sorting" of the results. Sorting will be disabled if set to {@code null}. + * @return a list of the results (likely PsiElements) found for the given pattern. */ @NotNull List<Object> getGotoClassResults(@NotNull String pattern, boolean searchEverywhere, @Nullable PsiElement contextForSorting); /** - * Get elements found by the Goto Symbol action called with the given pattern - * @param pattern a pattern to search for elements - * @param searchEverywhere indicates whether "include non-project classes" checkbox is selected - * @param contextForSorting a PsiElement used for "proximity sorting" of the results. The sorting will be disabled if null given. - * @return a list of the results (likely PsiElements) found for the given pattern + * Get elements found by the Goto Symbol action called with the given pattern. + * + * @param pattern pattern to search for elements. + * @param searchEverywhere indicates whether "include non-project classes" checkbox is selected. + * @param contextForSorting PsiElement used for "proximity sorting" of the results. Sorting will be disabled if set to {@code null}. + * @return a list of the results (likely PsiElements) found for the given pattern. */ @NotNull List<Object> getGotoSymbolResults(@NotNull String pattern, boolean searchEverywhere, @Nullable PsiElement contextForSorting); - + /** - * Get breadcrumbs to be generated for the current cursor position in the loaded file - * @return a list of the breadcrumbs in the order from the topmost element crumb to the deepest + * Get breadcrumbs to be generated for position marked by {@link #CARET_MARKER} in the loaded file. + * + * @return a list of the breadcrumbs in the order from the topmost element crumb to the deepest. */ @NotNull List<Crumb> getBreadcrumbsAtCaret(); diff --git a/platform/usageView-impl/src/com/intellij/usages/impl/SearchForUsagesRunnable.java b/platform/usageView-impl/src/com/intellij/usages/impl/SearchForUsagesRunnable.java index 148f7fd35d09..c153ecd59b41 100644 --- a/platform/usageView-impl/src/com/intellij/usages/impl/SearchForUsagesRunnable.java +++ b/platform/usageView-impl/src/com/intellij/usages/impl/SearchForUsagesRunnable.java @@ -394,7 +394,7 @@ final class SearchForUsagesRunnable implements Runnable { if (usageCount == 1 && !myProcessPresentation.isShowPanelIfOnlyOneUsage()) { myFirstUsage.compareAndSet(null, usage); } - myFirstItemFoundTS.compareAndSet(0, System.currentTimeMillis()); // Successes only once - at first assignment + myFirstItemFoundTS.compareAndSet(0, System.nanoTime()); // Successes only once - at first assignment UsageViewEx usageView = getUsageView(originalIndicator, startSearchStamp); diff --git a/platform/usageView-impl/src/com/intellij/usages/impl/UsageViewManagerImpl.java b/platform/usageView-impl/src/com/intellij/usages/impl/UsageViewManagerImpl.java index 04254d0fbf8b..0afac01f2cce 100644 --- a/platform/usageView-impl/src/com/intellij/usages/impl/UsageViewManagerImpl.java +++ b/platform/usageView-impl/src/com/intellij/usages/impl/UsageViewManagerImpl.java @@ -1,4 +1,4 @@ -// Copyright 2000-2020 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.usages.impl; import com.intellij.find.SearchInBackgroundOption; @@ -170,19 +170,19 @@ public class UsageViewManagerImpl extends UsageViewManager { UsageViewEx usageView = usageViewRef.get(); int count = usageView == null ? 0 : usageView.getUsagesCount(); long currentTS = System.nanoTime(); - long duration = TimeUnit.MILLISECONDS.convert(currentTS - start, TimeUnit.NANOSECONDS); + long durationFirstResults = TimeUnit.NANOSECONDS.toMillis(firstItemFoundTS.get() - start); + long duration = TimeUnit.NANOSECONDS.toMillis(currentTS - start); String notification = StringUtil.capitalizeWords(UsageViewBundle.message("usages.n", count), true); LOG.debug(notification + " in " + duration + "ms."); - reportFUS(count, TimeUnit.MILLISECONDS.convert(currentTS - firstItemFoundTS.get(), TimeUnit.NANOSECONDS), - duration, tooManyUsages.get()); + reportFUS(count, durationFirstResults, duration, tooManyUsages.get()); return new NotificationInfo("Find Usages", UsageViewBundle.message("notification.title.find.usages.finished"), notification); } - private void reportFUS(int count, long firstResultTS, long duration, boolean tooManyUsages) { + private void reportFUS(int count, long durationFirstResults, long duration, boolean tooManyUsages) { PsiElement element = SearchForUsagesRunnable.getPsiElement(searchFor); if (element != null) { Class<? extends PsiElement> targetClass = element.getClass(); @@ -194,7 +194,7 @@ public class UsageViewManagerImpl extends UsageViewManager { } UsageViewStatisticsCollector.logSearchFinished(myProject, targetClass, scope, language, - count, firstResultTS, duration, tooManyUsages, + count, durationFirstResults, duration, tooManyUsages, CodeNavigateSource.FindToolWindow); } } diff --git a/platform/vcs-impl/resources/META-INF/VcsActions.xml b/platform/vcs-impl/resources/META-INF/VcsActions.xml index e379092a94f3..73882b8698a4 100644 --- a/platform/vcs-impl/resources/META-INF/VcsActions.xml +++ b/platform/vcs-impl/resources/META-INF/VcsActions.xml @@ -651,5 +651,8 @@ <group class="com.intellij.openapi.vcs.actions.ShowAnnotateOperationsPopup$Group" popup="true" id="ShowAnnotateOperationsPopupGroup"/> </group> + <action id="MarkFileDirty" internal="true" class="com.intellij.openapi.vcs.changes.actions.MarkFileDirtyAction"> + <add-to-group group-id="Internal.VFS"/> + </action> </actions> </idea-plugin> diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeViewDiffRequestProcessor.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeViewDiffRequestProcessor.java index b5d09147b530..d50cb79ca8e4 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeViewDiffRequestProcessor.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeViewDiffRequestProcessor.java @@ -37,7 +37,8 @@ import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; -public abstract class ChangeViewDiffRequestProcessor extends CacheDiffRequestProcessor.Simple implements DiffPreviewUpdateProcessor { +public abstract class ChangeViewDiffRequestProcessor extends CacheDiffRequestProcessor.Simple + implements DiffPreviewUpdateProcessor, DiffRequestProcessorWithProducers { private static final int MANY_CHANGES_THRESHOLD = 10000; @@ -51,6 +52,16 @@ public abstract class ChangeViewDiffRequestProcessor extends CacheDiffRequestPro // Abstract // + @Override + public ListSelection<? extends DiffRequestProducer> collectDiffProducers(boolean selectedOnly) { + Project project = getProject(); + Wrapper change = getCurrentChange(); + List<Wrapper> changes = (selectedOnly ? getSelectedChanges() : getAllChanges()).collect(Collectors.toList()); + return ListSelection.create(changes, change) + .withExplicitSelection(selectedOnly) + .map(wrapper -> wrapper.createProducer(project)); + } + @NotNull public abstract Stream<? extends Wrapper> getSelectedChanges(); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java index 0a243ebd7786..b96c6cb7df0b 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java @@ -485,7 +485,7 @@ public class ChangesViewManager implements ChangesViewEx, } @Override - public void updateAvailability(@NotNull AnActionEvent e) { + public void updateDiffAction(@NotNull AnActionEvent e) { ShowDiffFromLocalChangesActionProvider.updateAvailability(e); } @@ -525,7 +525,7 @@ public class ChangesViewManager implements ChangesViewEx, PreviewDiffSplitterComponent previewSplitter = new PreviewDiffSplitterComponent(changeProcessor, CHANGES_VIEW_PREVIEW_SPLITTER_PROPORTION); previewSplitter.setFirstComponent(myContentPanel); - previewSplitter.setPreviewVisible(myVcsConfiguration.LOCAL_CHANGES_DETAILS_PREVIEW_SHOWN, false); + DiffPreview.setPreviewVisible(previewSplitter, myVcsConfiguration.LOCAL_CHANGES_DETAILS_PREVIEW_SHOWN); myView.addSelectionListener(() -> { boolean fromModelRefresh = myModelUpdateInProgress; @@ -873,20 +873,20 @@ public class ChangesViewManager implements ChangesViewEx, refreshView(); } } - } - public boolean isDiffPreviewAvailable() { if (myToolWindowPanel == null) return false; - return myToolWindowPanel.mySplitterDiffPreview != null || ChangesViewToolWindowPanel.isOpenEditorDiffPreviewWithSingleClick.asBoolean(); + return myToolWindowPanel.mySplitterDiffPreview != null || + myToolWindowPanel.myEditorDiffPreview != null && ChangesViewToolWindowPanel.isOpenEditorDiffPreviewWithSingleClick.asBoolean(); } public void diffPreviewChanged(boolean state) { if (myToolWindowPanel == null) return; - ObjectUtils.chooseNotNull(myToolWindowPanel.mySplitterDiffPreview, myToolWindowPanel.myEditorDiffPreview) - .setPreviewVisible(state, false); + DiffPreview preview = ObjectUtils.chooseNotNull(myToolWindowPanel.mySplitterDiffPreview, + myToolWindowPanel.myEditorDiffPreview); + DiffPreview.setPreviewVisible(preview, state); myToolWindowPanel.setCommitSplitOrientation(); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/DiffPreview.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/DiffPreview.kt index df7cc2af073c..ea7a31835623 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/DiffPreview.kt +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/DiffPreview.kt @@ -4,7 +4,31 @@ package com.intellij.openapi.vcs.changes import com.intellij.openapi.actionSystem.AnActionEvent interface DiffPreview { - fun updateAvailability(event: AnActionEvent) = Unit fun updatePreview(fromModelRefresh: Boolean) = Unit - fun setPreviewVisible(isPreviewVisible: Boolean, focus: Boolean = false) = Unit + + fun openPreview(requestFocus: Boolean): Boolean + fun closePreview() + + /** + * Allows overriding 'Show Diff' action availability and presentation + */ + fun updateDiffAction(event: AnActionEvent) = Unit + + /** + * Allows overriding 'Show Diff' action behavior. + * For example, by using External Diff Tools when applicable. + */ + fun performDiffAction(): Boolean = openPreview(true) + + companion object { + @JvmStatic + fun setPreviewVisible(preview: DiffPreview, value: Boolean) { + if (value) { + preview.openPreview(false) + } + else { + preview.closePreview() + } + } + } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/DiffRequestProcessorWithProducers.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/DiffRequestProcessorWithProducers.java new file mode 100644 index 000000000000..f5971049fdb7 --- /dev/null +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/DiffRequestProcessorWithProducers.java @@ -0,0 +1,11 @@ +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.openapi.vcs.changes; + +import com.intellij.diff.chains.DiffRequestProducer; +import com.intellij.openapi.ListSelection; +import org.jetbrains.annotations.Nullable; + +public interface DiffRequestProcessorWithProducers { + @Nullable + ListSelection<? extends DiffRequestProducer> collectDiffProducers(boolean selectedOnly); +} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/EditorTabDiffPreviewManager.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/EditorTabDiffPreviewManager.kt index 71198be2102a..7704dc7ff2e6 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/EditorTabDiffPreviewManager.kt +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/EditorTabDiffPreviewManager.kt @@ -3,7 +3,6 @@ package com.intellij.openapi.vcs.changes import com.intellij.diff.editor.DiffEditorTabFilesManager import com.intellij.diff.editor.DiffEditorTabFilesManager.Companion.isDiffInEditor -import com.intellij.diff.tools.external.ExternalDiffTool import com.intellij.openapi.Disposable import com.intellij.openapi.actionSystem.DataKey import com.intellij.openapi.components.service @@ -17,7 +16,7 @@ import com.intellij.openapi.vfs.VirtualFile class EditorTabDiffPreviewManager(private val project: Project) : DiffEditorTabFilesManager { - fun isEditorDiffPreviewAvailable() = isEditorDiffPreview.asBoolean() && !ExternalDiffTool.isEnabled() + fun isEditorDiffPreviewAvailable() = isEditorDiffPreview.asBoolean() fun subscribeToPreviewVisibilityChange(disposable: Disposable, onVisibilityChange: Runnable) { isEditorDiffPreview.addListener(object : RegistryValueListener { @@ -38,10 +37,6 @@ class EditorTabDiffPreviewManager(private val project: Project) : DiffEditorTabF return VcsEditorTabFilesManager.getInstance().openFile(project, diffFile, focusEditor, !isDiffInEditor, false) } - fun showDiffPreview(diffPreview: DiffPreview) { - diffPreview.setPreviewVisible(true, true) - } - companion object { private val isEditorDiffPreview = Registry.get("show.editor.diff.preview") diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/EditorTabPreview.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/EditorTabPreview.kt index 7836b5698159..bc9816b07c0e 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/EditorTabPreview.kt +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/EditorTabPreview.kt @@ -1,12 +1,15 @@ // Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.openapi.vcs.changes +import com.intellij.diff.DiffDialogHints import com.intellij.diff.chains.DiffRequestChain +import com.intellij.diff.chains.DiffRequestProducer import com.intellij.diff.chains.SimpleDiffRequestChain import com.intellij.diff.editor.DiffEditorEscapeAction import com.intellij.diff.editor.DiffEditorTabFilesManager import com.intellij.diff.editor.DiffVirtualFile import com.intellij.diff.impl.DiffRequestProcessor +import com.intellij.diff.tools.external.ExternalDiffTool import com.intellij.diff.util.DiffUserDataKeysEx import com.intellij.openapi.Disposable import com.intellij.openapi.ListSelection @@ -26,13 +29,13 @@ import com.intellij.openapi.wm.ToolWindowManager import com.intellij.util.EditSourceOnDoubleClickHandler.isToggleEvent import com.intellij.util.IJSwingUtilities import com.intellij.util.Processor +import com.intellij.util.castSafelyTo import com.intellij.util.ui.update.DisposableUpdate import com.intellij.util.ui.update.MergingUpdateQueue import org.jetbrains.annotations.Nls import java.awt.event.KeyEvent import java.awt.event.MouseEvent import javax.swing.JComponent -import kotlin.streams.toList abstract class EditorTabPreview(protected val diffProcessor: DiffRequestProcessor) : DiffPreview { protected val project get() = diffProcessor.project!! @@ -86,7 +89,7 @@ abstract class EditorTabPreview(protected val diffProcessor: DiffRequestProcesso val newDoubleClickHandler = Processor<MouseEvent> { e -> if (isToggleEvent(tree, e)) return@Processor false - isPreviewOnDoubleClickAllowed() && openPreview(true) || oldDoubleClickHandler?.process(e) == true + isPreviewOnDoubleClickAllowed() && performDiffAction() || oldDoubleClickHandler?.process(e) == true } tree.doubleClickHandler = newDoubleClickHandler @@ -96,7 +99,7 @@ abstract class EditorTabPreview(protected val diffProcessor: DiffRequestProcesso private fun installEnterKeyHandler(tree: ChangesTree) { val oldEnterKeyHandler = tree.enterKeyHandler val newEnterKeyHandler = Processor<KeyEvent> { e -> - isPreviewOnEnterAllowed() && openPreview(false) || oldEnterKeyHandler?.process(e) == true + isPreviewOnEnterAllowed() && performDiffAction() || oldEnterKeyHandler?.process(e) == true } tree.enterKeyHandler = newEnterKeyHandler @@ -128,26 +131,40 @@ abstract class EditorTabPreview(protected val diffProcessor: DiffRequestProcesso } } - override fun setPreviewVisible(isPreviewVisible: Boolean, focus: Boolean) { - if (isPreviewVisible) openPreview(focus) else closePreview() - } - protected fun isPreviewOpen(): Boolean = FileEditorManager.getInstance(project).isFileOpenWithRemotes(previewFile) - fun closePreview() { + override fun closePreview() { FileEditorManager.getInstance(project).closeFile(previewFile) updatePreviewProcessor?.clear() } - open fun openPreview(focusEditor: Boolean): Boolean { + override fun openPreview(requestFocus: Boolean): Boolean { + if (!ensureHasContent()) return false + return openPreviewEditor(requestFocus) + } + + private fun ensureHasContent(): Boolean { updatePreviewProcessor?.refresh(false) - if (!hasContent()) return false + return hasContent() + } + private fun openPreviewEditor(requestFocus: Boolean): Boolean { escapeHandler?.let { handler -> registerEscapeHandler(previewFile, handler) } + openPreview(project, previewFile, requestFocus) + return true + } - openPreview(project, previewFile, focusEditor) + override fun performDiffAction(): Boolean { + if (!ensureHasContent()) return false - return true + if (ExternalDiffTool.isEnabled()) { + val diffProducers = diffProcessor.castSafelyTo<DiffRequestProcessorWithProducers>()?.collectDiffProducers(true) + if (showExternalToolIfNeeded(project, diffProducers)) { + return true + } + } + + return openPreviewEditor(true) } private class EditorTabDiffPreviewVirtualFile(val preview: EditorTabPreview) @@ -166,6 +183,15 @@ abstract class EditorTabPreview(protected val diffProcessor: DiffRequestProcesso fun registerEscapeHandler(file: VirtualFile, handler: Runnable) { file.putUserData(DiffVirtualFile.ESCAPE_HANDLER, EditorTabPreviewEscapeAction(handler)) } + + fun showExternalToolIfNeeded(project: Project?, diffProducers: ListSelection<out DiffRequestProducer>?): Boolean { + if (diffProducers == null || diffProducers.isEmpty) return false + + val producers = diffProducers.explicitSelection + if (!ExternalDiffTool.wantShowExternalToolFor(producers)) return false + ExternalDiffTool.show(project, producers, DiffDialogHints.DEFAULT) + return true + } } } @@ -187,11 +213,9 @@ private class EditorTabDiffPreviewProvider( override fun getEditorTabName(processor: DiffRequestProcessor?): @Nls String = tabNameProvider().orEmpty() override fun createDiffRequestChain(): DiffRequestChain? { - if (diffProcessor is ChangeViewDiffRequestProcessor) { - val producers = ListSelection.create(diffProcessor.allChanges.toList(), diffProcessor.currentChange).map { - it.createProducer(diffProcessor.project) - } - return SimpleDiffRequestChain.fromProducers(producers.list, producers.selectedIndex) + if (diffProcessor is DiffRequestProcessorWithProducers) { + val producers = diffProcessor.collectDiffProducers(false) ?: return null + return SimpleDiffRequestChain.fromProducers(producers) } return null } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreviewDiffSplitterComponent.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreviewDiffSplitterComponent.kt index 1646f397c0c4..daef68ca82bc 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreviewDiffSplitterComponent.kt +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreviewDiffSplitterComponent.kt @@ -13,22 +13,38 @@ class PreviewDiffSplitterComponent( private var isPreviewVisible = false - override fun updatePreview(fromModelRefresh: Boolean) = - updatePreviewProcessor.run { if (isPreviewVisible) refresh(fromModelRefresh) else clear() } - - override fun setPreviewVisible(isPreviewVisible: Boolean, focus: Boolean) { - this.isPreviewVisible = isPreviewVisible - if (this.isPreviewVisible == (secondComponent == null)) { - updateVisibility() + override fun updatePreview(fromModelRefresh: Boolean) { + if (isPreviewVisible) { + updatePreviewProcessor.refresh(fromModelRefresh) + } + else { + updatePreviewProcessor.clear() } + } + + override fun openPreview(requestFocus: Boolean): Boolean { + setPreviewVisible(true) updatePreview(false) + return true } - private fun updateVisibility() { - secondComponent = if (isPreviewVisible) updatePreviewProcessor.component else null - secondComponent?.let { - updateComponentTreeUI(it) - it.minimumSize = emptySize() + override fun closePreview() { + setPreviewVisible(false) + updatePreview(false) + } + + private fun setPreviewVisible(isVisible: Boolean) { + if (isPreviewVisible == isVisible) return + isPreviewVisible = isVisible + + if (isVisible) { + secondComponent = updatePreviewProcessor.component.also { + updateComponentTreeUI(it) + it.minimumSize = emptySize() + } + } + else { + secondComponent = null } validate() diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ShowEditorDiffPreviewActionProvider.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ShowEditorDiffPreviewActionProvider.kt index 66c7d1a29129..057c5f9590cd 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ShowEditorDiffPreviewActionProvider.kt +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ShowEditorDiffPreviewActionProvider.kt @@ -16,17 +16,14 @@ open class ShowEditorDiffPreviewActionProvider : AnActionExtensionProvider { } override fun update(e: AnActionEvent) { - getDiffPreview(e)?.run { - e.presentation.description += " " + message("action.Diff.ShowDiffPreview.description") - updateAvailability(e) - } + val diffPreview = getDiffPreview(e)!! + e.presentation.description += " " + message("action.Diff.ShowDiffPreview.description") + diffPreview.updateDiffAction(e) } override fun actionPerformed(e: AnActionEvent) { val diffPreview = getDiffPreview(e)!! - - val previewManager = EditorTabDiffPreviewManager.getInstance(e.project!!) - previewManager.showDiffPreview(diffPreview) + diffPreview.performDiffAction() } open fun getDiffPreview(e: AnActionEvent) = e.getData(EDITOR_TAB_DIFF_PREVIEW) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsChangesSelectionRule.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsChangesSelectionRule.java index 9226832ea24a..869a5e0ed71b 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsChangesSelectionRule.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsChangesSelectionRule.java @@ -35,7 +35,8 @@ public class VcsChangesSelectionRule implements GetDataRule { public ListSelection<Change> getChangesSelection(@NotNull DataProvider dataProvider) { Change[] selectedChanges = VcsDataKeys.SELECTED_CHANGES.getData(dataProvider); if (selectedChanges != null) { - return ListSelection.createAt(Arrays.asList(selectedChanges), 0); + return ListSelection.createAt(Arrays.asList(selectedChanges), 0) + .withExplicitSelection(true); } Change[] changes = VcsDataKeys.CHANGES.getData(dataProvider); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/ShowDiffAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/ShowDiffAction.java index 2adefb25951b..18e4912b4524 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/ShowDiffAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/ShowDiffAction.java @@ -99,10 +99,11 @@ public class ShowDiffAction implements AnActionExtensionProvider { public static void showDiffForChange(@Nullable Project project, @NotNull ListSelection<? extends Change> changes, @NotNull ShowDiffContext context) { - ListSelection<ChangeDiffRequestProducer> presentables = changes.map(change -> ChangeDiffRequestProducer.create(project, change, context.getChangeContext(change))); + ListSelection<ChangeDiffRequestProducer> presentables = + changes.map(change -> ChangeDiffRequestProducer.create(project, change, context.getChangeContext(change))); if (presentables.isEmpty()) return; - DiffRequestChain chain = new ChangeDiffRequestChain(presentables.getList(), presentables.getSelectedIndex()); + DiffRequestChain chain = new ChangeDiffRequestChain(presentables); for (Map.Entry<Key<?>, Object> entry : context.getChainContext().entrySet()) { //noinspection unchecked,rawtypes diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/ShowDiffFromLocalChangesActionProvider.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/ShowDiffFromLocalChangesActionProvider.java index 72bd13b7ffe7..86d57f01d804 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/ShowDiffFromLocalChangesActionProvider.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/ShowDiffFromLocalChangesActionProvider.java @@ -109,7 +109,7 @@ public class ShowDiffFromLocalChangesActionProvider implements AnActionExtension else { ListSelection<Producer> producers = collectRequestProducers(project, changes, unversioned, view); if (producers.isEmpty()) return; - chain = new ChangeDiffRequestChain(producers.getList(), producers.getSelectedIndex()); + chain = new ChangeDiffRequestChain(producers); } chain.putUserData(DiffUserDataKeysEx.LAST_REVISION_WITH_LOCAL, true); @@ -146,9 +146,9 @@ public class ShowDiffFromLocalChangesActionProvider implements AnActionExtension @NotNull public static ListSelection<Producer> collectRequestProducers(@NotNull Project project, - @NotNull List<? extends Change> changes, - @NotNull List<? extends FilePath> unversioned, - @NotNull ChangesListView changesView) { + @NotNull List<? extends Change> changes, + @NotNull List<? extends FilePath> unversioned, + @NotNull ChangesListView changesView) { if (changes.size() == 1 && unversioned.isEmpty()) { // show all changes from this changelist Change selectedChange = changes.get(0); List<Change> selectedChanges = changesView.getAllChangesFromSameChangelist(selectedChange); @@ -171,7 +171,8 @@ public class ShowDiffFromLocalChangesActionProvider implements AnActionExtension ListSelection<Producer> changeProducers = createChangeProducers(project, changes, 0); ListSelection<Producer> unversionedProducers = createUnversionedProducers(project, unversioned, 0); - return ListSelection.createAt(ContainerUtil.concat(changeProducers.getList(), unversionedProducers.getList()), 0); + return ListSelection.createAt(ContainerUtil.concat(changeProducers.getList(), unversionedProducers.getList()), 0) + .asExplicitSelection(); } private static ListSelection<Producer> createChangeProducers(@NotNull Project project, diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/savedPatches/SavedPatchesEditorDiffPreview.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/savedPatches/SavedPatchesEditorDiffPreview.kt index b2b06321561a..bc27adbaa63d 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/savedPatches/SavedPatchesEditorDiffPreview.kt +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/savedPatches/SavedPatchesEditorDiffPreview.kt @@ -20,9 +20,9 @@ abstract class SavedPatchesEditorDiffPreview(diffProcessor: SavedPatchesDiffPrev Disposer.register(diffProcessor, Disposable { lastFocusOwner = null }) } - override fun openPreview(focusEditor: Boolean): Boolean { + override fun openPreview(requestFocus: Boolean): Boolean { lastFocusOwner = IdeFocusManager.getInstance(project).focusOwner - return super.openPreview(focusEditor) + return super.openPreview(requestFocus) } override fun returnFocusToTree() { @@ -31,7 +31,7 @@ abstract class SavedPatchesEditorDiffPreview(diffProcessor: SavedPatchesDiffPrev focusMainComponent(focusOwner) } - override fun updateAvailability(event: AnActionEvent) { + override fun updateDiffAction(event: AnActionEvent) { event.presentation.isVisible = true event.presentation.isEnabled = !changeViewProcessor.allChanges.isEmpty() } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/DiffShelvedChangesActionProvider.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/DiffShelvedChangesActionProvider.java index ea8b8a1c4b09..7ab18df1f56d 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/DiffShelvedChangesActionProvider.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/DiffShelvedChangesActionProvider.java @@ -158,7 +158,7 @@ public final class DiffShelvedChangesActionProvider implements AnActionExtension ListSelection<? extends ChangeDiffRequestChain.Producer> diffRequestProducers = createDiffProducers(dc, withLocal); if (diffRequestProducers == null || diffRequestProducers.isEmpty()) return; - DiffRequestChain chain = new ChangeDiffRequestChain(diffRequestProducers.getList(), diffRequestProducers.getSelectedIndex()); + DiffRequestChain chain = new ChangeDiffRequestChain(diffRequestProducers); chain.putUserData(PatchesPreloader.SHELF_PRELOADER, new PatchesPreloader(project)); DiffManager.getInstance().showDiff(project, chain, DiffDialogHints.FRAME); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangesViewManager.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangesViewManager.java index 6ff1182af825..da008397b8cb 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangesViewManager.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangesViewManager.java @@ -218,7 +218,8 @@ public class ShelvedChangesViewManager implements Disposable { createShelvedListsWithChangesNode(shelvedLists, createTagNode(VcsBundle.message("shelve.recently.deleted.node"))); } - private void createShelvedListsWithChangesNode(@NotNull List<ShelvedChangeList> shelvedLists, @NotNull ChangesBrowserNode<?> parentNode) { + private void createShelvedListsWithChangesNode(@NotNull List<ShelvedChangeList> shelvedLists, + @NotNull ChangesBrowserNode<?> parentNode) { shelvedLists.forEach(changeList -> { List<ShelvedWrapper> shelvedChanges = new ArrayList<>(); requireNonNull(changeList.getChanges()).stream().map(change -> new ShelvedWrapper(change, changeList)).forEach(shelvedChanges::add); @@ -487,7 +488,7 @@ public class ShelvedChangesViewManager implements Disposable { } } } - return wrappers; + return wrappers.asExplicitSelection(); } @NotNull @@ -796,7 +797,7 @@ public class ShelvedChangesViewManager implements Disposable { } @Override - public void updateAvailability(@NotNull AnActionEvent event) { + public void updateDiffAction(@NotNull AnActionEvent event) { DiffShelvedChangesActionProvider.updateAvailability(event); } @@ -824,7 +825,7 @@ public class ShelvedChangesViewManager implements Disposable { PreviewDiffSplitterComponent previewSplitter = new PreviewDiffSplitterComponent(changeProcessor, SHELVE_PREVIEW_SPLITTER_PROPORTION); previewSplitter.setFirstComponent(myTreeScrollPane); - previewSplitter.setPreviewVisible(myVcsConfiguration.SHELVE_DETAILS_PREVIEW_SHOWN, false); + DiffPreview.setPreviewVisible(previewSplitter, myVcsConfiguration.SHELVE_DETAILS_PREVIEW_SHOWN); myTree.addSelectionListener(() -> previewSplitter.updatePreview(false), changeProcessor); @@ -884,7 +885,8 @@ public class ShelvedChangesViewManager implements Disposable { @Override public void setSelected(@NotNull AnActionEvent e, boolean state) { - ObjectUtils.chooseNotNull(mySplitterDiffPreview, myEditorDiffPreview).setPreviewVisible(state, false); + DiffPreview previewSplitter = ObjectUtils.chooseNotNull(mySplitterDiffPreview, myEditorDiffPreview); + DiffPreview.setPreviewVisible(previewSplitter, state); myVcsConfiguration.SHELVE_DETAILS_PREVIEW_SHOWN = state; } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangeDiffRequestChain.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangeDiffRequestChain.java index 9d6f04503dd0..e0ff4a4234fb 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangeDiffRequestChain.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangeDiffRequestChain.java @@ -3,13 +3,14 @@ package com.intellij.openapi.vcs.changes.ui; import com.intellij.diff.actions.impl.GoToChangePopupBuilder; import com.intellij.diff.chains.AsyncDiffRequestChain; -import com.intellij.diff.chains.DiffRequestChainBase; import com.intellij.diff.chains.DiffRequestProducer; import com.intellij.diff.chains.DiffRequestProducerException; +import com.intellij.diff.chains.DiffRequestSelectionChain; import com.intellij.openapi.ListSelection; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Conditions; +import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.openapi.vcs.changes.actions.diff.PresentableGoToChangePopupAction; import com.intellij.util.Consumer; import com.intellij.util.ObjectUtils; @@ -19,25 +20,36 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; -import java.util.Objects; -public class ChangeDiffRequestChain extends DiffRequestChainBase implements GoToChangePopupBuilder.Chain { +/** + * Supports typical tree-like "Go to Change" navigation popup. + * + * @see ChangeDiffRequestChain.Async + */ +public class ChangeDiffRequestChain extends UserDataHolderBase implements DiffRequestSelectionChain, GoToChangePopupBuilder.Chain { private static final Logger LOG = Logger.getInstance(ChangeDiffRequestChain.class); - @NotNull private final List<? extends Producer> myProducers; + @NotNull private final ListSelection<? extends Producer> myProducers; + + public ChangeDiffRequestChain(@NotNull ListSelection<? extends Producer> producers) { + myProducers = producers.map(it -> { + if (it == null) LOG.error("Producers must not be null"); + return it; + }); + } public ChangeDiffRequestChain(@NotNull List<? extends Producer> producers, int index) { - super(index); - if (ContainerUtil.exists(producers, Objects::isNull)) { - producers = ContainerUtil.skipNulls(producers); - LOG.error("Producers must not be null"); - } - myProducers = producers; + this(ListSelection.createAt(producers, index)); + } + + @Override + public @NotNull ListSelection<? extends Producer> getListSelection() { + return myProducers; } @Override @NotNull public List<? extends Producer> getRequests() { - return myProducers; + return myProducers.getList(); } @NotNull diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowser.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowser.java index 3ef3b4b6a468..4baa8d466526 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowser.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowser.java @@ -80,7 +80,7 @@ public class ChangesBrowser extends JPanel implements DataProvider, TypeSafeData MyUseCase.LOCAL_CHANGES.equals(useCase) ? RemoteRevisionsCache.getInstance(myProject).getChangesNodeDecorator() : null; myViewer = new ChangesTreeList<>(myProject, changes, capableOfExcludingChanges, - highlightProblems, inclusionListener, decorator) { + highlightProblems, inclusionListener, decorator) { @Override protected DefaultTreeModel buildTreeModel(final List<Change> changes11, ChangeNodeDecorator changeNodeDecorator) { return ChangesBrowser.this.buildTreeModel(changes11, changeNodeDecorator, isShowFlatten()); @@ -244,11 +244,13 @@ public class ChangesBrowser extends JPanel implements DataProvider, TypeSafeData private ListSelection<Change> getChangesSelection() { final Change leadSelection = myViewer.getLeadSelection(); List<Change> changes = getSelectedChanges(); + boolean explicitSelection = true; if (changes.size() < 2) { List<Change> allChanges = myViewer.getChanges(); if (allChanges.size() > 1 || changes.isEmpty()) { changes = allChanges; + explicitSelection = false; } } @@ -256,7 +258,8 @@ public class ChangesBrowser extends JPanel implements DataProvider, TypeSafeData return ListSelection.createSingleton(leadSelection); } - return ListSelection.create(changes, leadSelection); + return ListSelection.create(changes, leadSelection) + .withExplicitSelection(explicitSelection); } protected void afterDiffRefresh() { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserBase.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserBase.java index 69320ab0eab8..56d6ecb645af 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserBase.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserBase.java @@ -304,7 +304,7 @@ public abstract class ChangesBrowserBase extends JPanel implements DataProvider EditorTabDiffPreviewManager previewManager = EditorTabDiffPreviewManager.getInstance(myProject); DiffPreview diffPreview = getShowDiffActionPreview(); if (diffPreview != null && previewManager.isEditorDiffPreviewAvailable()) { - previewManager.showDiffPreview(diffPreview); + diffPreview.performDiffAction(); } else { showStandaloneDiff(myProject, this); @@ -321,7 +321,7 @@ public abstract class ChangesBrowserBase extends JPanel implements DataProvider @NotNull ListSelection<T> selection, @NotNull NullableFunction<? super T, ? extends ChangeDiffRequestChain.Producer> getDiffRequestProducer) { ListSelection<ChangeDiffRequestChain.Producer> producers = selection.map(getDiffRequestProducer); - DiffRequestChain chain = new ChangeDiffRequestChain(producers.getList(), producers.getSelectedIndex()); + DiffRequestChain chain = new ChangeDiffRequestChain(producers); changesBrowser.updateDiffContext(chain); DiffManager.getInstance().showDiff(project, chain, new DiffDialogHints(null, changesBrowser)); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SimpleTreeEditorDiffPreview.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SimpleTreeEditorDiffPreview.kt index 3f6acc5fea6c..885e544b60af 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SimpleTreeEditorDiffPreview.kt +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SimpleTreeEditorDiffPreview.kt @@ -9,16 +9,14 @@ import com.intellij.util.ui.UIUtil import javax.swing.JComponent abstract class SimpleTreeEditorDiffPreview( - diffProcessor: ChangeViewDiffRequestProcessor, + protected val changeViewProcessor: ChangeViewDiffRequestProcessor, tree: ChangesTree, targetComponent: JComponent, isOpenEditorDiffPreviewWithSingleClick: Boolean -) : EditorTabPreview(diffProcessor) { +) : EditorTabPreview(changeViewProcessor) { constructor(diffProcessor: ChangeViewDiffRequestProcessor, tree: ChangesTree) : this(diffProcessor, tree, tree, false) - protected val changeViewProcessor: ChangeViewDiffRequestProcessor get() = diffProcessor as ChangeViewDiffRequestProcessor - init { escapeHandler = Runnable { closePreview() @@ -32,7 +30,7 @@ abstract class SimpleTreeEditorDiffPreview( open fun returnFocusToTree() = Unit - override fun updateAvailability(event: AnActionEvent) { + override fun updateDiffAction(event: AnActionEvent) { event.presentation.isVisible = event.isFromActionToolbar || event.presentation.isEnabled } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/VcsTreeModelData.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/VcsTreeModelData.java index 3739d34c1664..728dd5b0383c 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/VcsTreeModelData.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/VcsTreeModelData.java @@ -206,7 +206,7 @@ public abstract class VcsTreeModelData { return Stream.of(paths) .filter(path -> (path.getPathCount() <= 1 || - path.getPathComponent(1) == tagNode)) + path.getPathComponent(1) == tagNode)) .map(path -> (ChangesBrowserNode<?>)path.getLastPathComponent()); } } @@ -272,7 +272,8 @@ public abstract class VcsTreeModelData { public static ListSelection<Object> getListSelectionOrAll(@NotNull JTree tree) { List<Object> entries = selected(tree).userObjects(); if (entries.size() > 1) { - return ListSelection.createAt(entries, 0); + return ListSelection.createAt(entries, 0) + .asExplicitSelection(); } ChangesBrowserNode<?> selected = selected(tree).nodesStream().findFirst().orElse(null); @@ -286,7 +287,8 @@ public abstract class VcsTreeModelData { } if (allEntries.size() <= entries.size()) { - return ListSelection.createAt(entries, 0); + return ListSelection.createAt(entries, 0) + .asExplicitSelection(); } else { int index = selected != null ? ContainerUtil.indexOfIdentity(allEntries, selected.getUserObject()) : 0; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/RepositoryBrowser.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/RepositoryBrowser.kt index 02fcd5239e96..d41994c0943b 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/RepositoryBrowser.kt +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/RepositoryBrowser.kt @@ -3,6 +3,7 @@ package com.intellij.openapi.vcs.impl import com.intellij.ide.impl.ContentManagerWatcher import com.intellij.openapi.Disposable +import com.intellij.openapi.ListSelection import com.intellij.openapi.actionSystem.* import com.intellij.openapi.fileChooser.FileChooserDescriptor import com.intellij.openapi.fileChooser.ex.FileSystemTreeImpl @@ -171,8 +172,9 @@ class DiffRepoWithLocalAction : AnActionExtensionProvider { override fun actionPerformed(e: AnActionEvent) { val repoBrowser = e.getData(REPOSITORY_BROWSER_DATA_KEY) ?: return - val changes = repoBrowser.getSelectionAsChanges() - ShowDiffAction.showDiffForChange(repoBrowser.project, changes) + val selection = ListSelection.createAt(repoBrowser.getSelectionAsChanges(), 0) + .asExplicitSelection() + ShowDiffAction.showDiffForChange(repoBrowser.project, selection) } } diff --git a/platform/vcs-impl/src/com/intellij/vcs/commit/ChangesViewCommitPanel.kt b/platform/vcs-impl/src/com/intellij/vcs/commit/ChangesViewCommitPanel.kt index 83a09b3f1ecc..d5d6849b8862 100644 --- a/platform/vcs-impl/src/com/intellij/vcs/commit/ChangesViewCommitPanel.kt +++ b/platform/vcs-impl/src/com/intellij/vcs/commit/ChangesViewCommitPanel.kt @@ -8,7 +8,6 @@ import com.intellij.openapi.vcs.FilePath import com.intellij.openapi.vcs.ProjectLevelVcsManager import com.intellij.openapi.vcs.VcsBundle.message import com.intellij.openapi.vcs.changes.* -import com.intellij.openapi.vcs.changes.ChangesViewManager.isEditorPreview import com.intellij.openapi.vcs.changes.ui.* import com.intellij.openapi.vcs.changes.ui.ChangesBrowserNode.UNVERSIONED_FILES_TAG import com.intellij.openapi.vcs.changes.ui.ChangesViewContentManager.Companion.LOCAL_CHANGES @@ -198,7 +197,7 @@ class ChangesViewCommitPanel(private val changesViewHost: ChangesViewPanel, priv private fun closeEditorPreviewIfEmpty() { val changesViewManager = ChangesViewManager.getInstance(project) as? ChangesViewManager ?: return - if (!isEditorPreview(project)) return + if (!ChangesViewManager.isEditorPreview(project)) return refreshData() changesViewManager.closeEditorPreview(true) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/history/FileHistoryDiffPreview.kt b/platform/vcs-log/impl/src/com/intellij/vcs/log/history/FileHistoryDiffPreview.kt index 5272358043ef..fa7e34ca69ba 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/history/FileHistoryDiffPreview.kt +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/history/FileHistoryDiffPreview.kt @@ -53,7 +53,7 @@ class FileHistoryEditorDiffPreview(project: Project, private val fileHistoryPane return SimpleDiffRequestChain.fromProducer(producer) } - override fun updateAvailability(event: AnActionEvent) { + override fun updateDiffAction(event: AnActionEvent) { val log = event.getData(VcsLogDataKeys.VCS_LOG) ?: return CompareRevisionsFromFileHistoryActionProvider.setTextAndDescription(event, log) } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/history/FileHistoryPanel.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/history/FileHistoryPanel.java index 7eb27ce5a0ee..e669268214e4 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/history/FileHistoryPanel.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/history/FileHistoryPanel.java @@ -144,12 +144,12 @@ public class FileHistoryPanel extends JPanel implements DataProvider, Disposable private void setEditorDiffPreview() { FileHistoryEditorDiffPreview preview = myEditorDiffPreview; - boolean isEditorDiffPreview = VcsLogUiUtil.isDiffPreviewInEditor(myProject); - if (isEditorDiffPreview && preview == null) { + boolean isEditorPreview = VcsLogUiUtil.isDiffPreviewInEditor(myProject); + if (isEditorPreview && preview == null) { preview = new FileHistoryEditorDiffPreview(myProject, this); myEditorDiffPreview = preview; } - else if (!isEditorDiffPreview && preview != null) { + else if (!isEditorPreview && preview != null) { preview.closePreview(); myEditorDiffPreview = null; } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/history/CompareRevisionsFromFileHistoryActionProvider.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/history/CompareRevisionsFromFileHistoryActionProvider.java index f2e30120e586..cec26ad57861 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/history/CompareRevisionsFromFileHistoryActionProvider.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/history/CompareRevisionsFromFileHistoryActionProvider.java @@ -1,6 +1,7 @@ // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.vcs.log.ui.actions.history; +import com.intellij.openapi.ListSelection; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.AnActionExtensionProvider; import com.intellij.openapi.actionSystem.CommonDataKeys; @@ -58,7 +59,9 @@ abstract public class CompareRevisionsFromFileHistoryActionProvider implements A Change[] changes = e.getData(VcsDataKeys.SELECTED_CHANGES); if (changes == null || changes.length != 1 || changes[0] == null) return; - ShowDiffAction.showDiffForChange(project, Arrays.asList(changes)); + ListSelection<Change> selection = ListSelection.createAt(Arrays.asList(changes), 0) + .asExplicitSelection(); + ShowDiffAction.showDiffForChange(project, selection); } public static void setTextAndDescription(@NotNull AnActionEvent e, @NotNull VcsLog log) { diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogChangesBrowser.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogChangesBrowser.java index 9eb3dc81ace0..ce1d9f2fc282 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogChangesBrowser.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogChangesBrowser.java @@ -105,11 +105,9 @@ public final class VcsLogChangesBrowser extends FilterableChangesBrowser { init(); - setEditorDiffPreview(isWithEditorDiffPreview && VcsLogUiUtil.isDiffPreviewInEditor(myProject)); if (isWithEditorDiffPreview) { - EditorTabDiffPreviewManager.getInstance(myProject).subscribeToPreviewVisibilityChange(this, () -> { - setEditorDiffPreview(VcsLogUiUtil.isDiffPreviewInEditor(myProject)); - }); + setEditorDiffPreview(); + EditorTabDiffPreviewManager.getInstance(myProject).subscribeToPreviewVisibilityChange(this, this::setEditorDiffPreview); } hideViewerBorder(); @@ -401,8 +399,9 @@ public final class VcsLogChangesBrowser extends FilterableChangesBrowser { return ChangeDiffRequestProducer.create(project, change, context); } - public void setEditorDiffPreview(boolean isWithEditorDiffPreview) { + private void setEditorDiffPreview() { EditorDiffPreview preview = myEditorDiffPreview; + boolean isWithEditorDiffPreview = VcsLogUiUtil.isDiffPreviewInEditor(myProject); if (isWithEditorDiffPreview && preview == null) { preview = new VcsLogEditorDiffPreview(myProject, this); diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogDiffPreview.kt b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogDiffPreview.kt index 995018c35dc8..7d0aecd4aaf0 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogDiffPreview.kt +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogDiffPreview.kt @@ -4,6 +4,7 @@ package com.intellij.vcs.log.ui.frame import com.intellij.diff.chains.DiffRequestChain import com.intellij.diff.chains.SimpleDiffRequestChain import com.intellij.diff.impl.DiffRequestProcessor +import com.intellij.diff.tools.external.ExternalDiffTool import com.intellij.openapi.Disposable import com.intellij.openapi.actionSystem.ActionToolbar import com.intellij.openapi.application.invokeLater @@ -107,11 +108,7 @@ abstract class EditorDiffPreview(protected val project: Project, } } - override fun setPreviewVisible(isPreviewVisible: Boolean, focus: Boolean) { - if (isPreviewVisible) openPreviewInEditor(focus) else closePreview() - } - - fun openPreviewInEditor(focusEditor: Boolean) { + override fun openPreview(requestFocus: Boolean): Boolean { val currentFocusOwner = IdeFocusManager.getInstance(project).focusOwner val escapeHandler = Runnable { closePreview() @@ -120,10 +117,11 @@ abstract class EditorDiffPreview(protected val project: Project, } registerEscapeHandler(previewFile, escapeHandler) - EditorTabPreview.openPreview(project, previewFile, focusEditor) + EditorTabPreview.openPreview(project, previewFile, requestFocus) + return true } - fun closePreview() { + override fun closePreview() { if (previewFileDelegate.isInitialized()) { FileEditorManager.getInstance(project).closeFile(previewFile) } @@ -170,6 +168,18 @@ class VcsLogEditorDiffPreview(project: Project, private val changesBrowser: VcsL val producers = VcsTreeModelData.getListSelectionOrAll(changesBrowser.viewer).map { changesBrowser.getDiffRequestProducer(it, false) } - return SimpleDiffRequestChain.fromProducers(producers.list, producers.selectedIndex) + return SimpleDiffRequestChain.fromProducers(producers) + } + + override fun performDiffAction(): Boolean { + if (ExternalDiffTool.isEnabled()) { + val diffProducers = VcsTreeModelData.getListSelectionOrAll(changesBrowser.viewer) + .map { change -> changesBrowser.getDiffRequestProducer(change, false) } + if (EditorTabPreview.showExternalToolIfNeeded(project, diffProducers)) { + return true + } + } + + return super.performDiffAction() } } diff --git a/platform/vfs-impl/src/com/intellij/openapi/vfs/newvfs/RefreshProgress.java b/platform/vfs-impl/src/com/intellij/openapi/vfs/newvfs/RefreshProgress.java index c59d1ccfc718..d5c5796e5d41 100644 --- a/platform/vfs-impl/src/com/intellij/openapi/vfs/newvfs/RefreshProgress.java +++ b/platform/vfs-impl/src/com/intellij/openapi/vfs/newvfs/RefreshProgress.java @@ -1,10 +1,8 @@ -// Copyright 2000-2019 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.openapi.vfs.newvfs; import com.intellij.diagnostic.LoadingState; import com.intellij.ide.impl.ProjectUtilCore; -import com.intellij.internal.statistic.eventLog.FeatureUsageData; -import com.intellij.internal.statistic.service.fus.collectors.FUCounterUsageLogger; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.progress.EmptyProgressIndicator; @@ -25,7 +23,6 @@ final class RefreshProgress extends ProgressIndicatorBase { } private final @NlsContexts.Tooltip String myMessage; - private long myStartedTime; private RefreshProgress(@NotNull @NlsContexts.Tooltip String message) { super(true); @@ -36,27 +33,12 @@ final class RefreshProgress extends ProgressIndicatorBase { public void start() { super.start(); scheduleUiUpdate(); - - myStartedTime = System.currentTimeMillis(); } @Override public void stop() { super.stop(); scheduleUiUpdate(); - - long finishedTime = System.currentTimeMillis(); - long duration = finishedTime - myStartedTime; - // do not report short refreshes to avoid polluting the event log and increasing its size - if (duration > 1000) { - Application application = ApplicationManager.getApplication(); - application.runReadAction(() -> { - // refresh might be finished during IDE shutdown, in this case, don't report events (requred subsystems are already disposed) - if (application.isDisposed()) return; - - VfsUsageCollector.logVfsRefreshed(myStartedTime, finishedTime, duration); - }); - } } private void scheduleUiUpdate() { diff --git a/platform/vfs-impl/src/com/intellij/openapi/vfs/newvfs/RefreshQueueImpl.java b/platform/vfs-impl/src/com/intellij/openapi/vfs/newvfs/RefreshQueueImpl.java index fb1213a9522c..922a1491d419 100644 --- a/platform/vfs-impl/src/com/intellij/openapi/vfs/newvfs/RefreshQueueImpl.java +++ b/platform/vfs-impl/src/com/intellij/openapi/vfs/newvfs/RefreshQueueImpl.java @@ -1,4 +1,4 @@ -// Copyright 2000-2020 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.openapi.vfs.newvfs; import com.intellij.ide.IdeCoreBundle; @@ -30,6 +30,8 @@ import java.util.List; import java.util.concurrent.Executor; import java.util.function.Consumer; +import static java.util.concurrent.TimeUnit.NANOSECONDS; + public final class RefreshQueueImpl extends RefreshQueue implements Disposable { private static final Logger LOG = Logger.getInstance(RefreshQueueImpl.class); @@ -64,7 +66,7 @@ public final class RefreshQueueImpl extends RefreshQueue implements Disposable { private void queueSessionSync(@NotNull RefreshSessionImpl session) { ((TransactionGuardImpl)TransactionGuard.getInstance()).assertWriteActionAllowed(); - executeRefreshSession(session); + executeRefreshSession(session, -1L); fireEventsSync(session); } @@ -73,14 +75,17 @@ public final class RefreshQueueImpl extends RefreshQueue implements Disposable { } private void queueSessionAsync(@NotNull RefreshSessionImpl session, @NotNull ModalityState modality) { - myQueue.execute(() -> executeSession(session, modality)); + long queuedAt = System.nanoTime(); + myQueue.execute(() -> executeSession(session, modality, queuedAt)); myEventCounter.eventHappened(session); } - private void executeSession(@NotNull RefreshSessionImpl session, @NotNull ModalityState modality) { + private void executeSession(@NotNull RefreshSessionImpl session, @NotNull ModalityState modality, long queuedAt) { + long timeInQueue = NANOSECONDS.toMillis(System.nanoTime() - queuedAt); startRefreshActivity(); try { - HeavyProcessLatch.INSTANCE.performOperation(HeavyProcessLatch.Type.Syncing, IdeCoreBundle.message("progress.title.doing.file.refresh.0", session), ()-> executeRefreshSession(session)); + String title = IdeCoreBundle.message("progress.title.doing.file.refresh.0", session); + HeavyProcessLatch.INSTANCE.performOperation(HeavyProcessLatch.Type.Syncing, title, () -> executeRefreshSession(session, timeInQueue)); } finally { finishRefreshActivity(); @@ -148,10 +153,10 @@ public final class RefreshQueueImpl extends RefreshQueue implements Disposable { return () -> session.fireEvents(events, appliers, true); } - private void executeRefreshSession(@NotNull RefreshSessionImpl session) { + private void executeRefreshSession(@NotNull RefreshSessionImpl session, long timeInQueue) { try { updateSessionMap(session, true); - session.scan(); + session.scan(timeInQueue); } finally { updateSessionMap(session, false); diff --git a/platform/vfs-impl/src/com/intellij/openapi/vfs/newvfs/RefreshSessionImpl.java b/platform/vfs-impl/src/com/intellij/openapi/vfs/newvfs/RefreshSessionImpl.java index ea8315a58642..895fb2e85924 100644 --- a/platform/vfs-impl/src/com/intellij/openapi/vfs/newvfs/RefreshSessionImpl.java +++ b/platform/vfs-impl/src/com/intellij/openapi/vfs/newvfs/RefreshSessionImpl.java @@ -1,4 +1,4 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.openapi.vfs.newvfs; import com.intellij.codeInsight.daemon.impl.FileStatusMap; @@ -12,10 +12,7 @@ import com.intellij.openapi.application.ex.ApplicationEx; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.util.ProgressIndicatorWithDelayedPresentation; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.AsyncFileListener; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.vfs.*; import com.intellij.openapi.vfs.ex.VirtualFileManagerEx; import com.intellij.openapi.vfs.impl.local.LocalFileSystemImpl; import com.intellij.openapi.vfs.newvfs.events.VFileEvent; @@ -28,6 +25,8 @@ import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.concurrent.atomic.AtomicLong; +import static java.util.concurrent.TimeUnit.NANOSECONDS; + final class RefreshSessionImpl extends RefreshSession { @SuppressWarnings("LoggerInitializedWithForeignClass") private static final Logger LOG = Logger.getInstance(RefreshSession.class); @@ -115,7 +114,7 @@ final class RefreshSessionImpl extends RefreshSession { ((RefreshQueueImpl)RefreshQueue.getInstance()).execute(this); } - void scan() { + void scan(long timeInQueue) { List<VirtualFile> workQueue = myWorkQueue; myWorkQueue = new ArrayList<>(); boolean forceRefresh = !myIsRecursive && !myIsAsync; // shallow sync refresh (e.g. project config files on open) @@ -128,7 +127,7 @@ final class RefreshSessionImpl extends RefreshSession { if (LOG.isTraceEnabled()) LOG.trace("scanning " + workQueue); - long t = System.currentTimeMillis(); + long t = System.nanoTime(); PerformanceWatcher.Snapshot snapshot = null; Map<String, Integer> types = null; if (DURATION_REPORT_THRESHOLD_MS > 0) { @@ -167,7 +166,14 @@ final class RefreshSessionImpl extends RefreshSession { } while (!myCancelled && myIsRecursive && count < RETRY_LIMIT && ContainerUtil.exists(workQueue, f -> ((NewVirtualFile)f).isDirty())); - t = System.currentTimeMillis() - t; + t = NANOSECONDS.toMillis(System.nanoTime() - t); + int localRoots = 0, archiveRoots = 0, otherRoots = 0; + for (VirtualFile file : workQueue) { + if (file.getFileSystem() instanceof LocalFileSystem) localRoots++; + else if (file.getFileSystem() instanceof ArchiveFileSystem) archiveRoots++; + else otherRoots++; + } + VfsUsageCollector.logRefreshSession(myIsRecursive, localRoots, archiveRoots, otherRoots, myCancelled, timeInQueue, t, count); if (LOG.isTraceEnabled()) { LOG.trace((myCancelled ? "cancelled, " : "done, ") + t + " ms, tries " + count + ", events " + myEvents); } diff --git a/platform/vfs-impl/src/com/intellij/openapi/vfs/newvfs/RefreshWorker.java b/platform/vfs-impl/src/com/intellij/openapi/vfs/newvfs/RefreshWorker.java index 0f1636b61754..fa268ed3e0b7 100644 --- a/platform/vfs-impl/src/com/intellij/openapi/vfs/newvfs/RefreshWorker.java +++ b/platform/vfs-impl/src/com/intellij/openapi/vfs/newvfs/RefreshWorker.java @@ -1,4 +1,4 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.openapi.vfs.newvfs; import com.intellij.openapi.application.ReadAction; @@ -30,6 +30,7 @@ import java.util.*; import java.util.function.Consumer; import static com.intellij.openapi.vfs.newvfs.VfsEventGenerationHelper.LOG; +import static java.util.concurrent.TimeUnit.NANOSECONDS; final class RefreshWorker { private final boolean myIsRecursive; @@ -37,6 +38,8 @@ final class RefreshWorker { private final VfsEventGenerationHelper myHelper = new VfsEventGenerationHelper(); private volatile boolean myCancelled; private final LocalFileSystemRefreshWorker myLocalFileSystemRefreshWorker; + private int myFullScans, myPartialScans, myProcessed; + private long myVfsTime, myIoTime; RefreshWorker(@NotNull NewVirtualFile refreshRoot, boolean isRecursive) { boolean canUseNioRefresher = refreshRoot.isInLocalFileSystem() && @@ -64,6 +67,7 @@ final class RefreshWorker { return; } + var t = System.nanoTime(); NewVirtualFile root = myRefreshQueue.removeFirst(); NewVirtualFileSystem fs = root.getFileSystem(); if (root.isDirectory()) { @@ -90,6 +94,10 @@ final class RefreshWorker { catch (RefreshCancelledException e) { LOG.trace("refresh cancelled"); } + + t = NANOSECONDS.toMillis(System.nanoTime() - t); + var retries = (myFullScans + myPartialScans) - myProcessed; + VfsUsageCollector.logRefreshScan(myFullScans, myPartialScans, retries, t, NANOSECONDS.toMillis(myVfsTime), NANOSECONDS.toMillis(myIoTime)); } private void queueDirectory(@NotNull NewVirtualFile root) { @@ -109,6 +117,7 @@ final class RefreshWorker { boolean succeeded; do { + if (fullSync) myFullScans++; else myPartialScans++; myHelper.beginTransaction(); try { succeeded = fullSync ? fullDirRefresh(fs, persistence, dir) : partialDirRefresh(fs, persistence, dir); @@ -121,6 +130,7 @@ final class RefreshWorker { if (!succeeded && LOG.isTraceEnabled()) LOG.trace("retry: " + dir); } while (!succeeded); + myProcessed++; if (myIsRecursive) { dir.markClean(); @@ -131,15 +141,19 @@ final class RefreshWorker { private boolean fullDirRefresh(@NotNull NewVirtualFileSystem fs, @NotNull PersistentFS persistence, @NotNull VirtualDirectoryImpl dir) { + var t = System.nanoTime(); Pair<List<String>, List<VirtualFile>> snapshot = LocalFileSystemRefreshWorker.getDirectorySnapshot(dir); + myVfsTime += System.nanoTime() - t; if (snapshot == null) { return false; } List<String> persistedNames = snapshot.getFirst(); List<VirtualFile> children = snapshot.getSecond(); + t = System.nanoTime(); Map<String, FileAttributes> childrenWithAttributes = fs instanceof BatchingFileSystem ? ((BatchingFileSystem)fs).listWithAttributes(dir) : null; String[] listDir = childrenWithAttributes != null ? ArrayUtil.toStringArray(childrenWithAttributes.keySet()) : fs.list(dir); + myIoTime += System.nanoTime() - t; String[] upToDateNames = VfsUtil.filterNames(listDir); Set<String> newNames = new HashSet<>(upToDateNames.length); ContainerUtil.addAll(newNames, upToDateNames); @@ -190,10 +204,12 @@ final class RefreshWorker { } } else { + t = System.nanoTime(); for (VirtualFile child : chs) { checkCancelled(dir); updatedMap.add(new Pair<>(child, fs.getAttributes(child))); } + myIoTime += System.nanoTime() - t; } if (isFullScanDirectoryChanged(dir, persistedNames, children)) { @@ -236,19 +252,24 @@ final class RefreshWorker { private boolean isFullScanDirectoryChanged(@NotNull VirtualDirectoryImpl dir, @NotNull List<String> names, @NotNull List<? extends VirtualFile> children) { - return ReadAction.compute(() -> { + var t = System.nanoTime(); + var changed = ReadAction.compute(() -> { checkCancelled(dir); return LocalFileSystemRefreshWorker.areChildrenOrNamesChanged(dir, names, children); }); + myVfsTime += System.nanoTime() - t; + return changed; } private boolean partialDirRefresh(@NotNull NewVirtualFileSystem fs, @NotNull PersistentFS persistence, @NotNull VirtualDirectoryImpl dir) { + var t = System.nanoTime(); Pair<List<VirtualFile>, List<String>> snapshot = ReadAction.compute(() -> { checkCancelled(dir); return new Pair<>(dir.getCachedChildren(), dir.getSuspiciousNames()); }); + myVfsTime += System.nanoTime() - t; List<VirtualFile> cached = snapshot.getFirst(); List<String> wanted = snapshot.getSecond(); @@ -257,7 +278,9 @@ final class RefreshWorker { actualNames = null; } else { + t = System.nanoTime(); actualNames = (ObjectOpenCustomHashSet<String>)CollectionFactory.createFilePathSet(VfsUtil.filterNames(fs.list(dir)), false); + myIoTime += System.nanoTime() - t; } if (LOG.isTraceEnabled()) { @@ -265,10 +288,12 @@ final class RefreshWorker { } List<Pair<VirtualFile, FileAttributes>> existingMap = new ArrayList<>(cached.size()); + t = System.nanoTime(); for (VirtualFile child : cached) { checkCancelled(dir); existingMap.add(new Pair<>(child, fs.getAttributes(child))); } + myIoTime += System.nanoTime() - t; List<ChildInfo> newKids = new ArrayList<>(wanted.size()); for (String name : wanted) { @@ -305,21 +330,29 @@ final class RefreshWorker { } private boolean isDirectoryChanged(@NotNull VirtualDirectoryImpl dir, @NotNull List<VirtualFile> cached, @NotNull List<String> wanted) { - return ReadAction.compute(() -> { + var t = System.nanoTime(); + var changed = ReadAction.compute(() -> { checkCancelled(dir); return !cached.equals(dir.getCachedChildren()) || !wanted.equals(dir.getSuspiciousNames()); }); + myVfsTime += System.nanoTime() - t; + return changed; } - private static @Nullable ChildInfo childRecord(NewVirtualFileSystem fs, VirtualFile dir, String name, boolean canonicalize) { + private @Nullable ChildInfo childRecord(NewVirtualFileSystem fs, VirtualFile dir, String name, boolean canonicalize) { FakeVirtualFile file = new FakeVirtualFile(dir, name); + var t = System.nanoTime(); FileAttributes attributes = fs.getAttributes(file); - if (attributes == null) return null; + if (attributes == null) { + myIoTime += System.nanoTime() - t; + return null; + } boolean isEmptyDir = attributes.isDirectory() && !fs.hasChildren(file); String symlinkTarget = attributes.isSymLink() ? fs.resolveSymLink(file) : null; if (canonicalize) { name = fs.getCanonicallyCasedName(file); // need case-exact names in file events } + myIoTime += System.nanoTime() - t; return new ChildInfoImpl(name, attributes, isEmptyDir ? ChildInfo.EMPTY_ARRAY : null, symlinkTarget); } @@ -372,7 +405,10 @@ final class RefreshWorker { } if (childAttributes.isSymLink()) { - myHelper.checkSymbolicLinkChange(child, child.getCanonicalPath(), fs.resolveSymLink(child)); + var t = System.nanoTime(); + var target = fs.resolveSymLink(child); + myIoTime += System.nanoTime() - t; + myHelper.checkSymbolicLinkChange(child, child.getCanonicalPath(), target); } if (!childAttributes.isDirectory()) { @@ -397,7 +433,9 @@ final class RefreshWorker { if (currentIsDirectory != upToDateIsDirectory || currentIsSymlink != upToDateIsSymlink || currentIsSpecial != upToDateIsSpecial) { myHelper.scheduleDeletion(child); if (parent != null) { + var t = System.nanoTime(); String symlinkTarget = upToDateIsSymlink ? fs.resolveSymLink(child) : null; + myIoTime += System.nanoTime() - t; myHelper.scheduleCreation(parent, child.getName(), childAttributes, symlinkTarget, () -> checkCancelled(parent)); } else { diff --git a/platform/vfs-impl/src/com/intellij/openapi/vfs/newvfs/VfsUsageCollector.java b/platform/vfs-impl/src/com/intellij/openapi/vfs/newvfs/VfsUsageCollector.java new file mode 100644 index 000000000000..3b39b35cf4be --- /dev/null +++ b/platform/vfs-impl/src/com/intellij/openapi/vfs/newvfs/VfsUsageCollector.java @@ -0,0 +1,54 @@ +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.openapi.vfs.newvfs; + +import com.intellij.internal.statistic.eventLog.EventLogGroup; +import com.intellij.internal.statistic.eventLog.events.*; +import com.intellij.internal.statistic.service.fus.collectors.CounterUsagesCollector; + +final class VfsUsageCollector extends CounterUsagesCollector { + private static final int DURATION_THRESHOLD_MS = 100; + + private static final EventLogGroup GROUP = new EventLogGroup("vfs", 4); + + private static final BooleanEventField RefreshRecursive = EventFields.Boolean("recursive"); + private static final RoundedIntEventField RefreshLocalRoots = EventFields.RoundedInt("roots_local"); + private static final RoundedIntEventField RefreshArchiveRoots = EventFields.RoundedInt("roots_arc"); + private static final RoundedIntEventField RefreshOtherRoots = EventFields.RoundedInt("roots_other"); + private static final BooleanEventField RefreshCancelled = EventFields.Boolean("cancelled"); + private static final LongEventField RefreshWaitMs = EventFields.Long("wait_ms"); // -1 for synchronous refresh + private static final IntEventField RefreshTries = EventFields.Int("tries"); + private static final VarargEventId REFRESH_SESSION = GROUP.registerVarargEvent( + "refresh_session", + RefreshRecursive, RefreshLocalRoots, RefreshArchiveRoots, RefreshOtherRoots, + RefreshCancelled, RefreshWaitMs, EventFields.DurationMs, RefreshTries); + + private static final IntEventField RefreshFullScans = EventFields.Int("full_scans"); + private static final IntEventField RefreshPartialScans = EventFields.Int("partial_scans"); + private static final IntEventField RefreshRetries = EventFields.Int("retries"); + private static final LongEventField RefreshVfsTimeMs = EventFields.Long("vfs_time_ms"); + private static final LongEventField RefreshIoTimeMs = EventFields.Long("io_time_ms"); + private static final VarargEventId REFRESH_SCAN = GROUP.registerVarargEvent( + "refresh_scan", + RefreshFullScans, RefreshPartialScans, RefreshRetries, EventFields.DurationMs, RefreshVfsTimeMs, RefreshIoTimeMs); + + @Override + public EventLogGroup getGroup() { + return GROUP; + } + + static void logRefreshSession(boolean recursive, int lfsRoots, int arcRoots, int otherRoots, boolean cancelled, long wait, long duration, int tries) { + if (duration >= DURATION_THRESHOLD_MS) { + REFRESH_SESSION.log( + RefreshRecursive.with(recursive), RefreshLocalRoots.with(lfsRoots), RefreshArchiveRoots.with(arcRoots), RefreshOtherRoots.with(otherRoots), + RefreshCancelled.with(cancelled), RefreshWaitMs.with(wait), EventFields.DurationMs.with(duration), RefreshTries.with(tries)); + } + } + + static void logRefreshScan(int fullScans, int partialScans, int retries, long duration, long vfsTime, long ioTime) { + if (duration >= DURATION_THRESHOLD_MS) { + REFRESH_SCAN.log( + RefreshFullScans.with(fullScans), RefreshPartialScans.with(partialScans), RefreshRetries.with(retries), + EventFields.DurationMs.with(duration), RefreshVfsTimeMs.with(vfsTime), RefreshIoTimeMs.with(ioTime)); + } + } +} diff --git a/platform/vfs-impl/src/com/intellij/openapi/vfs/newvfs/VfsUsageCollector.kt b/platform/vfs-impl/src/com/intellij/openapi/vfs/newvfs/VfsUsageCollector.kt deleted file mode 100644 index f4799fef4209..000000000000 --- a/platform/vfs-impl/src/com/intellij/openapi/vfs/newvfs/VfsUsageCollector.kt +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.openapi.vfs.newvfs - -import com.intellij.internal.statistic.eventLog.EventLogGroup -import com.intellij.internal.statistic.eventLog.events.EventFields -import com.intellij.internal.statistic.service.fus.collectors.CounterUsagesCollector - -class VfsUsageCollector: CounterUsagesCollector() { - override fun getGroup(): EventLogGroup { - return GROUP - } - - companion object { - private val GROUP = EventLogGroup("vfs", 3) - private val REFRESHED = GROUP.registerEvent("refreshed", - EventFields.Long("start_time_ms"), - EventFields.Long("finish_time_ms"), - EventFields.DurationMs) - - @JvmStatic - fun logVfsRefreshed(startedTime: Long, finishedTime: Long, duration: Long) { - REFRESHED.log(startedTime, finishedTime, duration) - } - } -}
\ No newline at end of file diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ResumeAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ResumeAction.java index 0abd7dee36a1..eebed0a280a8 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ResumeAction.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ResumeAction.java @@ -23,9 +23,8 @@ public class ResumeAction extends XDebuggerActionBase implements DumbAware { if (session != null && !session.isStopped()) { return !session.isReadOnly() && session.isPaused(); } - // Android Studio: we don't want the resume action to ever start and show the debug config popup - //return e.getInputEvent() instanceof KeyEvent; - return false; + // disable visual representation but leave the shortcut action enabled + return e.getInputEvent() instanceof KeyEvent; } @Override diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/ArraysAsListWithZeroOrOneArgumentInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/ArraysAsListWithZeroOrOneArgumentInspection.java index 1c7feeca6fdb..9502c8476c6c 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/ArraysAsListWithZeroOrOneArgumentInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/ArraysAsListWithZeroOrOneArgumentInspection.java @@ -1,8 +1,10 @@ // Copyright 2000-2021 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.siyeh.ig.performance; +import com.intellij.codeInsight.Nullability; import com.intellij.codeInspection.CommonQuickFixBundle; import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.dataFlow.NullabilityUtil; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.util.PsiUtil; @@ -43,10 +45,9 @@ public class ArraysAsListWithZeroOrOneArgumentInspection extends BaseInspection @Nullable @Override protected InspectionGadgetsFix buildFix(Object... infos) { - final Boolean isEmpty = (Boolean)infos[0]; - final PsiElement element = (PsiElement)infos[1]; - final boolean level9OrHigher = PsiUtil.isLanguageLevel9OrHigher(element); - return new ArraysAsListWithOneArgumentFix(isEmpty.booleanValue(), level9OrHigher); + final boolean isEmpty = (Boolean)infos[0]; + final boolean level9OrHigher = (Boolean)infos[1]; + return new ArraysAsListWithOneArgumentFix(isEmpty, level9OrHigher); } private static final class ArraysAsListWithOneArgumentFix extends InspectionGadgetsFix { @@ -129,6 +130,7 @@ public class ArraysAsListWithZeroOrOneArgumentInspection extends BaseInspection final PsiExpression[] arguments = argumentList.getExpressions(); if (arguments.length > 1) return; + boolean isLevel9Plus = PsiUtil.isLanguageLevel9OrHigher(expression); boolean empty = false; if (arguments.length == 0) { empty = true; @@ -141,6 +143,10 @@ public class ArraysAsListWithZeroOrOneArgumentInspection extends BaseInspection } empty = true; } + if (isLevel9Plus && NullabilityUtil.getExpressionNullability(argument, true) != Nullability.NOT_NULL) { + // Avoid suggesting List.of with potentially nullable argument + isLevel9Plus = false; + } } final PsiMethod method = expression.resolveMethod(); if (method == null) { @@ -154,7 +160,7 @@ public class ArraysAsListWithZeroOrOneArgumentInspection extends BaseInspection if (!"java.util.Arrays".equals(className)) { return; } - registerMethodCallError(expression, empty, expression); + registerMethodCallError(expression, empty, isLevel9Plus); } } } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ClassUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ClassUtils.java index 5f74b7e73cea..a1be6b9c0ec9 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ClassUtils.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ClassUtils.java @@ -152,8 +152,9 @@ public final class ClassUtils { return aClass.hasModifierProperty(PsiModifier.FINAL) && Arrays.stream(aClass.getAllFields()) .filter(field -> !field.hasModifierProperty(PsiModifier.STATIC)) - .map(field -> field.getType()) - .allMatch(type -> TypeConversionUtil.isPrimitiveAndNotNull(type) || immutableTypes.contains(type.getCanonicalText())); + .allMatch(field -> field.hasModifierProperty(PsiModifier.FINAL) && + (TypeConversionUtil.isPrimitiveAndNotNull(field.getType()) || + immutableTypes.contains(field.getType().getCanonicalText()))); } public static boolean inSamePackage(@Nullable PsiElement element1, @Nullable PsiElement element2) { diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/SimplifiableIfStatementInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/SimplifiableIfStatementInspection.java index 4cc3754538cf..7764e2acbdbb 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/SimplifiableIfStatementInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/SimplifiableIfStatementInspection.java @@ -1,4 +1,4 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.siyeh.ig.style; import com.intellij.codeInspection.*; @@ -6,6 +6,7 @@ import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.psiutils.CommentTracker; import com.siyeh.ig.psiutils.ControlFlowUtils; @@ -69,6 +70,11 @@ public class SimplifiableIfStatementInspection extends AbstractBaseJavaLocalInsp if (var == null || !ref.isReferenceTo(var)) return; final PsiExpression rhs = assignment.getRExpression(); assert rhs != null; + boolean readBeforeWritten = SyntaxTraverser.psiTraverser(rhs) + .filter(PsiReferenceExpression.class) + .filter(r -> r.isReferenceTo(var) && PsiUtil.isAccessedForReading(r)) + .isNotEmpty(); + if (readBeforeWritten) return; CommentTracker ct = new CommentTracker(); var.setInitializer(ct.markUnchanged(rhs)); ct.deleteAndRestoreComments(result); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/resources/AutoCloseableResourceInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/resources/AutoCloseableResourceInspection.java index 4664a7aeb3b1..31a9cd9414a5 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/resources/AutoCloseableResourceInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/resources/AutoCloseableResourceInspection.java @@ -61,7 +61,8 @@ public class AutoCloseableResourceInspection extends ResourceInspection { "java.io.StringWriter", "java.io.StringReader", "java.util.Formatter", - "java.util.Scanner"); + "java.util.Scanner", + "org.springframework.context.ConfigurableApplicationContext"); protected final MethodMatcher myMethodMatcher; final List<String> ignoredTypes = new ArrayList<>(DEFAULT_IGNORED_TYPES); @SuppressWarnings("PublicField") diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/performance/ArraysAsListWithZeroOrOneArgumentFixJava9Test.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/performance/ArraysAsListWithZeroOrOneArgumentFixJava9Test.java index 21a0e776bf0b..a7398b133b09 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/performance/ArraysAsListWithZeroOrOneArgumentFixJava9Test.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/performance/ArraysAsListWithZeroOrOneArgumentFixJava9Test.java @@ -11,17 +11,18 @@ import com.siyeh.ig.performance.ArraysAsListWithZeroOrOneArgumentInspection; /** * @author Bas Leijdekkers */ +@SuppressWarnings({"ClassInitializerMayBeStatic", "ArraysAsListWithZeroOrOneArgument"}) public class ArraysAsListWithZeroOrOneArgumentFixJava9Test extends IGQuickFixesTestCase { public void testZeroArguments() { doTest(CommonQuickFixBundle.message("fix.replace.with.x", "List.of()"), "import java.util.*;\n" + "class X {{\n" + - " Arrays.asList/**/();\n" + + " Object o = Arrays.asList/**/();\n" + "}}", "import java.util.*;\n" + "class X {{\n" + - " List.of();\n" + + " Object o = List.of();\n" + "}}"); } @@ -50,6 +51,18 @@ public class ArraysAsListWithZeroOrOneArgumentFixJava9Test extends IGQuickFixesT "}}"); } + public void testOneArgumentNullable() { + doTest(CommonQuickFixBundle.message("fix.replace.with.x", "Collections.singletonList()"), + "import java.util.*;" + + "class X {{\n" + + " List<?> list = Arrays./**/asList((String)null);" + + "}}", + "import java.util.*;" + + "class X {{\n" + + " List<?> list = Collections.singletonList((String) null);" + + "}}"); + } + @Override protected void tuneFixture(JavaModuleFixtureBuilder builder) throws Exception { builder.setLanguageLevel(LanguageLevel.JDK_1_9); diff --git a/plugins/built-in-help/src/com/jetbrains/builtInHelp/BuiltInHelpManager.kt b/plugins/built-in-help/src/com/jetbrains/builtInHelp/BuiltInHelpManager.kt index 6c716b454351..791515dad12c 100644 --- a/plugins/built-in-help/src/com/jetbrains/builtInHelp/BuiltInHelpManager.kt +++ b/plugins/built-in-help/src/com/jetbrains/builtInHelp/BuiltInHelpManager.kt @@ -1,6 +1,7 @@ // Copyright 2000-2019 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.jetbrains.builtInHelp +import com.intellij.ide.BrowserUtil import com.intellij.ide.browsers.BrowserLauncher import com.intellij.ide.browsers.WebBrowserManager import com.intellij.openapi.application.ApplicationNamesInfo @@ -28,9 +29,11 @@ class BuiltInHelpManager : HelpManager() { override fun invokeHelp(helpId: String?) { try { - var url = "http://127.0.0.1:${BuiltInServerOptions.getInstance().effectiveBuiltInServerPort}/help/?${if (helpId != null) URLEncoder.encode( - helpId, StandardCharsets.UTF_8) - else "top"}" + var url = "http://127.0.0.1:${BuiltInServerOptions.getInstance().effectiveBuiltInServerPort}/help/?${ + if (helpId != null) URLEncoder.encode( + helpId, StandardCharsets.UTF_8) + else "top" + }" val tryOpenWebSite = java.lang.Boolean.valueOf(Utils.getStoredValue( SettingsPage.OPEN_HELP_FROM_WEB, "true")) @@ -78,14 +81,15 @@ class BuiltInHelpManager : HelpManager() { val browserName = java.lang.String.valueOf( Utils.getStoredValue(SettingsPage.USE_BROWSER, BuiltInHelpBundle.message("use.default.browser"))) - if (browserName == BuiltInHelpBundle.message("use.default.browser")) { - if (Desktop.isDesktopSupported()) { - Desktop.getDesktop().browse(URI(url)) - } - else BrowserLauncher.instance.browse(url, WebBrowserManager.getInstance().firstActiveBrowser) + val browser = WebBrowserManager.getInstance().findBrowserById(browserName) + + if (browser == null || browserName == BuiltInHelpBundle.message("use.default.browser")) { + BrowserUtil.browse(URI(url)) + } + else { + BrowserLauncher.instance.browse(url, browser) } - else BrowserLauncher.instance.browse(url, WebBrowserManager.getInstance().findBrowserById(browserName)) } catch (e: URISyntaxException) { diff --git a/plugins/git4idea/src/git4idea/index/actions/GitStageDiffAction.kt b/plugins/git4idea/src/git4idea/index/actions/GitStageDiffAction.kt index e1042951e322..b1a775295b04 100644 --- a/plugins/git4idea/src/git4idea/index/actions/GitStageDiffAction.kt +++ b/plugins/git4idea/src/git4idea/index/actions/GitStageDiffAction.kt @@ -23,7 +23,7 @@ class GitStageDiffAction : AnActionExtensionProvider { override fun actionPerformed(e: AnActionEvent) { val producers = e.getRequiredData(GitStageDataKeys.GIT_STAGE_TREE).statusNodesListSelection(true) .map { createTwoSidesDiffRequestProducer(e.project!!, it) } - DiffManager.getInstance().showDiff(e.project, ChangeDiffRequestChain(producers.list, producers.selectedIndex), DiffDialogHints.DEFAULT) + DiffManager.getInstance().showDiff(e.project, ChangeDiffRequestChain(producers), DiffDialogHints.DEFAULT) } companion object { @@ -49,6 +49,6 @@ class GitStageThreeSideDiffAction : DumbAwareAction() { override fun actionPerformed(e: AnActionEvent) { val producers = e.getRequiredData(GitStageDataKeys.GIT_STAGE_TREE).statusNodesListSelection(false) .map { createThreeSidesDiffRequestProducer(e.project!!, it) } - DiffManager.getInstance().showDiff(e.project, ChangeDiffRequestChain(producers.list, producers.selectedIndex), DiffDialogHints.DEFAULT) + DiffManager.getInstance().showDiff(e.project, ChangeDiffRequestChain(producers), DiffDialogHints.DEFAULT) } } diff --git a/plugins/git4idea/src/git4idea/index/ui/GitStageEditorDiffPreview.kt b/plugins/git4idea/src/git4idea/index/ui/GitStageEditorDiffPreview.kt index c2f79dd2c43d..51117065f43c 100644 --- a/plugins/git4idea/src/git4idea/index/ui/GitStageEditorDiffPreview.kt +++ b/plugins/git4idea/src/git4idea/index/ui/GitStageEditorDiffPreview.kt @@ -4,20 +4,21 @@ package git4idea.index.ui import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.vcs.VcsApplicationSettings import com.intellij.openapi.vcs.VcsBundle -import com.intellij.openapi.vcs.changes.ChangeViewDiffRequestProcessor import com.intellij.openapi.vcs.changes.EditorTabPreview import com.intellij.openapi.vcs.changes.ui.ChangesTree import com.intellij.openapi.wm.IdeFocusManager import git4idea.index.actions.GitStageDiffAction -class GitStageEditorDiffPreview(diffProcessor: GitStageDiffPreview, private val tree: ChangesTree) : EditorTabPreview(diffProcessor) { - private val changeViewProcessor: ChangeViewDiffRequestProcessor get() = diffProcessor as ChangeViewDiffRequestProcessor +class GitStageEditorDiffPreview( + private val changeViewProcessor: GitStageDiffPreview, + private val tree: ChangesTree +) : EditorTabPreview(changeViewProcessor) { override fun hasContent(): Boolean { return changeViewProcessor.currentChange != null } - override fun updateAvailability(event: AnActionEvent) { + override fun updateDiffAction(event: AnActionEvent) { GitStageDiffAction.updateAvailability(event) } @@ -32,7 +33,7 @@ class GitStageEditorDiffPreview(diffProcessor: GitStageDiffPreview, private val internal fun processDoubleClickOrEnter(isDoubleClick: Boolean): Boolean { val isPreviewAllowed = if (isDoubleClick) isPreviewOnDoubleClickAllowed() else isPreviewOnEnterAllowed() - return isPreviewAllowed && openPreview(isDoubleClick) + return isPreviewAllowed && performDiffAction() } override fun isPreviewOnDoubleClickAllowed(): Boolean = VcsApplicationSettings.getInstance().SHOW_EDITOR_PREVIEW_ON_DOUBLE_CLICK diff --git a/plugins/git4idea/src/git4idea/index/ui/GitStageTree.kt b/plugins/git4idea/src/git4idea/index/ui/GitStageTree.kt index 34c65e2fb82c..ea5ae53812ff 100644 --- a/plugins/git4idea/src/git4idea/index/ui/GitStageTree.kt +++ b/plugins/git4idea/src/git4idea/index/ui/GitStageTree.kt @@ -128,6 +128,7 @@ abstract class GitStageTree(project: Project, val entries = VcsTreeModelData.selected(this).userObjects(GitFileStatusNode::class.java) if (entries.size > 1) { return ListSelection.createAt(entries, 0) + .asExplicitSelection() } val selected = entries.singleOrNull() @@ -148,6 +149,7 @@ abstract class GitStageTree(project: Project, val allEntries = allEntriesData.userObjects(GitFileStatusNode::class.java) return if (allEntries.size <= entries.size) { ListSelection.createAt(entries, 0) + .asExplicitSelection() } else { ListSelection.create(allEntries, selected) diff --git a/plugins/github/src/org/jetbrains/plugins/github/pullrequest/ui/toolwindow/GHPRViewComponentFactory.kt b/plugins/github/src/org/jetbrains/plugins/github/pullrequest/ui/toolwindow/GHPRViewComponentFactory.kt index 511d65648f41..c4863f3adbc6 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/pullrequest/ui/toolwindow/GHPRViewComponentFactory.kt +++ b/plugins/github/src/org/jetbrains/plugins/github/pullrequest/ui/toolwindow/GHPRViewComponentFactory.kt @@ -389,25 +389,27 @@ internal class GHPRViewComponentFactory(private val actionManager: ActionManager getCustomData: ChangesTree.(String) -> Any? = { null } ): JComponent { val editorDiffPreview = object : DiffPreview { - override fun updateAvailability(event: AnActionEvent) { + override fun updateDiffAction(event: AnActionEvent) { GHPRShowDiffActionProvider.updateAvailability(event) } - override fun setPreviewVisible(isPreviewVisible: Boolean, focus: Boolean) { - if (isPreviewVisible) { - viewController.openPullRequestDiff(dataProvider.id, focus) - } + override fun openPreview(requestFocus: Boolean): Boolean { + viewController.openPullRequestDiff(dataProvider.id, requestFocus) + return true + } + + override fun closePreview() { } } val tree = GHPRChangesTreeFactory(project, model).create(emptyTextText).also { it.doubleClickHandler = Processor { e -> if (EditSourceOnDoubleClickHandler.isToggleEvent(it, e)) return@Processor false - editorDiffPreview.setPreviewVisible(true, true) + editorDiffPreview.performDiffAction() true } it.enterKeyHandler = Processor { - editorDiffPreview.setPreviewVisible(true, true) + editorDiffPreview.performDiffAction() true } } diff --git a/plugins/github/src/org/jetbrains/plugins/github/pullrequest/ui/toolwindow/create/GHPRCreateComponentHolder.kt b/plugins/github/src/org/jetbrains/plugins/github/pullrequest/ui/toolwindow/create/GHPRCreateComponentHolder.kt index a52a1c43f8bd..bc1859c2daff 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/pullrequest/ui/toolwindow/create/GHPRCreateComponentHolder.kt +++ b/plugins/github/src/org/jetbrains/plugins/github/pullrequest/ui/toolwindow/create/GHPRCreateComponentHolder.kt @@ -367,7 +367,7 @@ internal class GHPRCreateComponentHolder(private val actionManager: ActionManage ChangeDiffRequestProducer.create(project, it, requestDataKeys) } - return ChangeDiffRequestChain(producers.list, producers.selectedIndex) + return ChangeDiffRequestChain(producers) } } }
\ No newline at end of file diff --git a/plugins/gradle/gradle-dependency-updater/intellij.gradle.dependencyUpdater.iml b/plugins/gradle/gradle-dependency-updater/intellij.gradle.dependencyUpdater.iml index 70a609a7605e..8cd4db3f5070 100644 --- a/plugins/gradle/gradle-dependency-updater/intellij.gradle.dependencyUpdater.iml +++ b/plugins/gradle/gradle-dependency-updater/intellij.gradle.dependencyUpdater.iml @@ -12,7 +12,7 @@ <orderEntry type="module" module-name="intellij.gradle.common" /> <orderEntry type="module" module-name="intellij.platform.lang" /> <orderEntry type="module" module-name="intellij.platform.lang.impl" /> - <orderEntry type="module" module-name="intellij.externalSystem.dependencyUpdater" /> + <orderEntry type="module" module-name="intellij.platform.externalSystem.dependencyUpdater" /> <orderEntry type="module" module-name="intellij.android.gradle.dsl" /> <orderEntry type="module" module-name="intellij.platform.core.ui" /> </component> diff --git a/plugins/gradle/gradle-dependency-updater/resources/META-INF/plugin.xml b/plugins/gradle/gradle-dependency-updater/resources/META-INF/plugin.xml index d71aad48d9ad..7fd56727317f 100644 --- a/plugins/gradle/gradle-dependency-updater/resources/META-INF/plugin.xml +++ b/plugins/gradle/gradle-dependency-updater/resources/META-INF/plugin.xml @@ -7,7 +7,6 @@ <vendor>JetBrains</vendor> <depends>com.intellij.gradle</depends> - <depends>com.intellij.externalSystem.dependencyUpdater</depends> <depends>org.jetbrains.idea.gradle.dsl</depends> <extensions defaultExtensionNs="com.intellij"> <externalSystem.dependencyModifier implementation="org.jetbrains.plugins.gradle.dsl.GradleDependencyModificator"/> diff --git a/plugins/gradle/intellij.gradle.common.iml b/plugins/gradle/intellij.gradle.common.iml index 28214321b941..6fa241db7e2d 100644 --- a/plugins/gradle/intellij.gradle.common.iml +++ b/plugins/gradle/intellij.gradle.common.iml @@ -36,6 +36,6 @@ <orderEntry type="module" module-name="intellij.platform.ide.util.io" /> <orderEntry type="module" module-name="intellij.gradle.toolingProxy" /> <orderEntry type="library" name="Velocity" level="project" /> - <orderEntry type="module" module-name="intellij.externalSystem.dependencyUpdater" /> + <orderEntry type="module" module-name="intellij.platform.externalSystem.dependencyUpdater" /> </component> </module>
\ No newline at end of file diff --git a/plugins/gradle/java/src/execution/build/TasksExecutionSettingsBuilder.java b/plugins/gradle/java/src/execution/build/TasksExecutionSettingsBuilder.java index bbeea4091acf..2afd89a4caaa 100644 --- a/plugins/gradle/java/src/execution/build/TasksExecutionSettingsBuilder.java +++ b/plugins/gradle/java/src/execution/build/TasksExecutionSettingsBuilder.java @@ -167,6 +167,11 @@ public class TasksExecutionSettingsBuilder { if (!moduleBuildTask.isIncrementalBuild() && !(moduleBuildTask instanceof ModuleFilesBuildTask)) { projectInitScripts.add(String.format(FORCE_COMPILE_TASKS_INIT_SCRIPT_TEMPLATE, gradlePath)); } + if (moduleBuildTask.isIncludeRuntimeDependencies()) { + // if runtime deps are required, force Gradle to process all resources + projectInitScripts.add("System.setProperty('org.gradle.java.compile-classpath-packaging', 'true')\n"); + } + String assembleTask = "assemble"; boolean buildOnlyResources = projectTask instanceof ModuleResourcesBuildTask; String buildTaskPrefix = buildOnlyResources ? "process" : ""; diff --git a/plugins/gradle/java/src/execution/test/runner/events/BeforeSuiteEvent.java b/plugins/gradle/java/src/execution/test/runner/events/BeforeSuiteEvent.java index 8bce0c30950a..39ee4d52bd91 100644 --- a/plugins/gradle/java/src/execution/test/runner/events/BeforeSuiteEvent.java +++ b/plugins/gradle/java/src/execution/test/runner/events/BeforeSuiteEvent.java @@ -28,7 +28,7 @@ public class BeforeSuiteEvent extends AbstractTestEvent { public void process(@NotNull final TestEventXmlView eventXml) throws TestEventXmlView.XmlParserException { final String testId = eventXml.getTestId(); final String parentTestId = eventXml.getTestParentId(); - final String name = eventXml.getTestName(); + final String name = eventXml.getTestDisplayName(); final String fqClassName = eventXml.getTestClassName(); doProcess(testId, parentTestId, name, fqClassName); diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/execution/GradleProgressListener.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/execution/GradleProgressListener.java index 81b95001bc28..8366710aea29 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/execution/GradleProgressListener.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/execution/GradleProgressListener.java @@ -13,7 +13,6 @@ import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotifica import com.intellij.openapi.externalSystem.model.task.event.TestOperationDescriptor; import com.intellij.openapi.externalSystem.model.task.event.*; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Couple; import com.intellij.openapi.util.NlsSafe; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; @@ -36,6 +35,7 @@ import java.util.HashMap; import java.util.Map; import java.util.UUID; +import static com.intellij.openapi.util.text.StringUtil.formatDuration; import static com.intellij.openapi.util.text.StringUtil.formatFileSize; import static org.jetbrains.plugins.gradle.tooling.internal.ExtraModelBuilder.MODEL_BUILDER_SERVICE_MESSAGE_PREFIX; @@ -48,7 +48,7 @@ public class GradleProgressListener implements ProgressListener, org.gradle.tool private final ExternalSystemTaskNotificationListener myListener; private final ExternalSystemTaskId myTaskId; private final Map<Object, Long> myStatusEventIds = new HashMap<>(); - private final Map<Object, Couple<Long>> myDownloadStatusEventIds = new HashMap<>(); + private final Map<Object, StatusEvent> myDownloadStatusEventIds = new HashMap<>(); private final String myOperationId; private static final String STARTING_GRADLE_DAEMON_EVENT = "Starting Gradle Daemon"; private ExternalSystemTaskNotificationEvent myLastStatusChange = null; @@ -236,42 +236,35 @@ public class GradleProgressListener implements ProgressListener, org.gradle.tool if (progressEvent instanceof StatusEvent) { StatusEvent statusEvent = ((StatusEvent)progressEvent); if ("bytes".equals(statusEvent.getUnit())) { - Couple<Long> oldProgress = myDownloadStatusEventIds.get(operationName); - if (oldProgress == null) { - String totalSizeInfo = statusEvent.getTotal() > 0 ? (" (" + formatFileSize(statusEvent.getTotal()) + ")") : ""; - myListener.onTaskOutput(myTaskId, operationName + totalSizeInfo, true); - myDownloadStatusEventIds.put(operationName, Couple.of(statusEvent.getTotal(), statusEvent.getProgress())); - } - else { - if (!oldProgress.second.equals(statusEvent.getProgress())) { - myDownloadStatusEventIds.put(operationName, Couple.of(statusEvent.getTotal(), statusEvent.getProgress())); - if (statusEvent.getTotal() > 0) { - String sizeInfo = " (" + formatFileSize(statusEvent.getProgress()) + "/ " + formatFileSize(statusEvent.getTotal()) + ")"; - myListener.onTaskOutput(myTaskId, "\r" + operationName + sizeInfo, true); - } - else { - myListener.onTaskOutput(myTaskId, formatFileSize(statusEvent.getProgress()) + "\n", true); - } + StatusEvent oldStatusEvent = myDownloadStatusEventIds.get(operationName); + myDownloadStatusEventIds.put(operationName, statusEvent); + if (oldStatusEvent == null || oldStatusEvent.getProgress() != statusEvent.getProgress()) { + long progress = statusEvent.getProgress() > 0 ? statusEvent.getProgress() : 0; + long total = statusEvent.getTotal() > 0 ? statusEvent.getTotal() : 0; + String text = String.format("%s (%s / %s)", operationName, formatFileSize(progress), formatFileSize(total)); + if (oldStatusEvent == null) { + myListener.onTaskOutput(myTaskId, text, true); + } + else { + myListener.onTaskOutput(myTaskId, "\r" + text, true); } } } } - else { - if (progressEvent instanceof FinishEvent) { - FinishEvent finishEvent = (FinishEvent)progressEvent; - Couple<Long> currentProgress = myDownloadStatusEventIds.remove(operationName); - if (currentProgress != null) { - OperationResult operationResult = finishEvent.getResult(); - String duration = StringUtil.formatDuration(operationResult.getEndTime() - operationResult.getStartTime()); - String text = - String.format("\r%s, took %s (%s)\n", finishEvent.getDisplayName(), duration, formatFileSize(currentProgress.first)); - myListener.onTaskOutput(myTaskId, text, true); - if (!currentProgress.first.equals(currentProgress.second)) { - ProgressBuildEventImpl progressBuildEvent = - new ProgressBuildEventImpl(myTaskId, myTaskId, System.currentTimeMillis(), operationName, currentProgress.first, - currentProgress.first, "bytes"); - myListener.onStatusChange(new ExternalSystemBuildEvent(myTaskId, progressBuildEvent)); - } + else if (progressEvent instanceof FinishEvent) { + FinishEvent finishEvent = (FinishEvent)progressEvent; + StatusEvent statusEvent = myDownloadStatusEventIds.remove(operationName); + if (statusEvent != null) { + OperationResult operationResult = finishEvent.getResult(); + long duration = operationResult.getEndTime() - operationResult.getStartTime(); + long progress = statusEvent.getProgress() > 0 ? statusEvent.getProgress() : 0; + long total = statusEvent.getTotal() > 0 ? statusEvent.getTotal() : 0; + String text = String.format("%s, took %s (%s)", operationName, formatDuration(duration), formatFileSize(total)); + myListener.onTaskOutput(myTaskId, "\r" + text + "\n", true); + if (total != progress) { + ProgressBuildEventImpl progressBuildEvent = + new ProgressBuildEventImpl(myTaskId, myTaskId, System.currentTimeMillis(), operationName, total, progress, "bytes"); + myListener.onStatusChange(new ExternalSystemBuildEvent(myTaskId, progressBuildEvent)); } } } @@ -286,7 +279,7 @@ public class GradleProgressListener implements ProgressListener, org.gradle.tool myStatusEventIds.put(eventDescription, eventTime); } else { - String duration = StringUtil.formatDuration(eventTime - startTime); + String duration = formatDuration(eventTime - startTime); myListener.onTaskOutput(myTaskId, "\rGradle Daemon started in " + duration + "\n", true); } } diff --git a/plugins/grazie/java/src/main/kotlin/com/intellij/grazie/ide/language/java/JavaTextExtractor.java b/plugins/grazie/java/src/main/kotlin/com/intellij/grazie/ide/language/java/JavaTextExtractor.java index 9ab5bbf8a430..ffeb6c7c6fc8 100644 --- a/plugins/grazie/java/src/main/kotlin/com/intellij/grazie/ide/language/java/JavaTextExtractor.java +++ b/plugins/grazie/java/src/main/kotlin/com/intellij/grazie/ide/language/java/JavaTextExtractor.java @@ -28,10 +28,11 @@ import static com.intellij.grazie.text.TextContent.TextDomain.*; import static com.intellij.psi.JavaDocTokenType.*; import static com.intellij.psi.impl.source.tree.ElementType.JAVA_PLAIN_COMMENT_BIT_SET; import static com.intellij.psi.impl.source.tree.JavaDocElementType.DOC_PARAMETER_REF; +import static com.intellij.psi.impl.source.tree.JavaDocElementType.DOC_REFERENCE_HOLDER; public class JavaTextExtractor extends TextExtractor { private static final TokenSet EXCLUDED = - TokenSet.create(DOC_COMMENT_START, DOC_COMMENT_LEADING_ASTERISKS, DOC_COMMENT_END, DOC_PARAMETER_REF); + TokenSet.create(DOC_COMMENT_START, DOC_COMMENT_LEADING_ASTERISKS, DOC_COMMENT_END, DOC_PARAMETER_REF, DOC_REFERENCE_HOLDER); private static final TextContentBuilder javadocBuilder = TextContentBuilder.FromPsi .withUnknown(e -> e instanceof PsiInlineDocTag && !(e instanceof PsiSnippetDocTag)) .excluding(e -> EXCLUDED.contains(PsiUtilCore.getElementType(e))) diff --git a/plugins/grazie/markdown/src/main/kotlin/com/intellij/grazie/ide/language/markdown/MarkdownTextExtractor.kt b/plugins/grazie/markdown/src/main/kotlin/com/intellij/grazie/ide/language/markdown/MarkdownTextExtractor.kt index 27d20cc959c8..fdbc5e017959 100644 --- a/plugins/grazie/markdown/src/main/kotlin/com/intellij/grazie/ide/language/markdown/MarkdownTextExtractor.kt +++ b/plugins/grazie/markdown/src/main/kotlin/com/intellij/grazie/ide/language/markdown/MarkdownTextExtractor.kt @@ -5,6 +5,7 @@ import com.intellij.grazie.ide.language.markdown.MarkdownPsiUtils.isMarkdownLink import com.intellij.grazie.text.TextContent import com.intellij.grazie.text.TextContentBuilder import com.intellij.grazie.text.TextExtractor +import com.intellij.grazie.utils.nbspToSpace import com.intellij.psi.PsiElement import com.intellij.psi.PsiWhiteSpace import com.intellij.psi.util.elementType @@ -18,14 +19,14 @@ class MarkdownTextExtractor : TextExtractor() { public override fun buildTextContent(root: PsiElement, allowedDomains: Set<TextContent.TextDomain>): TextContent? { if (allowedDomains.contains(TextContent.TextDomain.PLAIN_TEXT) && (MarkdownPsiUtils.isHeaderContent(root) || MarkdownPsiUtils.isParagraph(root))) { - return TextContentBuilder.FromPsi + return nbspToSpace(TextContentBuilder.FromPsi .withUnknown { it.node.isMarkdownCodeType() } .excluding { e -> e.elementType in toExclude || e.firstChild == null && e.parent.node.isMarkdownLinkType() && !isLinkText(e) } .removingIndents(" \t").removingLineSuffixes(" \t") - .build(root, TextContent.TextDomain.PLAIN_TEXT) + .build(root, TextContent.TextDomain.PLAIN_TEXT)) } return null } diff --git a/plugins/grazie/src/intellij.grazie.core.iml b/plugins/grazie/src/intellij.grazie.core.iml index 7490a67f3dc2..3caae3829b49 100644 --- a/plugins/grazie/src/intellij.grazie.core.iml +++ b/plugins/grazie/src/intellij.grazie.core.iml @@ -48,37 +48,37 @@ <orderEntry type="library" name="swingx" level="project" /> <orderEntry type="module-library"> <library name="ai.grazie:nlp-detector" type="repository"> - <properties include-transitive-deps="false" maven-id="ai.grazie:nlp-detector-jvm:0.0.2" /> + <properties include-transitive-deps="false" maven-id="ai.grazie:nlp-detector-jvm:0.0.5" /> <CLASSES> - <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/nlp-detector-jvm/0.0.2/nlp-detector-jvm-0.0.2.jar!/" /> + <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/nlp-detector-jvm/0.0.5/nlp-detector-jvm-0.0.5.jar!/" /> </CLASSES> <JAVADOC /> <SOURCES> - <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/nlp-detector-jvm/0.0.2/nlp-detector-jvm-0.0.2-sources.jar!/" /> + <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/nlp-detector-jvm/0.0.5/nlp-detector-jvm-0.0.5-sources.jar!/" /> </SOURCES> </library> </orderEntry> <orderEntry type="module-library"> <library name="ai.grazie.nlp:nlp-common" type="repository"> - <properties include-transitive-deps="false" maven-id="ai.grazie.nlp:nlp-common:0.1.50" /> + <properties include-transitive-deps="false" maven-id="ai.grazie.nlp:nlp-common:0.1.50-1" /> <CLASSES> - <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/nlp/nlp-common/0.1.50/nlp-common-0.1.50.jar!/" /> + <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/nlp/nlp-common/0.1.50-1/nlp-common-0.1.50-1.jar!/" /> </CLASSES> <JAVADOC /> <SOURCES> - <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/nlp/nlp-common/0.1.50/nlp-common-0.1.50-sources.jar!/" /> + <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/nlp/nlp-common/0.1.50-1/nlp-common-0.1.50-1-sources.jar!/" /> </SOURCES> </library> </orderEntry> <orderEntry type="module-library"> <library name="ai.grazie.nlp:nlp-tokenizer" type="repository"> - <properties include-transitive-deps="false" maven-id="ai.grazie.nlp:nlp-tokenizer:0.1.50" /> + <properties include-transitive-deps="false" maven-id="ai.grazie.nlp:nlp-tokenizer:0.1.50-1" /> <CLASSES> - <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/nlp/nlp-tokenizer/0.1.50/nlp-tokenizer-0.1.50.jar!/" /> + <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/nlp/nlp-tokenizer/0.1.50-1/nlp-tokenizer-0.1.50-1.jar!/" /> </CLASSES> <JAVADOC /> <SOURCES> - <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/nlp/nlp-tokenizer/0.1.50/nlp-tokenizer-0.1.50-sources.jar!/" /> + <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/nlp/nlp-tokenizer/0.1.50-1/nlp-tokenizer-0.1.50-1-sources.jar!/" /> </SOURCES> </library> </orderEntry> @@ -263,25 +263,25 @@ <orderEntry type="library" name="lucene-analyzers-common" level="project" /> <orderEntry type="module-library"> <library name="ai.grazie.utils:utils-common" type="repository"> - <properties include-transitive-deps="false" maven-id="ai.grazie.utils:utils-common:0.1.50" /> + <properties include-transitive-deps="false" maven-id="ai.grazie.utils:utils-common:0.1.50-1" /> <CLASSES> - <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/utils/utils-common/0.1.50/utils-common-0.1.50.jar!/" /> + <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/utils/utils-common/0.1.50-1/utils-common-0.1.50-1.jar!/" /> </CLASSES> <JAVADOC /> <SOURCES> - <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/utils/utils-common/0.1.50/utils-common-0.1.50-sources.jar!/" /> + <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/utils/utils-common/0.1.50-1/utils-common-0.1.50-1-sources.jar!/" /> </SOURCES> </library> </orderEntry> <orderEntry type="module-library"> <library name="ai.grazie.spell:gec-spell-local-engine" type="repository"> - <properties include-transitive-deps="false" maven-id="ai.grazie.spell:gec-spell-local-engine:0.1.50" /> + <properties include-transitive-deps="false" maven-id="ai.grazie.spell:gec-spell-local-engine:0.1.50-1" /> <CLASSES> - <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/spell/gec-spell-local-engine/0.1.50/gec-spell-local-engine-0.1.50.jar!/" /> + <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/spell/gec-spell-local-engine/0.1.50-1/gec-spell-local-engine-0.1.50-1.jar!/" /> </CLASSES> <JAVADOC /> <SOURCES> - <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/spell/gec-spell-local-engine/0.1.50/gec-spell-local-engine-0.1.50-sources.jar!/" /> + <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/spell/gec-spell-local-engine/0.1.50-1/gec-spell-local-engine-0.1.50-1-sources.jar!/" /> </SOURCES> </library> </orderEntry> diff --git a/plugins/grazie/src/main/kotlin/com/intellij/grazie/text/CommentProblemFilter.kt b/plugins/grazie/src/main/kotlin/com/intellij/grazie/text/CommentProblemFilter.kt index ebc35ac3ae92..00c89d5dc69b 100644 --- a/plugins/grazie/src/main/kotlin/com/intellij/grazie/text/CommentProblemFilter.kt +++ b/plugins/grazie/src/main/kotlin/com/intellij/grazie/text/CommentProblemFilter.kt @@ -20,10 +20,9 @@ internal class CommentProblemFilter : ProblemFilter() { if (problem.rule.globalId.startsWith("LanguageTool.") && isAboutIdentifierParts(problem, text)) { return true } - } - - if (domain == DOCUMENTATION) { - return isInFirstSentence(problem) && problem.fitsGroup(RuleGroup(RuleGroup.INCOMPLETE_SENTENCE)) + if (isInFirstSentence(problem) && problem.fitsGroup(RuleGroup(RuleGroup.INCOMPLETE_SENTENCE))) { + return true + } } if (domain == COMMENTS) { diff --git a/plugins/grazie/src/main/kotlin/com/intellij/grazie/text/TextContent.java b/plugins/grazie/src/main/kotlin/com/intellij/grazie/text/TextContent.java index 6978f1faba6a..7518cb30635d 100644 --- a/plugins/grazie/src/main/kotlin/com/intellij/grazie/text/TextContent.java +++ b/plugins/grazie/src/main/kotlin/com/intellij/grazie/text/TextContent.java @@ -117,6 +117,14 @@ public interface TextContent extends CharSequence, UserDataHolderEx { TextContent excludeRanges(List<Exclusion> ranges); /** + * @return the part of this text inside the corresponding range, or {@code null} if the result is empty + */ + default @Nullable TextContent subText(TextRange range) { + if (range.isEmpty()) return null; + return excludeRange(new TextRange(range.getEndOffset(), length())).excludeRange(new TextRange(0, range.getStartOffset())); + } + + /** * @return whether the given PSI file text range has non-empty intersection with any fragment covered by this text content. */ @Contract(pure = true) diff --git a/plugins/grazie/src/main/kotlin/com/intellij/grazie/utils/HtmlUtils.kt b/plugins/grazie/src/main/kotlin/com/intellij/grazie/utils/HtmlUtils.kt index beaec52c3cac..56975b156746 100644 --- a/plugins/grazie/src/main/kotlin/com/intellij/grazie/utils/HtmlUtils.kt +++ b/plugins/grazie/src/main/kotlin/com/intellij/grazie/utils/HtmlUtils.kt @@ -70,3 +70,21 @@ fun removeHtml(_content: TextContent?): TextContent? { } return content.excludeRanges(exclusions) } + +private val nbsp = Pattern.compile(" ") + +fun nbspToSpace(content: TextContent?): TextContent? { + if (content == null) return null + + val spaces = Text.allOccurrences(nbsp, content) + if (spaces.isEmpty()) return content.trimWhitespace() + + val components = arrayListOf<TextContent?>() + for (i in spaces.indices) { + val prevEnd = if (i == 0) 0 else spaces[i - 1].endOffset + components.add(content.subText(TextRange(prevEnd, spaces[i].startOffset))?.trimWhitespace()) + } + components.add(content.subText(TextRange(spaces.last().endOffset, content.length))?.trimWhitespace()) + return TextContent.joinWithWhitespace(' ', components.filterNotNull()) +} + diff --git a/plugins/grazie/src/test/intellij.grazie.tests.iml b/plugins/grazie/src/test/intellij.grazie.tests.iml index c5761ad9509d..95fe42fed1f1 100644 --- a/plugins/grazie/src/test/intellij.grazie.tests.iml +++ b/plugins/grazie/src/test/intellij.grazie.tests.iml @@ -55,5 +55,6 @@ <orderEntry type="module" module-name="intellij.grazie.java" scope="TEST" /> <orderEntry type="module" module-name="intellij.markdown" scope="TEST" /> <orderEntry type="library" scope="TEST" name="kotlinx-coroutines-jdk8" level="project" /> + <orderEntry type="module" module-name="intellij.grazie.markdown" scope="TEST" /> </component> </module>
\ No newline at end of file diff --git a/plugins/grazie/src/test/kotlin/com/intellij/grazie/text/TextExtractionTest.java b/plugins/grazie/src/test/kotlin/com/intellij/grazie/text/TextExtractionTest.java index 29b452d18bc4..242e48583228 100644 --- a/plugins/grazie/src/test/kotlin/com/intellij/grazie/text/TextExtractionTest.java +++ b/plugins/grazie/src/test/kotlin/com/intellij/grazie/text/TextExtractionTest.java @@ -1,6 +1,7 @@ package com.intellij.grazie.text; import com.intellij.grazie.ide.language.java.JavaTextExtractor; +import com.intellij.grazie.ide.language.markdown.MarkdownTextExtractor; import com.intellij.ide.highlighter.JavaFileType; import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.lang.injection.MultiHostInjector; @@ -62,6 +63,10 @@ public class TextExtractionTest extends BasePlatformTestCase { assertEquals("bold italic strikethrough", unknownOffsets(extractText("a.md", "**bold** *italic* ~~strikethrough~~", 3))); } + public void testHtmlNbsp() { + assertEquals("hello world", unknownOffsets(extractText("a.md", "hello world", 3))); + assertEquals("hello world", unknownOffsets(extractText("a.html", "hello world", 3))); + } public void testMarkdownInlineCode() { TextContent extracted = extractText("a.md", "you can use a number of predefined fields (e.g. `EventFields.InputEvent`)", 0); assertEquals("you can use a number of predefined fields (e.g. |)", unknownOffsets(extracted)); @@ -119,6 +124,7 @@ public class TextExtractionTest extends BasePlatformTestCase { "* {@link #unknown} is unknown.\n" + "* @param foo the text without the parameter name\n" + "* @return the offset of {@link #bar} in something\n" + + "* @throws Exception when something happens\n" + " */"; TextContent text = extractText("a.java", docText, 6); assertEquals("Hello |,\nhere's an asterisk: *\nand some |.\ntags1 |\ntags2 |\n|is unknown.", unknownOffsets(text)); @@ -128,6 +134,9 @@ public class TextExtractionTest extends BasePlatformTestCase { text = extractText("a.java", docText, docText.indexOf("without")); assertEquals("the text without the parameter name", text.toString()); + + text = extractText("a.java", docText, docText.indexOf("when something")); + assertEquals("when something happens", text.toString()); } public void testJavaLiteral() { @@ -270,6 +279,17 @@ public class TextExtractionTest extends BasePlatformTestCase { }).assertTiming(); } + public void testBuildingPerformance_removingNbsp() { + String text = "b ".repeat(10_000); + String expected = "b ".repeat(10_000).trim(); + PsiFile file = myFixture.configureByText("a.md", text); + var psi = PsiTreeUtil.findElementOfClassAtOffset(file, 10, MarkdownParagraph.class, false); + TextExtractor extractor = new MarkdownTextExtractor(); + PlatformTestUtil.startPerformanceTest("TextContent building with nbsp removal", 200, () -> { + assertEquals(expected, extractor.buildTextContent(psi, TextContent.TextDomain.ALL).toString()); + }).assertTiming(); + } + public void testBuildingPerformance_longTextFragment() { String line = "here's some relative long text that helps make this text fragment a bit longer than it could have been otherwise"; String text = ("\n\n\n" + line).repeat(10_000); diff --git a/plugins/grazie/src/test/testData/ide/language/java/Comments.java b/plugins/grazie/src/test/testData/ide/language/java/Comments.java index 48d59f8ef5bf..4a110f67abe4 100644 --- a/plugins/grazie/src/test/testData/ide/language/java/Comments.java +++ b/plugins/grazie/src/test/testData/ide/language/java/Comments.java @@ -58,4 +58,9 @@ class ForMultiLanguageSupport { // value between hours and minutes (":" is used by default) // Copyright refers to <warning descr="EN_A_VS_AN">an</warning> legal right bla-bla-bla, and we check for errors here. + + // Returns details about the current user + int foo() { + return 1; + } } diff --git a/plugins/grazie/src/test/testData/ide/language/java/Docs.java b/plugins/grazie/src/test/testData/ide/language/java/Docs.java index 55bdb9a07df8..f07807dd167e 100644 --- a/plugins/grazie/src/test/testData/ide/language/java/Docs.java +++ b/plugins/grazie/src/test/testData/ide/language/java/Docs.java @@ -92,4 +92,11 @@ class ForMultiLanguageSupport { // er überprüfte die Rechnungen noch <TYPO descr="Typo: In word 'einal'">einal</TYPO>, um ganz <warning descr="COMPOUND_INFINITIV_RULE">sicher zu gehen</warning>. // das ist <warning descr="FUEHR_FUER">führ</warning> Dich! // das <TYPO descr="Typo: In word 'daert'">daert</TYPO> geschätzt fünf <warning descr="MANNSTUNDE">Mannstunden</warning>. + + /** + * @throws Exception wenn ein Fehler auftritt + */ + public static void main(String[] args) throws Exception { + throw new Exception("Hello World"); + } } diff --git a/plugins/grazie/src/test/testData/ide/language/markdown/Example.md b/plugins/grazie/src/test/testData/ide/language/markdown/Example.md index 8842e26cb6bd..5210fc136a5f 100644 --- a/plugins/grazie/src/test/testData/ide/language/markdown/Example.md +++ b/plugins/grazie/src/test/testData/ide/language/markdown/Example.md @@ -41,6 +41,8 @@ val b = "It is friend." Собрание состоится в <warning descr="RU_COMPOUNDS">конференц зале</warning>. <warning descr="WORD_REPEAT_RULE">Он он</warning> ошибка. +Я предлагаю в своём приложении создавать что-нибудь. + Er überprüfte die Rechnungen noch <TYPO descr="Typo: In word 'einal'">einal</TYPO>, um ganz <warning descr="COMPOUND_INFINITIV_RULE">sicher zu gehen</warning>. das ist <warning descr="FUEHR_FUER">führ</warning> Dich! das <TYPO descr="Typo: In word 'daert'">daert</TYPO> geschätzt fünf <warning descr="MANNSTUNDE">Mannstunden</warning>. diff --git a/plugins/grazie/src/test/testData/ide/language/xml/Example.html b/plugins/grazie/src/test/testData/ide/language/xml/Example.html index 0fc9e6df475b..c4ecced40a30 100644 --- a/plugins/grazie/src/test/testData/ide/language/xml/Example.html +++ b/plugins/grazie/src/test/testData/ide/language/xml/Example.html @@ -24,6 +24,8 @@ actually return values. За весь вечер она <warning descr="ne_proronila_ni">не проронила и слово</warning>. Собрание состоится в <warning descr="RU_COMPOUNDS">конференц зале</warning>. <warning descr="WORD_REPEAT_RULE">Он он</warning> ошибка. + + Я предлагаю в своём приложении создавать что-нибудь. </p> <p> Er überprüfte die Rechnungen noch <TYPO descr="Typo: In word 'einal'">einal</TYPO>, um ganz <warning descr="COMPOUND_INFINITIV_RULE">sicher zu gehen</warning>. diff --git a/plugins/grazie/xml/main/kotlin/com/intellij/grazie/ide/language/xml/XmlTextExtractor.java b/plugins/grazie/xml/main/kotlin/com/intellij/grazie/ide/language/xml/XmlTextExtractor.java index 9878510f2c38..20312118d8d0 100644 --- a/plugins/grazie/xml/main/kotlin/com/intellij/grazie/ide/language/xml/XmlTextExtractor.java +++ b/plugins/grazie/xml/main/kotlin/com/intellij/grazie/ide/language/xml/XmlTextExtractor.java @@ -4,6 +4,7 @@ import com.intellij.application.options.CodeStyle; import com.intellij.grazie.text.TextContent; import com.intellij.grazie.text.TextContentBuilder; import com.intellij.grazie.text.TextExtractor; +import com.intellij.grazie.utils.HtmlUtilsKt; import com.intellij.lang.Language; import com.intellij.lang.dtd.DTDLanguage; import com.intellij.lang.html.HTMLLanguage; @@ -118,7 +119,7 @@ public class XmlTextExtractor extends TextExtractor { if (content != null) { if (unknownBefore) content = content.markUnknown(TextRange.from(0, 0)); if (unknownAfter) content = content.markUnknown(TextRange.from(content.length(), 0)); - content = content.removeIndents(Set.of(' ', '\t')).trimWhitespace(); + content = HtmlUtilsKt.nbspToSpace(content.removeIndents(Set.of(' ', '\t'))); if (content != null) { for (PsiElement e : group) { result.put(e, content); diff --git a/plugins/ide-features-trainer/src/training/actions/DumpFeaturesTrainerText.kt b/plugins/ide-features-trainer/src/training/actions/DumpFeaturesTrainerText.kt index ee2cc0b3c63e..9f83cd15b8f2 100644 --- a/plugins/ide-features-trainer/src/training/actions/DumpFeaturesTrainerText.kt +++ b/plugins/ide-features-trainer/src/training/actions/DumpFeaturesTrainerText.kt @@ -52,7 +52,7 @@ private class DumpFeaturesTrainerText : DumbAwareAction() { if (x is KLesson) { buffer.append(x.name) buffer.append(":\n") - x.lessonContent(ApplyTaskLessonContext(buffer, project, dialog.mode, x)) + x.fullLessonContent(ApplyTaskLessonContext(buffer, project, dialog.mode, x)) buffer.append('\n') } } diff --git a/plugins/ide-features-trainer/src/training/dsl/LessonContext.kt b/plugins/ide-features-trainer/src/training/dsl/LessonContext.kt index 0a13972feecb..d06e3d4d393e 100644 --- a/plugins/ide-features-trainer/src/training/dsl/LessonContext.kt +++ b/plugins/ide-features-trainer/src/training/dsl/LessonContext.kt @@ -75,6 +75,7 @@ abstract class LessonContext : LearningDslBase { caret(position) } + @JvmOverloads open fun prepareSample(sample: LessonSample, checkSdkConfiguration: Boolean = true) { prepareRuntimeTask { setSample(sample) } diff --git a/plugins/ide-features-trainer/src/training/dsl/impl/LessonExecutor.kt b/plugins/ide-features-trainer/src/training/dsl/impl/LessonExecutor.kt index 346a90e205a8..d3e863077db1 100644 --- a/plugins/ide-features-trainer/src/training/dsl/impl/LessonExecutor.kt +++ b/plugins/ide-features-trainer/src/training/dsl/impl/LessonExecutor.kt @@ -11,7 +11,6 @@ import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.LogicalPosition import com.intellij.openapi.fileEditor.FileDocumentManager import com.intellij.openapi.fileEditor.FileEditorManager -import com.intellij.openapi.project.DumbService import com.intellij.openapi.project.Project import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.Ref @@ -174,15 +173,7 @@ internal class LessonExecutor(val lesson: KLesson, fun startLesson() { addAllInactiveMessages() - if (lesson.properties.canStartInDumbMode) { - processNextTask(0) - } - else { - DumbService.getInstance(project).runWhenSmart { - if (!hasBeenStopped) - processNextTask(0) - } - } + processNextTask(0) } inline fun invokeInBackground(crossinline runnable: () -> Unit) { diff --git a/plugins/ide-features-trainer/src/training/lang/LangSupport.kt b/plugins/ide-features-trainer/src/training/lang/LangSupport.kt index 12c00e0878ce..aea40a038de0 100644 --- a/plugins/ide-features-trainer/src/training/lang/LangSupport.kt +++ b/plugins/ide-features-trainer/src/training/lang/LangSupport.kt @@ -53,6 +53,9 @@ interface LangSupport { val sdkConfigurationTasks: LessonContext.(lesson: KLesson) -> Unit get() = {} + /** Check that the project has needed SDK configured */ + fun isSdkConfigured(project: Project): Boolean + companion object { const val EP_NAME = "training.ift.language.extension" } diff --git a/plugins/ide-features-trainer/src/training/learn/OpenLessonActivities.kt b/plugins/ide-features-trainer/src/training/learn/OpenLessonActivities.kt index d001ee986dec..aa0b773933ce 100644 --- a/plugins/ide-features-trainer/src/training/learn/OpenLessonActivities.kt +++ b/plugins/ide-features-trainer/src/training/learn/OpenLessonActivities.kt @@ -101,7 +101,9 @@ internal object OpenLessonActivities { val lessonType = params.lesson.lessonType when { - lessonType == LessonType.SCRATCH && !params.forceLearningProject -> { + lessonType == LessonType.SCRATCH + && !params.forceLearningProject + && langSupport.isSdkConfigured(projectWhereToStartLesson) -> { LOG.debug("${projectWhereToStartLesson.name}: scratch based lesson") } lessonType == LessonType.USER_PROJECT -> { @@ -293,7 +295,7 @@ internal object OpenLessonActivities { val executor = LessonExecutor(lesson, projectWhereToStartLesson, textEditor?.editor, vf) val lessonContext = LessonContextImpl(executor) LessonManager.instance.initDslLesson(textEditor?.editor, lesson, executor) - lesson.lessonContent(lessonContext) + lesson.fullLessonContent(lessonContext) executor.startLesson() } diff --git a/plugins/ide-features-trainer/src/training/learn/course/KLesson.kt b/plugins/ide-features-trainer/src/training/learn/course/KLesson.kt index 4fc83584db59..bf6156bf3936 100644 --- a/plugins/ide-features-trainer/src/training/learn/course/KLesson.kt +++ b/plugins/ide-features-trainer/src/training/learn/course/KLesson.kt @@ -1,13 +1,52 @@ // Copyright 2000-2021 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 training.learn.course +import com.intellij.openapi.project.DumbService +import com.intellij.openapi.project.Project +import com.intellij.openapi.ui.popup.Balloon +import com.intellij.ui.components.panels.NonOpaquePanel import org.jetbrains.annotations.Nls import org.jetbrains.annotations.NonNls +import training.dsl.LearningBalloonConfig import training.dsl.LessonContext +import training.dsl.waitSmartModeStep +import training.learn.LearnBundle +import training.ui.LearningUiHighlightingManager abstract class KLesson(@NonNls id: String, @Nls name: String) : Lesson(id, name) { - abstract val lessonContent: LessonContext.() -> Unit + protected abstract val lessonContent: LessonContext.() -> Unit override lateinit var module: IftModule internal set + + val fullLessonContent: LessonContext.() -> Unit get() = { + showIndexingTask() + lessonContent() + } + + private fun LessonContext.showIndexingTask() { + if (properties.canStartInDumbMode) return + + task { + if (!isDumb(project)) return@task + triggerAndBorderHighlight().component { progress: NonOpaquePanel -> + progress.javaClass.name.contains("InlineProgressPanel") + } + } + + task { + if (!isDumb(project)) return@task + showWarning(LearnBundle.message("indexing.message")) { + isDumb(project) + } + text(LearnBundle.message("indexing.message"), LearningBalloonConfig(Balloon.Position.above, 0, duplicateMessage = false)) + waitSmartModeStep() + } + + prepareRuntimeTask { + LearningUiHighlightingManager.clearHighlights() + } + } + + private fun isDumb(project: Project) = DumbService.getInstance(project).isDumb } diff --git a/plugins/ide-features-trainer/src/training/learn/lesson/LessonManager.kt b/plugins/ide-features-trainer/src/training/learn/lesson/LessonManager.kt index b16969701e93..476f4a408ca0 100644 --- a/plugins/ide-features-trainer/src/training/learn/lesson/LessonManager.kt +++ b/plugins/ide-features-trainer/src/training/learn/lesson/LessonManager.kt @@ -47,7 +47,7 @@ class LessonManager { val learnPanel = learnPanel ?: error("No learn panel") initLesson(null, lesson) learnPanel.scrollToNewMessages = false - OpenPassedContext(project, lesson).apply(lesson.lessonContent) + OpenPassedContext(project, lesson).apply(lesson.fullLessonContent) learnPanel.scrollRectToVisible(Rectangle(0, 0, 1, 1)) learnPanel.makeNextButtonSelected() learnPanel.learnToolWindow.showGotItAboutRestart() diff --git a/plugins/ide-features-trainer/src/training/statistic/TaskIdRuleValidator.kt b/plugins/ide-features-trainer/src/training/statistic/TaskIdRuleValidator.kt index 0ed90b051ee2..1a433d16fa91 100644 --- a/plugins/ide-features-trainer/src/training/statistic/TaskIdRuleValidator.kt +++ b/plugins/ide-features-trainer/src/training/statistic/TaskIdRuleValidator.kt @@ -31,7 +31,7 @@ private class TaskIdRuleValidator : CustomValidationRule() { private fun KLesson.getTaskCount(): Int { val context = ExtractTaskCountContext(this) - lessonContent(context) + fullLessonContent(context) return context.taskCount } } diff --git a/plugins/junit/src/com/intellij/execution/junit/JUnit5Framework.java b/plugins/junit/src/com/intellij/execution/junit/JUnit5Framework.java index 0d336af61068..e12e2c0eebcb 100644 --- a/plugins/junit/src/com/intellij/execution/junit/JUnit5Framework.java +++ b/plugins/junit/src/com/intellij/execution/junit/JUnit5Framework.java @@ -1,4 +1,4 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.execution.junit; import com.intellij.codeInsight.AnnotationUtil; @@ -29,6 +29,11 @@ public class JUnit5Framework extends JUnitTestFramework { } @Override + protected boolean isFrameworkAvailable(@NotNull PsiElement clazz) { + return isFrameworkApplicable(clazz, JUnitUtil.CUSTOM_TESTABLE_ANNOTATION); + } + + @Override public boolean shouldRunSingleClassAsJUnit5(Project project, GlobalSearchScope scope) { return true; } diff --git a/plugins/junit/src/com/intellij/execution/junit/codeInsight/JUnit5MalformedParameterizedInspection.kt b/plugins/junit/src/com/intellij/execution/junit/codeInsight/JUnit5MalformedParameterizedInspection.kt index b437013c545d..6f68f3f9ae2e 100644 --- a/plugins/junit/src/com/intellij/execution/junit/codeInsight/JUnit5MalformedParameterizedInspection.kt +++ b/plugins/junit/src/com/intellij/execution/junit/codeInsight/JUnit5MalformedParameterizedInspection.kt @@ -233,7 +233,10 @@ private class NullOrEmptySourceChecker(val holder: ProblemsHolder) { val size = method.uastParameters.size val shortName = psiAnnotation.qualifiedName ?: return if (size == 1) { - val type = method.uastParameters[0].type + var type = method.uastParameters[0].type + if (type is PsiClassType) { + type = type.rawType() + } if (type is PsiArrayType || type.equalsToText(CommonClassNames.JAVA_LANG_STRING) || type.equalsToText(CommonClassNames.JAVA_UTIL_LIST) || @@ -241,7 +244,7 @@ private class NullOrEmptySourceChecker(val holder: ProblemsHolder) { type.equalsToText(CommonClassNames.JAVA_UTIL_MAP)) { return } - holder.registerProblem(sourcePsi, + holder.registerProblem(sourcePsi, JUnitBundle.message("junit5.malformed.parameterized.inspection.description.emptysource.cannot.provide.argument", StringUtil.getShortName(shortName), type.presentableText)) diff --git a/plugins/junit/test/com/intellij/execution/junit/codeInsight/JUnit5MalformedParameterizedTest.java b/plugins/junit/test/com/intellij/execution/junit/codeInsight/JUnit5MalformedParameterizedTest.java index 21059102d813..b25cb8aa985d 100644 --- a/plugins/junit/test/com/intellij/execution/junit/codeInsight/JUnit5MalformedParameterizedTest.java +++ b/plugins/junit/test/com/intellij/execution/junit/codeInsight/JUnit5MalformedParameterizedTest.java @@ -27,6 +27,7 @@ public class JUnit5MalformedParameterizedTest extends LightJavaInspectionTestCas public void testMalformedSourcesImplicitConversion() { doTest(); } public void testMalformedSourcesImplicitParameters() { doTest(); } public void testMalformedSourcesTestInstancePerClass() { doTest(); } + public void testMalformedParameterizedCollection() { doTest(); } @Override protected String getBasePath() { @@ -38,4 +39,4 @@ public class JUnit5MalformedParameterizedTest extends LightJavaInspectionTestCas protected LightProjectDescriptor getProjectDescriptor() { return JAVA_8; } -}
\ No newline at end of file +} diff --git a/plugins/junit/test/com/intellij/execution/junit/codeInsight/JUnit5TestFrameworkSetupUtil.java b/plugins/junit/test/com/intellij/execution/junit/codeInsight/JUnit5TestFrameworkSetupUtil.java index 70466be4e3f4..20d7738f9e8b 100644 --- a/plugins/junit/test/com/intellij/execution/junit/codeInsight/JUnit5TestFrameworkSetupUtil.java +++ b/plugins/junit/test/com/intellij/execution/junit/codeInsight/JUnit5TestFrameworkSetupUtil.java @@ -7,6 +7,8 @@ public class JUnit5TestFrameworkSetupUtil { public static JavaCodeInsightTestFixture setupJUnit5Library(JavaCodeInsightTestFixture fixture) { fixture.addClass( "package org.junit.jupiter.params.provider;\n" + "public @interface MethodSource {String[] value() default \"\";}"); + fixture.addClass( "package org.junit.jupiter.params.provider;\n" + + "public @interface EmptySource {}"); fixture.addClass( "package org.junit.jupiter.params;\n" + "@org.junit.platform.commons.annotation.Testable\n" + "public @interface ParameterizedTest {String name() default \"\";}"); @@ -83,4 +85,4 @@ public class JUnit5TestFrameworkSetupUtil { fixture.addClass("package org.junit.jupiter.api; public @interface Nested{}"); return fixture; } -}
\ No newline at end of file +} diff --git a/plugins/junit/testData/codeInsight/junit5malformed/MalformedParameterizedCollection.java b/plugins/junit/testData/codeInsight/junit5malformed/MalformedParameterizedCollection.java new file mode 100644 index 000000000000..12705df8c54e --- /dev/null +++ b/plugins/junit/testData/codeInsight/junit5malformed/MalformedParameterizedCollection.java @@ -0,0 +1,20 @@ +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.junit.jupiter.params.provider.EmptySource; +import org.junit.jupiter.params.ParameterizedTest; + +class MalformedParameterizedCollection { + @ParameterizedTest + @EmptySource + void testFooSet(Set<String> input) {} + + @ParameterizedTest + @EmptySource + void testFooList(List<String> input) {} + + @ParameterizedTest + @EmptySource + void testFooMap(Map<String, String> input) {} +} diff --git a/plugins/junit5_rt_tests/test/com/intellij/junit5/JUnit5AcceptanceNoJupiterTest.java b/plugins/junit5_rt_tests/test/com/intellij/junit5/JUnit5AcceptanceNoJupiterTest.java new file mode 100644 index 000000000000..43e2ce1ca512 --- /dev/null +++ b/plugins/junit5_rt_tests/test/com/intellij/junit5/JUnit5AcceptanceNoJupiterTest.java @@ -0,0 +1,56 @@ +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.junit5; + +import com.intellij.codeInsight.TestFrameworks; +import com.intellij.execution.junit.JUnit5Framework; +import com.intellij.execution.junit.JUnitUtil; +import com.intellij.psi.PsiClass; +import com.intellij.testFramework.fixtures.*; +import com.intellij.testFramework.fixtures.impl.LightTempDirTestFixtureImpl; +import com.intellij.testFramework.junit5.EdtInterceptor; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +@ExtendWith(EdtInterceptor.class) + +public class JUnit5AcceptanceNoJupiterTest { + protected JavaCodeInsightTestFixture myFixture; + + @BeforeEach + void setUp() throws Exception { + IdeaTestFixtureFactory factory = IdeaTestFixtureFactory.getFixtureFactory(); + TestFixtureBuilder<IdeaProjectTestFixture> fixtureBuilder = factory.createLightFixtureBuilder(new DefaultLightProjectDescriptor(), + "JUnit5CodeInsightTest"); + final IdeaProjectTestFixture fixture = fixtureBuilder.getFixture(); + myFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(fixture, new LightTempDirTestFixtureImpl(true)); + myFixture.setUp(); + + myFixture.addClass("package org.junit.platform.commons.annotation; public @interface Testable {}"); + + } + + @AfterEach + void tearDown() throws Exception { + myFixture.tearDown(); + } + + @Test + void customEngineOnly() { + PsiClass customEngineTest = myFixture.addClass("import org.junit.platform.commons.annotation.Testable;" + + " /** @noinspection ALL*/ " + + "@Testable\n" + + "class MyTests{}"); + assertTrue(JUnitUtil.isTestClass(customEngineTest)); + assertTrue(TestFrameworks.detectFramework(customEngineTest) instanceof JUnit5Framework); + + PsiClass customEngineAnnotationOnSuper + = myFixture.addClass( + "class MyCustomClass extends MyTests{}"); + assertTrue(JUnitUtil.isTestClass(customEngineAnnotationOnSuper)); + assertTrue(TestFrameworks.detectFramework(customEngineAnnotationOnSuper) instanceof JUnit5Framework); + } +} diff --git a/plugins/kotlin/project-wizard/cli/testData/projectTemplatesBuildFileGeneration/consoleApplication/pom.xml b/plugins/kotlin/project-wizard/cli/testData/projectTemplatesBuildFileGeneration/consoleApplication/pom.xml index 9a711f8500a2..b151d11a5925 100644 --- a/plugins/kotlin/project-wizard/cli/testData/projectTemplatesBuildFileGeneration/consoleApplication/pom.xml +++ b/plugins/kotlin/project-wizard/cli/testData/projectTemplatesBuildFileGeneration/consoleApplication/pom.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> - <artifactId>artifactId</artifactId> + <artifactId>consoleApp</artifactId> <groupId>me.user</groupId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> diff --git a/plugins/markdown/core/src/org/intellij/plugins/markdown/editor/lists/MarkdownListEnterHandlerDelegate.kt b/plugins/markdown/core/src/org/intellij/plugins/markdown/editor/lists/MarkdownListEnterHandlerDelegate.kt index 3c3870288d53..45e7e9cea8fa 100644 --- a/plugins/markdown/core/src/org/intellij/plugins/markdown/editor/lists/MarkdownListEnterHandlerDelegate.kt +++ b/plugins/markdown/core/src/org/intellij/plugins/markdown/editor/lists/MarkdownListEnterHandlerDelegate.kt @@ -99,7 +99,8 @@ internal class MarkdownListEnterHandlerDelegate : EnterHandlerDelegate { caretOffset.set(markerElement.endOffset) } - emptyItem = document.getLineIndentSpaces(itemLine) + item.normalizedMarker + val indentSpaces = document.getLineIndentSpaces(itemLine, file) ?: "" + emptyItem = indentSpaces + item.normalizedMarker return EnterHandlerDelegate.Result.Default } diff --git a/plugins/maven/intellij.maven.iml b/plugins/maven/intellij.maven.iml index 9785e2d238d9..b312628e4c59 100644 --- a/plugins/maven/intellij.maven.iml +++ b/plugins/maven/intellij.maven.iml @@ -66,7 +66,7 @@ <orderEntry type="module" module-name="intellij.maven.model" exported="" /> <orderEntry type="library" name="commons-cli" level="project" /> <orderEntry type="module" module-name="intellij.platform.core.ui" /> - <orderEntry type="module" module-name="intellij.externalSystem.dependencyUpdater" /> + <orderEntry type="module" module-name="intellij.platform.externalSystem.dependencyUpdater" /> <orderEntry type="module" module-name="intellij.properties.psi.impl" /> <orderEntry type="module" module-name="intellij.platform.concurrency" /> <orderEntry type="library" name="fastutil-min" level="project" /> diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenProjectImporterImpl.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenProjectImporterImpl.java index aa7dd0f92ad8..bdcdf7a40a68 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenProjectImporterImpl.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenProjectImporterImpl.java @@ -37,6 +37,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.maven.model.MavenId; import org.jetbrains.idea.maven.project.*; +import org.jetbrains.idea.maven.statistics.MavenImportCollector; import org.jetbrains.idea.maven.utils.MavenLog; import org.jetbrains.idea.maven.utils.MavenUtil; import org.jetbrains.jps.model.java.compiler.JpsJavaCompilerOptions; @@ -615,9 +616,14 @@ class MavenProjectImporterImpl extends MavenProjectImporterBase { boolean removed = false; for (Library each : unusedLibraries) { - if (!isDisposed(each) && MavenRootModelAdapter.isMavenLibrary(each) && !MavenRootModelAdapter.isChangedByUser(each)) { - myModelsProvider.removeLibrary(each); - removed = true; + if (!isDisposed(each) && MavenRootModelAdapter.isMavenLibrary(each)) { + if (!MavenRootModelAdapter.isChangedByUser(each)) { + myModelsProvider.removeLibrary(each); + removed = true; + } + else { + MavenImportCollector.HAS_USER_MODIFIED_IMPORTED_LIBRARY.log(myProject); + } } } return removed; diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapterLegacyImpl.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapterLegacyImpl.java index ff3850ff7727..b470cdddfd08 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapterLegacyImpl.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapterLegacyImpl.java @@ -20,6 +20,7 @@ import org.jetbrains.idea.maven.model.MavenArtifact; import org.jetbrains.idea.maven.model.MavenConstants; import org.jetbrains.idea.maven.project.MavenProject; import org.jetbrains.idea.maven.project.MavenProjectsManager; +import org.jetbrains.idea.maven.statistics.MavenImportCollector; import org.jetbrains.idea.maven.utils.MavenUtil; import org.jetbrains.idea.maven.utils.Path; import org.jetbrains.idea.maven.utils.Url; @@ -94,10 +95,16 @@ public class MavenRootModelAdapterLegacyImpl implements MavenRootModelAdapterInt if (e instanceof LibraryOrderEntry) { if (Registry.is("maven.always.remove.bad.entries")) { - if (!isMavenLibrary((LibraryOrderEntry)e)) continue; + if (!isMavenLibrary((LibraryOrderEntry)e)) { + MavenImportCollector.HAS_USER_ADDED_LIBRARY_DEP.log(myRootModel.getProject()); + continue; + } } else { - if (!isMavenLibrary(((LibraryOrderEntry)e).getLibrary())) continue; + if (!isMavenLibrary(((LibraryOrderEntry)e).getLibrary())) { + MavenImportCollector.HAS_USER_ADDED_LIBRARY_DEP.log(myRootModel.getProject()); + continue; + } } } if (e instanceof ModuleOrderEntry) { @@ -105,6 +112,7 @@ public class MavenRootModelAdapterLegacyImpl implements MavenRootModelAdapterInt if (m != null && !MavenProjectsManager.getInstance(myRootModel.getProject()).isMavenizedModule(m) && ExternalSystemModulePropertyManager.getInstance(m).getExternalSystemId() == null) { + MavenImportCollector.HAS_USER_ADDED_MODULE_DEP.log(myRootModel.getProject()); continue; } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/statistics/MavenImportCollector.kt b/plugins/maven/src/main/java/org/jetbrains/idea/maven/statistics/MavenImportCollector.kt new file mode 100644 index 000000000000..1159d89291b9 --- /dev/null +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/statistics/MavenImportCollector.kt @@ -0,0 +1,24 @@ +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.idea.maven.statistics + +import com.intellij.internal.statistic.eventLog.EventLogGroup +import com.intellij.internal.statistic.service.fus.collectors.CounterUsagesCollector + +class MavenImportCollector : CounterUsagesCollector() { + companion object { + val GROUP = EventLogGroup("maven.import", 1) + + @JvmField + val HAS_USER_ADDED_LIBRARY_DEP = GROUP.registerEvent("hasUserAddedLibraryDependency") + + @JvmField + val HAS_USER_ADDED_MODULE_DEP = GROUP.registerEvent("hasUserAddedModuleDependency") + + @JvmField + val HAS_USER_MODIFIED_IMPORTED_LIBRARY = GROUP.registerEvent("hasUserModifiedImportedLibrary") + } + + override fun getGroup(): EventLogGroup { + return GROUP + } +}
\ No newline at end of file diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/archetype/AbstractMavenCatalogDialog.kt b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/archetype/AbstractMavenCatalogDialog.kt index dfeb8e41ab3c..a480b59b247d 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/archetype/AbstractMavenCatalogDialog.kt +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/archetype/AbstractMavenCatalogDialog.kt @@ -41,13 +41,13 @@ abstract class AbstractMavenCatalogDialog(private val project: Project) : Dialog .bindText(locationProperty.trim()) .applyToComponent { emptyText.text = MavenWizardBundle.message("maven.new.project.wizard.archetype.catalog.dialog.location.hint") } .columns(COLUMNS_MEDIUM) - .textValidation(CHECK_NON_EMPTY, CHECK_MAVEN_CATALOG) + .trimmedTextValidation(CHECK_NON_EMPTY, CHECK_MAVEN_CATALOG) } row(MavenWizardBundle.message("maven.new.project.wizard.archetype.catalog.dialog.name.label")) { textField() .bindText(nameProperty.trim()) .columns(COLUMNS_MEDIUM) - .textValidation(CHECK_NON_EMPTY) + .trimmedTextValidation(CHECK_NON_EMPTY) } onApply { onApply() } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/archetype/CatalogUiUtil.kt b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/archetype/CatalogUiUtil.kt index a0cbaf026cfd..e989a12e4340 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/archetype/CatalogUiUtil.kt +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/archetype/CatalogUiUtil.kt @@ -1,7 +1,7 @@ // Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.idea.maven.wizards.archetype -import com.intellij.openapi.ui.validation.validationTextErrorFor +import com.intellij.openapi.ui.validation.validationErrorFor import com.intellij.openapi.util.io.FileUtil import com.intellij.util.io.exists import com.intellij.util.text.nullize @@ -47,7 +47,7 @@ internal fun suggestCatalogNameByLocation(location: String): String { } } -val CHECK_MAVEN_CATALOG = validationTextErrorFor { location -> +val CHECK_MAVEN_CATALOG = validationErrorFor<String> { location -> if (MavenCatalogManager.isLocal(location)) { validateLocalLocation(location) } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/archetype/MavenAddArchetypeDialog.kt b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/archetype/MavenAddArchetypeDialog.kt index e55b7e208072..abaaf3e59d92 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/archetype/MavenAddArchetypeDialog.kt +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/archetype/MavenAddArchetypeDialog.kt @@ -7,14 +7,11 @@ import com.intellij.openapi.observable.util.trim import com.intellij.openapi.project.Project import com.intellij.openapi.ui.DialogWrapper import com.intellij.openapi.ui.emptyText -import com.intellij.openapi.ui.validation.CHECK_ARTIFACT_ID_FORMAT -import com.intellij.openapi.ui.validation.CHECK_GROUP_ID_FORMAT -import com.intellij.openapi.ui.validation.CHECK_NON_EMPTY +import com.intellij.openapi.ui.validation.* import com.intellij.ui.dsl.builder.* import com.intellij.ui.dsl.builder.bindText import com.intellij.ui.dsl.builder.columns import com.intellij.ui.dsl.builder.panel -import com.intellij.ui.layout.* import org.jetbrains.idea.maven.model.MavenArchetype import org.jetbrains.idea.maven.wizards.MavenWizardBundle @@ -40,19 +37,19 @@ class MavenAddArchetypeDialog(private val project: Project) : DialogWrapper(proj textField() .bindText(archetypeGroupIdProperty.trim()) .columns(COLUMNS_MEDIUM) - .textValidation(CHECK_NON_EMPTY, CHECK_GROUP_ID_FORMAT) + .trimmedTextValidation(CHECK_NON_EMPTY, CHECK_GROUP_ID) } row(MavenWizardBundle.message("maven.new.project.wizard.archetype.artifact.id.label")) { textField() .bindText(archetypeArtifactIdProperty.trim()) .columns(COLUMNS_MEDIUM) - .textValidation(CHECK_NON_EMPTY, CHECK_ARTIFACT_ID_FORMAT) + .trimmedTextValidation(CHECK_NON_EMPTY, CHECK_ARTIFACT_ID) } row(MavenWizardBundle.message("maven.new.project.wizard.archetype.version.label")) { textField() .bindText(archetypeVersionProperty.trim()) .columns(COLUMNS_MEDIUM) - .textValidation(CHECK_NON_EMPTY) + .trimmedTextValidation(CHECK_NON_EMPTY) } row(MavenWizardBundle.message("maven.new.project.wizard.archetype.catalog.label")) { val title = MavenWizardBundle.message("maven.new.project.wizard.archetype.catalog.dialog.location.title") @@ -61,7 +58,7 @@ class MavenAddArchetypeDialog(private val project: Project) : DialogWrapper(proj .bindText(catalogLocationProperty.trim()) .applyToComponent { emptyText.text = MavenWizardBundle.message("maven.new.project.wizard.archetype.catalog.dialog.location.hint") } .columns(COLUMNS_MEDIUM) - .textValidation(CHECK_MAVEN_CATALOG) + .trimmedTextValidation(CHECK_MAVEN_CATALOG) } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/archetype/MavenArchetypeNewProjectWizard.kt b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/archetype/MavenArchetypeNewProjectWizard.kt index 5258457b3972..6f5ca1fe737d 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/archetype/MavenArchetypeNewProjectWizard.kt +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/archetype/MavenArchetypeNewProjectWizard.kt @@ -27,6 +27,7 @@ import com.intellij.openapi.externalSystem.service.ui.completion.TextCompletionR import com.intellij.openapi.externalSystem.service.ui.properties.PropertiesTable import com.intellij.openapi.externalSystem.util.ExternalSystemBundle import com.intellij.openapi.observable.util.transform +import com.intellij.openapi.observable.util.trim import com.intellij.openapi.progress.util.BackgroundTaskUtil import com.intellij.openapi.project.Project import com.intellij.openapi.ui.ComboBox @@ -181,9 +182,9 @@ class MavenArchetypeNewProjectWizard : GeneratorNewProjectWizard { with(builder) { row(ExternalSystemBundle.message("external.system.mavenized.structure.wizard.version.label")) { textField() - .bindText(versionProperty) + .bindText(versionProperty.trim()) .columns(COLUMNS_MEDIUM) - .textValidation(CHECK_NON_EMPTY) + .trimmedTextValidation(CHECK_NON_EMPTY) }.bottomGap(BottomGap.SMALL) } } diff --git a/plugins/maven/src/main/resources/META-INF/maven-dependency-update-integration.xml b/plugins/maven/src/main/resources/META-INF/maven-dependency-update-integration.xml deleted file mode 100644 index 9be8ad748de7..000000000000 --- a/plugins/maven/src/main/resources/META-INF/maven-dependency-update-integration.xml +++ /dev/null @@ -1,5 +0,0 @@ -<idea-plugin> - <extensions defaultExtensionNs="com.intellij"> - <externalSystem.dependencyModifier implementation="org.jetbrains.idea.maven.dsl.MavenDependencyModificator"/> - </extensions> -</idea-plugin>
\ No newline at end of file diff --git a/plugins/maven/src/main/resources/META-INF/plugin.xml b/plugins/maven/src/main/resources/META-INF/plugin.xml index 51d48dd6806f..599364728a62 100644 --- a/plugins/maven/src/main/resources/META-INF/plugin.xml +++ b/plugins/maven/src/main/resources/META-INF/plugin.xml @@ -50,7 +50,6 @@ <depends>org.jetbrains.idea.maven.model</depends> <depends optional="true" config-file="groovy-support.xml">org.intellij.groovy</depends> <depends optional="true" config-file="errorProne-compiler-support.xml">Error-prone plugin</depends> - <depends optional="true" config-file="maven-dependency-update-integration.xml">com.intellij.externalSystem.dependencyUpdater</depends> <extensions defaultExtensionNs="com.intellij"> <pathMacroContributor implementation="org.jetbrains.idea.maven.utils.MavenPathMacroContributor"/> @@ -266,6 +265,7 @@ <statistics.projectUsagesCollector implementation="org.jetbrains.idea.maven.statistics.MavenSettingsCollector"/> <statistics.counterUsagesCollector implementationClass="org.jetbrains.idea.maven.statistics.MavenActionsUsagesCollector"/> + <statistics.counterUsagesCollector implementationClass="org.jetbrains.idea.maven.statistics.MavenImportCollector"/> <statistics.counterUsagesCollector groupId="build.maven.packagesearch" version="2"/> <registryKey key="maven.new.import" defaultValue="false" @@ -329,6 +329,8 @@ <newProjectWizard.java.buildSystem implementation="org.jetbrains.idea.maven.wizards.MavenJavaNewProjectWizard"/> <commandLineInspectionProjectConfigurator implementation="org.jetbrains.idea.maven.MavenCommandLineInspectionProjectConfigurator"/> + + <externalSystem.dependencyModifier implementation="org.jetbrains.idea.maven.dsl.MavenDependencyModificator"/> </extensions> <extensions defaultExtensionNs="com.intellij.properties"> diff --git a/plugins/maven/src/test/intellij.maven.tests.iml b/plugins/maven/src/test/intellij.maven.tests.iml index bdd05ccfb360..35bffe4d662d 100644 --- a/plugins/maven/src/test/intellij.maven.tests.iml +++ b/plugins/maven/src/test/intellij.maven.tests.iml @@ -13,7 +13,7 @@ <orderEntry type="module" module-name="intellij.java.testFramework" scope="TEST" /> <orderEntry type="module" module-name="intellij.repository.search" scope="TEST" /> <orderEntry type="library" scope="TEST" name="assertJ" level="project" /> - <orderEntry type="module" module-name="intellij.externalSystem.dependencyUpdater" scope="TEST" /> + <orderEntry type="module" module-name="intellij.platform.externalSystem.dependencyUpdater" scope="TEST" /> <orderEntry type="module" module-name="intellij.platform.externalSystem.tests" scope="TEST" /> <orderEntry type="module" module-name="intellij.properties.psi" scope="TEST" /> <orderEntry type="module" module-name="intellij.spellchecker" scope="TEST" /> diff --git a/plugins/maven/testFramework/src/com/intellij/maven/testFramework/MavenImportingTestCase.java b/plugins/maven/testFramework/src/com/intellij/maven/testFramework/MavenImportingTestCase.java index 38a786edea6a..113ba6a2227f 100644 --- a/plugins/maven/testFramework/src/com/intellij/maven/testFramework/MavenImportingTestCase.java +++ b/plugins/maven/testFramework/src/com/intellij/maven/testFramework/MavenImportingTestCase.java @@ -39,6 +39,7 @@ import org.jetbrains.concurrency.Promise; import org.jetbrains.idea.maven.execution.MavenRunner; import org.jetbrains.idea.maven.execution.MavenRunnerParameters; import org.jetbrains.idea.maven.execution.MavenRunnerSettings; +import org.jetbrains.idea.maven.importing.MavenProjectImporter; import org.jetbrains.idea.maven.model.MavenArtifact; import org.jetbrains.idea.maven.model.MavenExplicitProfiles; import org.jetbrains.idea.maven.project.*; @@ -218,6 +219,12 @@ public abstract class MavenImportingTestCase extends MavenTestCase { actual.add(folderUrl); } + if (MavenProjectImporter.isImportToWorkspaceModelEnabled()) { + // The new workspace model currently doesn't return source folders in the same order that they were added. + // Actually, we don't care about the source folders order as it shouldn't affect functionality. + checkOrder = false; + } + if (checkOrder) { assertOrderedElementsAreEqual(actual, Arrays.asList(expected)); } diff --git a/plugins/package-search/gradle/intellij.packageSearch.gradle.iml b/plugins/package-search/gradle/intellij.packageSearch.gradle.iml index 17610663e0f1..3861650695c8 100644 --- a/plugins/package-search/gradle/intellij.packageSearch.gradle.iml +++ b/plugins/package-search/gradle/intellij.packageSearch.gradle.iml @@ -14,7 +14,7 @@ <orderEntry type="module" module-name="intellij.platform.ide" /> <orderEntry type="module" module-name="intellij.platform.statistics" /> <orderEntry type="module" module-name="intellij.java.psi" /> - <orderEntry type="module" module-name="intellij.externalSystem.dependencyUpdater" /> + <orderEntry type="module" module-name="intellij.platform.externalSystem.dependencyUpdater" /> <orderEntry type="library" name="kotlinx-coroutines-jdk8" level="project" /> </component> </module>
\ No newline at end of file diff --git a/plugins/package-search/intellij.packageSearch.iml b/plugins/package-search/intellij.packageSearch.iml index 9e6f0804312e..0d2324b1c5ba 100644 --- a/plugins/package-search/intellij.packageSearch.iml +++ b/plugins/package-search/intellij.packageSearch.iml @@ -55,7 +55,7 @@ <orderEntry type="module" module-name="intellij.platform.rd.community" /> <orderEntry type="module" module-name="intellij.platform.statistics" /> <orderEntry type="module" module-name="intellij.platform.util.ui" /> - <orderEntry type="module" module-name="intellij.externalSystem.dependencyUpdater" /> + <orderEntry type="module" module-name="intellij.platform.externalSystem.dependencyUpdater" /> <orderEntry type="module" module-name="intellij.platform.ide.util.io" /> <orderEntry type="module" module-name="intellij.platform.ide.util.netty" /> <orderEntry type="module" module-name="intellij.platform.analysis" /> diff --git a/plugins/package-search/maven/intellij.packageSearch.maven.iml b/plugins/package-search/maven/intellij.packageSearch.maven.iml index ffd973ea2be5..fc0876e6c27b 100644 --- a/plugins/package-search/maven/intellij.packageSearch.maven.iml +++ b/plugins/package-search/maven/intellij.packageSearch.maven.iml @@ -10,7 +10,7 @@ <orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="module" module-name="intellij.packageSearch" /> <orderEntry type="module" module-name="intellij.maven" /> - <orderEntry type="module" module-name="intellij.externalSystem.dependencyUpdater" /> + <orderEntry type="module" module-name="intellij.platform.externalSystem.dependencyUpdater" /> <orderEntry type="module" module-name="intellij.platform.projectModel.impl" /> <orderEntry type="library" name="kotlinx-coroutines-jdk8" level="project" /> </component> diff --git a/plugins/package-search/resources/META-INF/plugin.xml b/plugins/package-search/resources/META-INF/plugin.xml index 04532685d209..bb98f1af906f 100644 --- a/plugins/package-search/resources/META-INF/plugin.xml +++ b/plugins/package-search/resources/META-INF/plugin.xml @@ -50,7 +50,6 @@ Supports Maven and Gradle projects. </content> <dependencies> <plugin id="com.intellij.java"/> - <plugin id="com.intellij.externalSystem.dependencyUpdater"/> </dependencies> <extensions defaultExtensionNs="com.intellij"> diff --git a/plugins/package-search/src/com/jetbrains/packagesearch/intellij/plugin/data/PackageSearchProjectService.kt b/plugins/package-search/src/com/jetbrains/packagesearch/intellij/plugin/data/PackageSearchProjectService.kt index 7159d645cfd4..0076cc657e35 100644 --- a/plugins/package-search/src/com/jetbrains/packagesearch/intellij/plugin/data/PackageSearchProjectService.kt +++ b/plugins/package-search/src/com/jetbrains/packagesearch/intellij/plugin/data/PackageSearchProjectService.kt @@ -5,7 +5,9 @@ package com.jetbrains.packagesearch.intellij.plugin.data import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer import com.intellij.openapi.application.readAction import com.intellij.openapi.components.Service +import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.openapi.project.Project +import com.intellij.psi.PsiManager import com.jetbrains.packagesearch.intellij.plugin.PackageSearchBundle import com.jetbrains.packagesearch.intellij.plugin.PluginEnvironment import com.jetbrains.packagesearch.intellij.plugin.api.PackageSearchApiClient @@ -46,6 +48,7 @@ import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.asFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combineTransform import kotlinx.coroutines.flow.consumeAsFlow @@ -54,6 +57,7 @@ import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.receiveAsFlow @@ -269,7 +273,12 @@ internal class PackageSearchProjectService(private val project: Project) { // allows rerunning PKGS inspections on already opened files // when the data is finally available or changes for PackageUpdateInspection // or when a build file changes - packageUpgradesStateFlow.onEach { DaemonCodeAnalyzer.getInstance(project).restart() } + packageUpgradesStateFlow.throttle(5.seconds) + .map { projectModulesStateFlow.value.map { it.buildFile.path }.toSet() } + .filter { it.isNotEmpty() } + .flatMapLatest { knownBuildFiles -> FileEditorManager.getInstance(project).openFiles.filter { it.path in knownBuildFiles }.asFlow() } + .mapNotNull { readAction { PsiManager.getInstance(project).findFile(it) } } + .onEach { DaemonCodeAnalyzer.getInstance(project).restart(it) } .launchIn(project.lifecycleScope) var controller: BackgroundLoadingBarController? = null @@ -294,7 +303,6 @@ internal class PackageSearchProjectService(private val project: Project) { ) }.launchIn(project.lifecycleScope) } - } fun notifyOperationExecuted(successes: List<ProjectModule>) { diff --git a/plugins/package-search/src/com/jetbrains/packagesearch/intellij/plugin/data/PackagesUpgradesUtils.kt b/plugins/package-search/src/com/jetbrains/packagesearch/intellij/plugin/data/PackagesUpgradesUtils.kt index b57632058e44..ccebf981aade 100644 --- a/plugins/package-search/src/com/jetbrains/packagesearch/intellij/plugin/data/PackagesUpgradesUtils.kt +++ b/plugins/package-search/src/com/jetbrains/packagesearch/intellij/plugin/data/PackagesUpgradesUtils.kt @@ -38,8 +38,8 @@ internal suspend fun computePackageUpgrades( .getOrNull() ?: continue val upgradeVersion = PackageVersionUtils.upgradeCandidateVersionOrNull(normalizedPackageVersion, availableVersions) - if (upgradeVersion != null && upgradeVersion.originalVersion is PackageVersion.Named) { - val moduleModel = nativeModulesMap.getValue(usageInfo.projectModule) + val moduleModel = nativeModulesMap[usageInfo.projectModule] + if (upgradeVersion != null && upgradeVersion.originalVersion is PackageVersion.Named && moduleModel != null) { @Suppress("UNCHECKED_CAST") // The if guards us against cast errors updatesByModule.getOrPut(usageInfo.projectModule.nativeModule) { mutableSetOf() } += PackagesToUpgrade.PackageUpgradeInfo( diff --git a/plugins/package-search/src/com/jetbrains/packagesearch/intellij/plugin/util/LogExtensions.kt b/plugins/package-search/src/com/jetbrains/packagesearch/intellij/plugin/util/LogExtensions.kt index fff2fe2bb943..7d3e16d55305 100644 --- a/plugins/package-search/src/com/jetbrains/packagesearch/intellij/plugin/util/LogExtensions.kt +++ b/plugins/package-search/src/com/jetbrains/packagesearch/intellij/plugin/util/LogExtensions.kt @@ -38,6 +38,7 @@ fun logWarn(traceInfo: TraceInfo? = null, contextName: String? = null, throwable } fun logWarn(message: String, throwable: Throwable? = null) { + if (throwable is CancellationException) return logger.warn(message, throwable) } diff --git a/python/ideCoreSrc/idea/PyCharmCoreApplicationInfo.xml b/python/ideCoreSrc/idea/PyCharmCoreApplicationInfo.xml index d03f56c9ba09..d268cd2f56ff 100644 --- a/python/ideCoreSrc/idea/PyCharmCoreApplicationInfo.xml +++ b/python/ideCoreSrc/idea/PyCharmCoreApplicationInfo.xml @@ -2,7 +2,7 @@ <component xmlns="http://jetbrains.org/intellij/schema/application-info" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jetbrains.org/intellij/schema/application-info http://jetbrains.org/intellij/schema/ApplicationInfo.xsd"> - <version major="2022" minor="1.1" eap="false"/> + <version major="2022" minor="1.2" eap="false"/> <company name="JetBrains s.r.o." url="https://www.jetbrains.com" copyrightStart="2010"/> <build number="PC-__BUILD__" date="__BUILD_DATE__" majorReleaseDate="20220413"/> <logo url="/pycharm_core_logo.png" textcolor="ffffff" progressColor="ffffff" progressY="396" progressHeight="4"/> diff --git a/python/python-features-trainer/src/com/jetbrains/python/ift/PythonBasedLangSupport.kt b/python/python-features-trainer/src/com/jetbrains/python/ift/PythonBasedLangSupport.kt index e6ea03d79dfa..352b22173b37 100644 --- a/python/python-features-trainer/src/com/jetbrains/python/ift/PythonBasedLangSupport.kt +++ b/python/python-features-trainer/src/com/jetbrains/python/ift/PythonBasedLangSupport.kt @@ -24,7 +24,6 @@ import com.jetbrains.python.sdk.configuration.PyProjectSdkConfiguration.setReady import com.jetbrains.python.sdk.configuration.PyProjectVirtualEnvConfiguration import com.jetbrains.python.statistics.modules import training.dsl.LessonContext -import training.dsl.TaskRuntimeContext import training.lang.AbstractLangSupport import training.learn.CourseManager import training.learn.course.KLesson @@ -142,11 +141,12 @@ abstract class PythonBasedLangSupport : AbstractLangSupport() { } } + override fun isSdkConfigured(project: Project): Boolean = project.pythonSdk != null override val sdkConfigurationTasks: LessonContext.(lesson: KLesson) -> Unit = { lesson -> task { stateCheck { - hasPythonSdk() + isSdkConfigured(project) } val configureCallbackId = LearningUiManager.addCallback { val module = project.modules.singleOrNull() ?: return@addCallback @@ -155,7 +155,7 @@ abstract class PythonBasedLangSupport : AbstractLangSupport() { if (useUserProjects || isLearningProject(project, this@PythonBasedLangSupport)) { showWarning(PythonLessonsBundle.message("no.interpreter.in.learning.project", configureCallbackId), problem = LearningInternalProblems.NO_SDK_CONFIGURED) { - !hasPythonSdk() + !isSdkConfigured(project) } } else { // for Scratch lessons in the non-learning project @@ -163,11 +163,9 @@ abstract class PythonBasedLangSupport : AbstractLangSupport() { CourseManager.instance.openLesson(project, lesson, LessonStartingWay.NO_SDK_RESTART, true, true) } showWarning(PythonLessonsBundle.message("no.interpreter.in.user.project", openCallbackId, configureCallbackId)) { - !hasPythonSdk() + !isSdkConfigured(project) } } } } } - -private fun TaskRuntimeContext.hasPythonSdk() = project.pythonSdk != null diff --git a/python/python-psi-impl/src/com/jetbrains/python/formatter/PyBlock.java b/python/python-psi-impl/src/com/jetbrains/python/formatter/PyBlock.java index c76d0d3558d4..51654e214e6b 100644 --- a/python/python-psi-impl/src/com/jetbrains/python/formatter/PyBlock.java +++ b/python/python-psi-impl/src/com/jetbrains/python/formatter/PyBlock.java @@ -400,7 +400,7 @@ public class PyBlock implements ASTBlock { } else if (parentType == PyElementTypes.REFERENCE_EXPRESSION) { if (child != myNode.getFirstChildNode()) { - childIndent = Indent.getNormalIndent(); + childIndent = Indent.getNoneIndent(); if (hasLineBreaksBeforeInSameParent(child, 1)) { if (isInControlStatement()) { childIndent = Indent.getContinuationIndent(); diff --git a/python/src/com/jetbrains/python/refactoring/changeSignature/PyChangeSignatureUsageProcessor.java b/python/src/com/jetbrains/python/refactoring/changeSignature/PyChangeSignatureUsageProcessor.java index 5413071421bf..2e6aaedeb2f9 100644 --- a/python/src/com/jetbrains/python/refactoring/changeSignature/PyChangeSignatureUsageProcessor.java +++ b/python/src/com/jetbrains/python/refactoring/changeSignature/PyChangeSignatureUsageProcessor.java @@ -196,7 +196,7 @@ public class PyChangeSignatureUsageProcessor implements ChangeSignatureUsageProc // Imagine "def f(x, y=None): ..." -> "def f(x, foo=None, y=None): ..." and a call "f(1, 2)" keywordArgsRequired = true; } - else if (!isKeywordVararg && !isPositionalVararg) { + else { newArguments.add(formatArgument(paramName, paramDefault, keywordArgsRequired)); } } @@ -261,7 +261,6 @@ public class PyChangeSignatureUsageProcessor implements ChangeSignatureUsageProc @NotNull private static String formatArgument(@NotNull String name, @NotNull String value, boolean keywordArgument) { if (keywordArgument && !value.startsWith("*")) { - assert !name.startsWith("*"); return name + "=" + value; } else { diff --git a/python/testData/formatter/hangingIndentsInMultilineCallChainInParenthesis.py b/python/testData/formatter/hangingIndentsInMultilineCallChainInParenthesis.py new file mode 100644 index 000000000000..4c8467b81058 --- /dev/null +++ b/python/testData/formatter/hangingIndentsInMultilineCallChainInParenthesis.py @@ -0,0 +1,9 @@ +def get_queryset(self): + return ( + super().get_queryset() + .filter(user=self.request.user) + .prefetch_related( + 'lines__oscar_line', + 'lines__oscar_line__product' + ) + )
\ No newline at end of file diff --git a/python/testData/formatter/hangingIndentsInMultilineCallChainInParenthesis_after.py b/python/testData/formatter/hangingIndentsInMultilineCallChainInParenthesis_after.py new file mode 100644 index 000000000000..5a0fcdc864d5 --- /dev/null +++ b/python/testData/formatter/hangingIndentsInMultilineCallChainInParenthesis_after.py @@ -0,0 +1,9 @@ +def get_queryset(self): + return ( + super().get_queryset() + .filter(user=self.request.user) + .prefetch_related( + 'lines__oscar_line', + 'lines__oscar_line__product' + ) + ) diff --git a/python/testData/formatter/hangingIndentsInMultilineCallChainInSquareBrackets.py b/python/testData/formatter/hangingIndentsInMultilineCallChainInSquareBrackets.py new file mode 100644 index 000000000000..ef1eb6335071 --- /dev/null +++ b/python/testData/formatter/hangingIndentsInMultilineCallChainInSquareBrackets.py @@ -0,0 +1,5 @@ +c = ["line" + .casefold() + .capitalize() + .encode() +]
\ No newline at end of file diff --git a/python/testData/formatter/hangingIndentsInMultilineCallChainInSquareBrackets_after.py b/python/testData/formatter/hangingIndentsInMultilineCallChainInSquareBrackets_after.py new file mode 100644 index 000000000000..52809d28e918 --- /dev/null +++ b/python/testData/formatter/hangingIndentsInMultilineCallChainInSquareBrackets_after.py @@ -0,0 +1,5 @@ +c = ["line" + .casefold() + .capitalize() + .encode() + ] diff --git a/python/testData/formatter/multiLineCallChainSplitByBackslashes.py b/python/testData/formatter/multiLineCallChainSplitByBackslashes.py new file mode 100644 index 000000000000..95b0398e4c5b --- /dev/null +++ b/python/testData/formatter/multiLineCallChainSplitByBackslashes.py @@ -0,0 +1,4 @@ +def func(): + return x.foo() \ + .bar() \ + .baz()
\ No newline at end of file diff --git a/python/testData/formatter/multiLineCallChainSplitByBackslashes_after.py b/python/testData/formatter/multiLineCallChainSplitByBackslashes_after.py new file mode 100644 index 000000000000..0ca77d53b123 --- /dev/null +++ b/python/testData/formatter/multiLineCallChainSplitByBackslashes_after.py @@ -0,0 +1,4 @@ +def func(): + return x.foo() \ + .bar() \ + .baz() diff --git a/python/testData/refactoring/changeSignature/addKeywordVarargAsLastParameter.after.py b/python/testData/refactoring/changeSignature/addKeywordVarargAsLastParameter.after.py deleted file mode 100644 index c94ddc71a5af..000000000000 --- a/python/testData/refactoring/changeSignature/addKeywordVarargAsLastParameter.after.py +++ /dev/null @@ -1,5 +0,0 @@ -def f(a=1, **kwargs): - pass - - -f() diff --git a/python/testData/refactoring/changeSignature/addKeywordVarargAsLastParameter.before.py b/python/testData/refactoring/changeSignature/addKeywordVarargAsLastParameter.before.py deleted file mode 100644 index c1ad718b1188..000000000000 --- a/python/testData/refactoring/changeSignature/addKeywordVarargAsLastParameter.before.py +++ /dev/null @@ -1,5 +0,0 @@ -def f(a=1): - pass - - -f() diff --git a/python/testData/refactoring/changeSignature/addPositionalVarargToKeywordVararg.after.py b/python/testData/refactoring/changeSignature/addPositionalVarargToKeywordVararg.after.py deleted file mode 100644 index a21d04f28c63..000000000000 --- a/python/testData/refactoring/changeSignature/addPositionalVarargToKeywordVararg.after.py +++ /dev/null @@ -1,7 +0,0 @@ -def fun(*args, **kwargs): - print(type(kwargs)) - for key in kwargs: - print("%s = %s" % (key, kwargs[key])) - - -fun(name="geeks", ID="101", language="Python")
\ No newline at end of file diff --git a/python/testData/refactoring/changeSignature/addPositionalVarargToKeywordVararg.before.py b/python/testData/refactoring/changeSignature/addPositionalVarargToKeywordVararg.before.py deleted file mode 100644 index 8cc78fee9eb0..000000000000 --- a/python/testData/refactoring/changeSignature/addPositionalVarargToKeywordVararg.before.py +++ /dev/null @@ -1,7 +0,0 @@ -def fu<caret>n(**kwargs): - print(type(kwargs)) - for key in kwargs: - print("%s = %s" % (key, kwargs[key])) - - -fun(name="geeks", ID="101", language="Python")
\ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PyFormatterTest.java b/python/testSrc/com/jetbrains/python/PyFormatterTest.java index 8845df941646..076b4f3ff2ca 100644 --- a/python/testSrc/com/jetbrains/python/PyFormatterTest.java +++ b/python/testSrc/com/jetbrains/python/PyFormatterTest.java @@ -1239,4 +1239,18 @@ public class PyFormatterTest extends PyTestCase { getCodeStyleSettings().setRightMargin(PythonLanguage.getInstance(), 20); doTest(); } + + // PY-28496 + public void testHangingIndentsInMultilineCallChainInParenthesis() { + doTest(); + } + + // PY-27660 + public void testHangingIndentsInMultilineCallChainInSquareBrackets() { + doTest(); + } + + public void testMultiLineCallChainSplitByBackslashes() { + doTest(); + } } diff --git a/python/testSrc/com/jetbrains/python/refactoring/changeSignature/PyChangeSignatureTest.java b/python/testSrc/com/jetbrains/python/refactoring/changeSignature/PyChangeSignatureTest.java index 64b8aac50a69..afeb10ff5a73 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/changeSignature/PyChangeSignatureTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/changeSignature/PyChangeSignatureTest.java @@ -476,18 +476,6 @@ public class PyChangeSignatureTest extends PyTestCase { new PyParameterInfo(1, PySlashParameter.TEXT, null, false))); } - // PY-42682 - public void testAddPositionalVarargToKeywordVararg() { - doChangeSignatureTest(null, Arrays.asList(new PyParameterInfo(NEW_PARAMETER, "*args", null, false), - new PyParameterInfo(0, "**kwargs", null, false))); - } - - // PY-42682 - public void testAddKeywordVarargAsLastParameter() { - doChangeSignatureTest(null, Arrays.asList(new PyParameterInfo(0, "a", "1", true), - new PyParameterInfo(NEW_PARAMETER, "**kwargs", null, false))); - } - public void testPositionalOnlyMarkerAsFirstParameter() { doValidationTest(null, Arrays.asList(new PyParameterInfo(NEW_PARAMETER, PySlashParameter.TEXT, null, false), new PyParameterInfo(0, "a", null, false)), diff --git a/resources/src/idea/JavaActions.xml b/resources/src/idea/JavaActions.xml index 6d481ef9caca..e5454fbc3bc5 100644 --- a/resources/src/idea/JavaActions.xml +++ b/resources/src/idea/JavaActions.xml @@ -109,38 +109,6 @@ <separator/> <action id="Merge3Files" internal="true" class="com.intellij.openapi.diff.actions.MergeFilesAction"/> <separator/> - <group id="Internal.Dump" internal="true" popup="true"> - <action id="DumpExtensions" internal="true" class="com.intellij.internal.DumpExtensionsAction"/> - <action id="DumpInspectionDescriptions" internal="true" class="com.intellij.internal.DumpInspectionDescriptionsAction"/> - <action id="DumpIntentionsDescriptions" internal="true" class="com.intellij.internal.DumpIntentionsAction"/> - <action id="DumpConfigurationTypes" internal="true" class="com.intellij.internal.DumpConfigurationTypesAction"/> - <action id="DumpDirectoryIndex" internal="true" class="com.intellij.internal.DumpDirectoryInfoAction"/> - <action id="ScanSourceCommentsAction" internal="true" class="com.intellij.tools.ScanSourceCommentsAction"/> - <action id="DumpScreenConfiguration" class="com.intellij.internal.DumpScreenConfigurationAction"/> - <action id="DumpInvalidTipsOfTheDay" internal="true" class="com.intellij.ide.util.DumpInvalidTipsAction"/> - </group> - - <separator/> - <group id="Internal.VFS" popup="true"> - <action id="VirtualFileInfo" internal="true" class="com.intellij.openapi.vfs.impl.local.VirtualFileInfoAction"/> - <action id="MarkFileDirty" internal="true" class="com.intellij.openapi.vcs.changes.actions.MarkFileDirtyAction"/> - <separator/> - <action id="CheckVfsSanity" internal="true" class="com.intellij.openapi.vfs.newvfs.persistent.CheckSanityAction"/> - <action id="MarkVfsCorrupted" internal="true" class="com.intellij.openapi.vfs.newvfs.persistent.MarkVfsCorruptedAction"/> - <action id="LoadAllContent" internal="true" class="com.intellij.internal.LoadAllContentsAction"/> - <action id="LoadAllVFSContent" internal="true" class="com.intellij.internal.LoadAllVfsStoredContentsAction"/> - <action id="ComputeVFStatistics" internal="true" class="com.intellij.internal.ComputeVirtualFileNameStatAction"/> - <action id="DumpVfsInfoForExcludedFiles" internal="true" class="com.intellij.internal.DumpVfsInfoForExcludedFilesAction"/> - <action id="DumpWatchedRoots" internal="true" class="com.intellij.openapi.roots.impl.DumpWatchedRootsAction"/> - <separator/> - <action internal="true" id="PruneEmptyDirectories" class="com.intellij.ide.actions.PruneEmptyDirectoriesAction"/> - <action internal="true" id="FixLineSeparators" class="com.intellij.ide.actions.FixLineSeparatorsAction"/> - <separator/> - <action internal="true" id="ValidateLocalHistory" class="com.intellij.history.integration.ValidateHistoryAction"/> - </group> - - <separator/> - <add-to-group group-id="Internal" anchor="last"/> </group> diff --git a/spellchecker/intellij.spellchecker.iml b/spellchecker/intellij.spellchecker.iml index fb62d9726166..82c182533272 100644 --- a/spellchecker/intellij.spellchecker.iml +++ b/spellchecker/intellij.spellchecker.iml @@ -23,49 +23,49 @@ <orderEntry type="module" module-name="intellij.platform.statistics" /> <orderEntry type="module-library"> <library name="ai.grazie.utils:utils-common" type="repository"> - <properties include-transitive-deps="false" maven-id="ai.grazie.utils:utils-common:0.1.50" /> + <properties include-transitive-deps="false" maven-id="ai.grazie.utils:utils-common:0.1.50-1" /> <CLASSES> - <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/utils/utils-common/0.1.50/utils-common-0.1.50.jar!/" /> + <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/utils/utils-common/0.1.50-1/utils-common-0.1.50-1.jar!/" /> </CLASSES> <JAVADOC /> <SOURCES> - <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/utils/utils-common/0.1.50/utils-common-0.1.50-sources.jar!/" /> + <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/utils/utils-common/0.1.50-1/utils-common-0.1.50-1-sources.jar!/" /> </SOURCES> </library> </orderEntry> <orderEntry type="module-library"> <library name="ai.grazie.nlp:nlp-common" type="repository"> - <properties include-transitive-deps="false" maven-id="ai.grazie.nlp:nlp-common:0.1.50" /> + <properties include-transitive-deps="false" maven-id="ai.grazie.nlp:nlp-common:0.1.50-1" /> <CLASSES> - <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/nlp/nlp-common/0.1.50/nlp-common-0.1.50.jar!/" /> + <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/nlp/nlp-common/0.1.50-1/nlp-common-0.1.50-1.jar!/" /> </CLASSES> <JAVADOC /> <SOURCES> - <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/nlp/nlp-common/0.1.50/nlp-common-0.1.50-sources.jar!/" /> + <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/nlp/nlp-common/0.1.50-1/nlp-common-0.1.50-1-sources.jar!/" /> </SOURCES> </library> </orderEntry> <orderEntry type="module-library"> <library name="ai.grazie.nlp:nlp-tokenizer" type="repository"> - <properties include-transitive-deps="false" maven-id="ai.grazie.nlp:nlp-tokenizer:0.1.50" /> + <properties include-transitive-deps="false" maven-id="ai.grazie.nlp:nlp-tokenizer:0.1.50-1" /> <CLASSES> - <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/nlp/nlp-tokenizer/0.1.50/nlp-tokenizer-0.1.50.jar!/" /> + <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/nlp/nlp-tokenizer/0.1.50-1/nlp-tokenizer-0.1.50-1.jar!/" /> </CLASSES> <JAVADOC /> <SOURCES> - <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/nlp/nlp-tokenizer/0.1.50/nlp-tokenizer-0.1.50-sources.jar!/" /> + <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/nlp/nlp-tokenizer/0.1.50-1/nlp-tokenizer-0.1.50-1-sources.jar!/" /> </SOURCES> </library> </orderEntry> <orderEntry type="module-library"> <library name="ai.grazie.spell:hunspell-en" type="repository"> - <properties include-transitive-deps="false" maven-id="ai.grazie.spell:hunspell-en:0.1.7" /> + <properties include-transitive-deps="false" maven-id="ai.grazie.spell:hunspell-en:0.1.7-1" /> <CLASSES> - <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/spell/hunspell-en/0.1.7/hunspell-en-0.1.7.jar!/" /> + <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/spell/hunspell-en/0.1.7-1/hunspell-en-0.1.7-1.jar!/" /> </CLASSES> <JAVADOC /> <SOURCES> - <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/spell/hunspell-en/0.1.7/hunspell-en-0.1.7-sources.jar!/" /> + <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/spell/hunspell-en/0.1.7-1/hunspell-en-0.1.7-1-sources.jar!/" /> </SOURCES> </library> </orderEntry> @@ -85,13 +85,13 @@ <orderEntry type="library" name="lucene-analyzers-common" level="project" /> <orderEntry type="module-library"> <library name="ai.grazie.spell:gec-spell-local-engine" type="repository"> - <properties include-transitive-deps="false" maven-id="ai.grazie.spell:gec-spell-local-engine:0.1.50" /> + <properties include-transitive-deps="false" maven-id="ai.grazie.spell:gec-spell-local-engine:0.1.50-1" /> <CLASSES> - <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/spell/gec-spell-local-engine/0.1.50/gec-spell-local-engine-0.1.50.jar!/" /> + <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/spell/gec-spell-local-engine/0.1.50-1/gec-spell-local-engine-0.1.50-1.jar!/" /> </CLASSES> <JAVADOC /> <SOURCES> - <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/spell/gec-spell-local-engine/0.1.50/gec-spell-local-engine-0.1.50-sources.jar!/" /> + <root url="jar://$MAVEN_REPOSITORY$/ai/grazie/spell/gec-spell-local-engine/0.1.50-1/gec-spell-local-engine-0.1.50-1-sources.jar!/" /> </SOURCES> </library> </orderEntry> diff --git a/spellchecker/src/com/intellij/spellchecker/SpellCheckerManager.java b/spellchecker/src/com/intellij/spellchecker/SpellCheckerManager.java index 3725e7bf2c4e..c84eb44fe560 100644 --- a/spellchecker/src/com/intellij/spellchecker/SpellCheckerManager.java +++ b/spellchecker/src/com/intellij/spellchecker/SpellCheckerManager.java @@ -27,7 +27,7 @@ import com.intellij.spellchecker.engine.SuggestionProvider; import com.intellij.spellchecker.grazie.GrazieSpellCheckerEngine; import com.intellij.spellchecker.grazie.GrazieSuggestionProvider; import com.intellij.spellchecker.settings.SpellCheckerSettings; -import com.intellij.spellchecker.state.CachedDictionaryState; +import com.intellij.spellchecker.state.AppDictionaryState; import com.intellij.spellchecker.state.DictionaryStateListener; import com.intellij.spellchecker.state.ProjectDictionaryState; import com.intellij.spellchecker.util.SpellCheckerBundle; @@ -66,7 +66,7 @@ public final class SpellCheckerManager implements Disposable { private final String myAppDictionaryPath; private static final String PROJECT_DICTIONARY_PATH = "dictionaries" + File.separator + System.getProperty("user.name").replace('.', '_') + ".xml"; - private static final String CACHED_DICTIONARY_FILE = "cachedDictionary.xml"; + private static final String CACHED_DICTIONARY_FILE = "spellchecker-dictionary.xml"; private final EventDispatcher<DictionaryStateListener> userDictionaryListenerEventDispatcher = EventDispatcher.create(DictionaryStateListener.class); @@ -181,12 +181,12 @@ public final class SpellCheckerManager implements Disposable { } private void initUserDictionaries() { - CachedDictionaryState cachedDictionaryState = CachedDictionaryState.getInstance(); - cachedDictionaryState.addCachedDictListener(__ -> restartInspections(), this); - if (cachedDictionaryState.getDictionary() == null) { - cachedDictionaryState.setDictionary(new UserDictionary(CachedDictionaryState.DEFAULT_NAME)); + AppDictionaryState appDictionaryState = AppDictionaryState.getInstance(); + appDictionaryState.addAppDictListener(__ -> restartInspections(), this); + if (appDictionaryState.getDictionary() == null) { + appDictionaryState.setDictionary(new UserDictionary(AppDictionaryState.DEFAULT_NAME)); } - myAppDictionary = cachedDictionaryState.getDictionary(); + myAppDictionary = appDictionaryState.getDictionary(); mySpellChecker.addModifiableDictionary(myAppDictionary); ProjectDictionaryState dictionaryState = project.getService(ProjectDictionaryState.class); diff --git a/spellchecker/src/com/intellij/spellchecker/state/CachedDictionaryState.java b/spellchecker/src/com/intellij/spellchecker/state/AppDictionaryState.java index d72d6dec2d15..568612d234a9 100644 --- a/spellchecker/src/com/intellij/spellchecker/state/CachedDictionaryState.java +++ b/spellchecker/src/com/intellij/spellchecker/state/AppDictionaryState.java @@ -9,27 +9,34 @@ import com.intellij.spellchecker.dictionary.EditableDictionary; import com.intellij.util.EventDispatcher; import org.jetbrains.annotations.NotNull; +// do not change component name - `CachedDictionaryState` is used historically and no easy way to change it. @State( name = "CachedDictionaryState", - storages = @Storage(value = StoragePathMacros.CACHE_FILE, roamingType = RoamingType.DISABLED), + storages = { + @Storage("spellchecker-dictionary.xml"), + @Storage(value = "cachedDictionary.xml", deprecated = true), + @Storage(value = StoragePathMacros.CACHE_FILE, deprecated = true), + }, reportStatistic = false ) @Service(Service.Level.APP) -public final class CachedDictionaryState extends DictionaryState implements PersistentStateComponent<DictionaryState> { +public final class AppDictionaryState extends DictionaryState implements PersistentStateComponent<DictionaryState> { public static final String DEFAULT_NAME = "cached"; private final EventDispatcher<DictionaryStateListener> myDictListenerEventDispatcher = EventDispatcher.create(DictionaryStateListener.class); - public CachedDictionaryState() { + @SuppressWarnings("unused") + public AppDictionaryState() { name = DEFAULT_NAME; } - public static @NotNull CachedDictionaryState getInstance() { - return ApplicationManager.getApplication().getService(CachedDictionaryState.class); + public static @NotNull AppDictionaryState getInstance() { + return ApplicationManager.getApplication().getService(AppDictionaryState.class); } + @SuppressWarnings("unused") @NonInjectable - public CachedDictionaryState(EditableDictionary dictionary) { + public AppDictionaryState(EditableDictionary dictionary) { super(dictionary); name = DEFAULT_NAME; } @@ -43,7 +50,7 @@ public final class CachedDictionaryState extends DictionaryState implements Pers myDictListenerEventDispatcher.getMulticaster().dictChanged(getDictionary()); } - public void addCachedDictListener(DictionaryStateListener listener, Disposable parentDisposable) { + public void addAppDictListener(DictionaryStateListener listener, Disposable parentDisposable) { myDictListenerEventDispatcher.addListener(listener, parentDisposable); } } diff --git a/tools/intellij.ide.starter/src/com/intellij/ide/starter/ide/ide.kt b/tools/intellij.ide.starter/src/com/intellij/ide/starter/ide/ide.kt index f05ce67e5f28..8acda396d42a 100644 --- a/tools/intellij.ide.starter/src/com/intellij/ide/starter/ide/ide.kt +++ b/tools/intellij.ide.starter/src/com/intellij/ide/starter/ide/ide.kt @@ -208,7 +208,7 @@ private fun downloadAndUnpackJbrIfNeeded(jbrFullVersion: String): Path { false -> "x64" } - val localFileName = "jbrsdk-$majorVersion-$os-$arch-b$buildNumber.tar.gz" + val localFileName = "jbrsdk_dcevm-$majorVersion-$os-$arch-b$buildNumber.tar.gz" val downloadUrl = "https://cache-redirector.jetbrains.com/intellij-jbr/$localFileName" val jbrCacheDirectory = di.direct.instance<GlobalPaths>().getCacheDirectoryFor("jbr") diff --git a/tools/intellij.ide.starter/src/com/intellij/ide/starter/plugins/PluginConfigurator.kt b/tools/intellij.ide.starter/src/com/intellij/ide/starter/plugins/PluginConfigurator.kt index 6dd3b15f54f3..1f1e6cfbd92b 100644 --- a/tools/intellij.ide.starter/src/com/intellij/ide/starter/plugins/PluginConfigurator.kt +++ b/tools/intellij.ide.starter/src/com/intellij/ide/starter/plugins/PluginConfigurator.kt @@ -43,7 +43,7 @@ open class PluginConfigurator(val testContext: IDETestContext) { val url = buildString { append("https://plugins.jetbrains.com/pluginManager/") append("?action=download") - append("&id=$pluginName") + append("&id=${pluginName.replace(" ", "%20")}") append("&noStatistic=false") append("&build=$ideBuild") channel?.let { diff --git a/xml/impl/src/com/intellij/xml/template/formatter/AbstractXmlTemplateFormattingModelBuilder.java b/xml/impl/src/com/intellij/xml/template/formatter/AbstractXmlTemplateFormattingModelBuilder.java index 43277f0c1e5e..5b3266331dc4 100644 --- a/xml/impl/src/com/intellij/xml/template/formatter/AbstractXmlTemplateFormattingModelBuilder.java +++ b/xml/impl/src/com/intellij/xml/template/formatter/AbstractXmlTemplateFormattingModelBuilder.java @@ -305,7 +305,7 @@ public abstract class AbstractXmlTemplateFormattingModelBuilder extends SimpleTe } - private List<Block> buildTemplateLanguageBlocksInside(@NotNull PsiFile templateFile, + protected List<Block> buildTemplateLanguageBlocksInside(@NotNull PsiFile templateFile, @NotNull TextRange range, CodeStyleSettings settings, XmlFormattingPolicy xmlFormattingPolicy, |