From 149838abea9cf773e37bc3daefdbc6040dea9739 Mon Sep 17 00:00:00 2001 From: Nikita Barkov Date: Fri, 5 Jul 2024 14:14:58 +0000 Subject: [PATCH] [perf_test_kotlin]AT-695. Implemented move kotlin files test GitOrigin-RevId: 318c1046a6d66fe0dd851435e3e75f855dc7587c --- .../JavaMoveClassesOrPackagesHandler.java | 6 +- .../refactoring/BaseRefactoringProcessor.java | 9 +- .../MoveKotlinDeclarationsHandler.kt | 10 +- .../idea/k2/refactoring/move/K2MoveHandler.kt | 8 +- .../commands/dto/MoveFilesData.kt | 3 + .../commands/generalCommandChain.kt | 100 +++++++++++------- .../BaseCommandProvider.java | 3 +- .../commands/MoveFilesCommand.kt | 55 ++++++++++ .../commands/dto/MoveFilesData.kt | 3 + 9 files changed, 152 insertions(+), 45 deletions(-) create mode 100644 plugins/performanceTesting/commands-model/src/com/intellij/tools/ide/performanceTesting/commands/dto/MoveFilesData.kt create mode 100644 plugins/performanceTesting/core/src/com/jetbrains/performancePlugin/commands/MoveFilesCommand.kt create mode 100644 plugins/performanceTesting/core/src/com/jetbrains/performancePlugin/commands/dto/MoveFilesData.kt diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java b/java/java-impl-refactorings/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java index b8a694798fc9..06a3c2d85229 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java @@ -155,7 +155,11 @@ public class JavaMoveClassesOrPackagesHandler extends MoveHandlerDelegate { if (targetContainer instanceof PsiDirectory) { if (CommonRefactoringUtil.checkReadOnlyStatusRecursively(project, Arrays.asList(adjustedElements), true)) { if (!packageHasMultipleDirectoriesInModule(project, (PsiDirectory)targetContainer)) { - createMoveClassesOrPackagesToNewDirectoryDialog((PsiDirectory)targetContainer, adjustedElements, callback).show(); + var dialogue = createMoveClassesOrPackagesToNewDirectoryDialog((PsiDirectory)targetContainer, adjustedElements, callback); + if (Boolean.getBoolean("ide.performance.skip.move.files.dialog")) + dialogue.performOKAction(); + else + dialogue.show(); return; } } diff --git a/platform/refactoring/src/com/intellij/refactoring/BaseRefactoringProcessor.java b/platform/refactoring/src/com/intellij/refactoring/BaseRefactoringProcessor.java index 1e09da80eb82..7e59feb25c2e 100644 --- a/platform/refactoring/src/com/intellij/refactoring/BaseRefactoringProcessor.java +++ b/platform/refactoring/src/com/intellij/refactoring/BaseRefactoringProcessor.java @@ -263,8 +263,10 @@ public abstract class BaseRefactoringProcessor implements Runnable { } protected void previewRefactoring(UsageInfo @NotNull [] usages) { - if (ApplicationManager.getApplication().isUnitTestMode()) { - if (!PREVIEW_IN_TESTS) throw new RuntimeException("Unexpected preview in tests: " + StringUtil.join(usages, UsageInfo::toString, ", ")); + if (ApplicationManager.getApplication().isUnitTestMode() || Boolean.getBoolean("ide.performance.skip.refactoring.conflicts.dialog")) { + if (!PREVIEW_IN_TESTS) { + throw new RuntimeException("Unexpected preview in tests: " + StringUtil.join(usages, UsageInfo::toString, ", ")); + } ensureElementsWritable(usages, createUsageViewDescriptor(usages)); execute(usages); return; @@ -666,7 +668,8 @@ public abstract class BaseRefactoringProcessor implements Runnable { } protected boolean showConflicts(@NotNull MultiMap conflicts, UsageInfo @Nullable [] usages) { - if (!conflicts.isEmpty() && ApplicationManager.getApplication().isUnitTestMode()) { + if (!conflicts.isEmpty() && (ApplicationManager.getApplication().isUnitTestMode() + || Boolean.getBoolean("ide.performance.skip.refactoring.conflicts.dialog"))) { if (!ConflictsInTestsException.isTestIgnore()) throw new ConflictsInTestsException(conflicts.values()); return true; } diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsHandler.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsHandler.kt index ff2ceb3e23ab..246dd6a60804 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsHandler.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsHandler.kt @@ -33,6 +33,7 @@ import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext import org.jetbrains.kotlin.psi.psiUtil.isTopLevelInFileOrScript +import java.lang.Boolean.getBoolean private val defaultHandlerActions = object : MoveKotlinDeclarationsHandlerActions { @@ -82,7 +83,12 @@ private val defaultHandlerActions = object : MoveKotlinDeclarationsHandlerAction initialDirectory: PsiDirectory?, elements: List, moveCallback: MoveCallback? - ) = KotlinAwareMoveFilesOrDirectoriesDialog(project, initialDirectory, elements, moveCallback).show() + ) = KotlinAwareMoveFilesOrDirectoriesDialog(project, initialDirectory, elements, moveCallback).let { + if (getBoolean("ide.performance.skip.move.files.dialog")) + it.performOKAction() + else + it.show() + } } class MoveKotlinDeclarationsHandler internal constructor(private val handlerActions: MoveKotlinDeclarationsHandlerActions) : @@ -173,7 +179,7 @@ class MoveKotlinDeclarationsHandler internal constructor(private val handlerActi } val initialTargetDirectory = MoveFilesOrDirectoriesUtil.resolveToDirectory(project, initialTargetElement) - if (!isUnitTestMode() && + if (!getBoolean("ide.performance.skip.move.files.dialog") && !isUnitTestMode() && elementsToSearch.any { it.isExpectDeclaration() || it.isEffectivelyActual() } ) { val message = diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/move/K2MoveHandler.kt b/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/move/K2MoveHandler.kt index d3fd14f7ad99..c24ead8becb7 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/move/K2MoveHandler.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/move/K2MoveHandler.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.psi.KtConstructor import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtNamedDeclaration +import java.lang.Boolean.getBoolean class K2MoveHandler : MoveHandlerDelegate() { override fun supportsLanguage(language: Language): Boolean = language == KotlinLanguage.INSTANCE @@ -71,6 +72,11 @@ class K2MoveHandler : MoveHandlerDelegate() { editor: Editor? ) { val type = K2MoveModel.create(elements, targetContainer, editor) ?: return - K2MoveDialog(project, type).show() + K2MoveDialog(project, type).apply { + if (getBoolean("ide.performance.skip.move.files.dialog")) + performOKAction() + else + show() + } } } \ No newline at end of file diff --git a/plugins/performanceTesting/commands-model/src/com/intellij/tools/ide/performanceTesting/commands/dto/MoveFilesData.kt b/plugins/performanceTesting/commands-model/src/com/intellij/tools/ide/performanceTesting/commands/dto/MoveFilesData.kt new file mode 100644 index 000000000000..1d74c75e44b5 --- /dev/null +++ b/plugins/performanceTesting/commands-model/src/com/intellij/tools/ide/performanceTesting/commands/dto/MoveFilesData.kt @@ -0,0 +1,3 @@ +package com.intellij.tools.ide.performanceTesting.commands.dto + +data class MoveFilesData(val files: List, val toDirectory: String, val spanTag: String = "") \ No newline at end of file diff --git a/plugins/performanceTesting/commands-model/src/com/intellij/tools/ide/performanceTesting/commands/generalCommandChain.kt b/plugins/performanceTesting/commands-model/src/com/intellij/tools/ide/performanceTesting/commands/generalCommandChain.kt index 92df2f992d0c..8c041d64aa81 100644 --- a/plugins/performanceTesting/commands-model/src/com/intellij/tools/ide/performanceTesting/commands/generalCommandChain.kt +++ b/plugins/performanceTesting/commands-model/src/com/intellij/tools/ide/performanceTesting/commands/generalCommandChain.kt @@ -63,16 +63,20 @@ private fun T.appendRawLine(line: String): T = apply { addCommand(line) } -fun T.verifyFileEncoding(relativePath: String, - expectedCharsetName: String): T = apply { +fun T.verifyFileEncoding( + relativePath: String, + expectedCharsetName: String, +): T = apply { addCommand("${CMD_PREFIX}assertEncodingFileCommand", relativePath, expectedCharsetName) } -fun T.openFile(relativePath: String, - timeoutInSeconds: Long = 0, - suppressErrors: Boolean = false, - warmup: Boolean = false, - disableCodeAnalysis: Boolean = false): T = apply { +fun T.openFile( + relativePath: String, + timeoutInSeconds: Long = 0, + suppressErrors: Boolean = false, + warmup: Boolean = false, + disableCodeAnalysis: Boolean = false, +): T = apply { val command = mutableListOf("${CMD_PREFIX}openFile", "-file ${relativePath.replace(" ", "SPACE_SYMBOL")}") if (timeoutInSeconds != 0L) { command.add("-timeout $timeoutInSeconds") @@ -152,10 +156,12 @@ fun T.findUsages(expectedElementName: String = "", scope: Str navigateAndFindUsages(expectedElementName, "", scope, warmup = warmup) } -fun T.navigateAndFindUsages(expectedElementName: String, - position: String = "INTO", - scope: String = "Project Files", - warmup: Boolean = false): T = apply { +fun T.navigateAndFindUsages( + expectedElementName: String, + position: String = "INTO", + scope: String = "Project Files", + warmup: Boolean = false, +): T = apply { val command = mutableListOf("${CMD_PREFIX}findUsages") if (expectedElementName.isNotEmpty()) { command.add("-expectedName $expectedElementName") @@ -365,15 +371,17 @@ fun T.pressKey(key: Keys): T = apply { addCommand("${CMD_PREFIX}pressKey", key.name) } -fun T.delayType(delayMs: Int, - text: String, - calculateAnalyzesTime: Boolean = false, - disableWriteProtection: Boolean = false): T = apply { +fun T.delayType( + delayMs: Int, + text: String, + calculateAnalyzesTime: Boolean = false, + disableWriteProtection: Boolean = false, +): T = apply { addCommand("${CMD_PREFIX}delayType", "$delayMs|$text|$calculateAnalyzesTime|$disableWriteProtection") } fun T.doLocalInspection(spanTag: String? = null): T = apply { - val spanTagLine = spanTag?.let { " spanTag $spanTag" } ?: "" + val spanTagLine = spanTag?.let { " spanTag $spanTag" } ?: "" addCommand("${CMD_PREFIX}doLocalInspection" + spanTagLine) } @@ -399,10 +407,12 @@ fun T.createAllServicesAndExtensions(): T = apply { addCommand("${CMD_PREFIX}CreateAllServicesAndExtensions") } -fun T.runConfiguration(configurationName: String, - mode: String = "TILL_TERMINATED", - failureExpected: Boolean = false, - debug: Boolean = false): T = apply { +fun T.runConfiguration( + configurationName: String, + mode: String = "TILL_TERMINATED", + failureExpected: Boolean = false, + debug: Boolean = false, +): T = apply { val command = mutableListOf("${CMD_PREFIX}runConfiguration") command.add("-configurationName=$configurationName") command.add("-mode=$mode") @@ -427,12 +437,14 @@ fun T.stopPowerSave(): T = apply { addCommand("${CMD_PREFIX}stopPowerSave") } -fun T.searchEverywhere(tab: String = "all", - textToInsert: String = "", - textToType: String = "", - close: Boolean = false, - selectFirst: Boolean = false, - warmup: Boolean = false): T = apply { +fun T.searchEverywhere( + tab: String = "all", + textToInsert: String = "", + textToType: String = "", + close: Boolean = false, + selectFirst: Boolean = false, + warmup: Boolean = false, +): T = apply { val closeOnOpenArgument = when { close -> "-close" else -> "" @@ -445,7 +457,7 @@ fun T.searchEverywhere(tab: String = "all", textToType.isNotEmpty() -> "-type $textToType" else -> "" } - val warmupText = if(warmup) "|WARMUP" else "" + val warmupText = if (warmup) "|WARMUP" else "" if (selectFirstArgument.isNotEmpty() && closeOnOpenArgument.isNotEmpty()) { throw Exception("selectFirst=true argument will be ignored since close=true and SE will be closed first") } @@ -565,9 +577,11 @@ enum class AssertModuleJdkVersionMode { EQUALS } -fun T.assertModuleJdkVersion(moduleName: String, - jdkVersion: String, - mode: AssertModuleJdkVersionMode = AssertModuleJdkVersionMode.CONTAINS): T { +fun T.assertModuleJdkVersion( + moduleName: String, + jdkVersion: String, + mode: AssertModuleJdkVersionMode = AssertModuleJdkVersionMode.CONTAINS, +): T { val command = mutableListOf("${CMD_PREFIX}assertModuleJdkVersionCommand") command.add("-moduleName=$moduleName") command.add("-jdkVersion=$jdkVersion") @@ -614,8 +628,10 @@ fun T.refreshGradleProject(): T = apply { addCommand("${CMD_PREFIX}refreshGradleProject") } -fun T.setGradleDelegatedBuildCommand(delegatedBuild: Boolean = true, - gradleTestRunner: GradleTestRunner = GradleTestRunner.GRADLE): T = apply { +fun T.setGradleDelegatedBuildCommand( + delegatedBuild: Boolean = true, + gradleTestRunner: GradleTestRunner = GradleTestRunner.GRADLE, +): T = apply { addCommand("${CMD_PREFIX}setGradleDelegatedBuildCommand $delegatedBuild $gradleTestRunner") } @@ -739,9 +755,11 @@ fun T.setGradleJdk(jdk: SdkObject): T = apply { addCommand("${CMD_PREFIX}setGradleJdk ${jdk.sdkName}|${jdk.sdkType}|${jdk.sdkPath}") } -fun T.showEvaluateExpression(expression: String = "", - performEvaluateCount: Int = 0, - warmup: Boolean = false): T = apply { +fun T.showEvaluateExpression( + expression: String = "", + performEvaluateCount: Int = 0, + warmup: Boolean = false, +): T = apply { val command = mutableListOf("${CMD_PREFIX}showEvaluateExpression") if (expression.isNotEmpty()) { command.add("-expression $expression") @@ -757,6 +775,12 @@ fun T.executeEditorAction(action: String): T = apply { addCommand("${CMD_PREFIX}executeEditorAction $action") } +fun T.moveFiles(moveFileData: MoveFilesData): T = apply { + val jsonData = objectMapper.writeValueAsString(moveFileData) + addCommand("${CMD_PREFIX}moveFiles $jsonData") +} + + fun T.copy(): T = apply { executeEditorAction("\$Copy") } @@ -941,8 +965,10 @@ enum class EnableSettingSyncOptions { GET, PUSH, NONE } -fun T.enableSettingsSync(enableCrossIdeSync: Boolean = false, - action: EnableSettingSyncOptions = EnableSettingSyncOptions.NONE): T = apply { +fun T.enableSettingsSync( + enableCrossIdeSync: Boolean = false, + action: EnableSettingSyncOptions = EnableSettingSyncOptions.NONE, +): T = apply { addCommand("${CMD_PREFIX}enableSettingsSync ${enableCrossIdeSync} ${action.name}") } diff --git a/plugins/performanceTesting/core/src/com/jetbrains/performancePlugin/BaseCommandProvider.java b/plugins/performanceTesting/core/src/com/jetbrains/performancePlugin/BaseCommandProvider.java index 94d37c91ff64..080f260ccebc 100644 --- a/plugins/performanceTesting/core/src/com/jetbrains/performancePlugin/BaseCommandProvider.java +++ b/plugins/performanceTesting/core/src/com/jetbrains/performancePlugin/BaseCommandProvider.java @@ -119,7 +119,8 @@ public final class BaseCommandProvider implements CommandProvider { Map.entry(RenameModuleCommand.PREFIX, RenameModuleCommand::new), Map.entry(WaitForProjectViewCommand.PREFIX, WaitForProjectViewCommand::new), Map.entry(ExpandProjectViewCommand.PREFIX, ExpandProjectViewCommand::new), - Map.entry(DebugToggleBreakpointCommand.PREFIX, DebugToggleBreakpointCommand::new) + Map.entry(DebugToggleBreakpointCommand.PREFIX, DebugToggleBreakpointCommand::new), + Map.entry(MoveFilesCommand.PREFIX, MoveFilesCommand::new) ); } } diff --git a/plugins/performanceTesting/core/src/com/jetbrains/performancePlugin/commands/MoveFilesCommand.kt b/plugins/performanceTesting/core/src/com/jetbrains/performancePlugin/commands/MoveFilesCommand.kt new file mode 100644 index 000000000000..df4a86f8e31e --- /dev/null +++ b/plugins/performanceTesting/core/src/com/jetbrains/performancePlugin/commands/MoveFilesCommand.kt @@ -0,0 +1,55 @@ +package com.jetbrains.performancePlugin.commands + +import com.intellij.openapi.application.EDT +import com.intellij.openapi.project.Project +import com.intellij.openapi.ui.playback.PlaybackContext +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.platform.diagnostic.telemetry.Scope +import com.intellij.platform.diagnostic.telemetry.TelemetryManager +import com.intellij.platform.diagnostic.telemetry.helpers.runWithSpan +import com.intellij.psi.PsiManager +import com.intellij.refactoring.BaseRefactoringProcessor.ConflictsInTestsException.withIgnoredConflicts +import com.intellij.refactoring.move.MoveHandler +import com.jetbrains.performancePlugin.commands.dto.MoveFilesData +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +/** + * The command moves files to new directory + * Argument is serialized [MoveFilesData] as json + * !!!Different MoveHandlerDelegates are used to move files. + * If you encounter a problem, then perhaps in your case you are using a delegate that has not been used before + */ +class MoveFilesCommand(text: String, line: Int) : PerformanceCommandCoroutineAdapter(text, line) { + companion object { + const val NAME = "moveFiles" + const val PREFIX = "$CMD_PREFIX$NAME" + } + + private fun findFile(project: Project, path: String): VirtualFile { + return OpenFileCommand.findFile(path, project) ?: throw IllegalArgumentException("File not found: $path") + } + + override suspend fun doExecute(context: PlaybackContext) { + val project = context.project + val psiManager = PsiManager.getInstance(project) + val moveFileData = deserializeOptionsFromJson(extractCommandArgument(PREFIX), MoveFilesData::class.java) + val tag = if (moveFileData.spanTag.isNotEmpty()) "_${moveFileData.spanTag}" else "" + withContext(Dispatchers.EDT) { + val files = moveFileData.files + .map { file -> findFile(project, file) } + .map { file -> psiManager.findFile(file) } + .toTypedArray() + val toDirectory = psiManager.findDirectory(findFile(project, moveFileData.toDirectory)) + runWithSpan(TelemetryManager.getTracer(Scope("MoveFiles")), "$NAME$tag") { + withIgnoredConflicts { + MoveHandler.doMove(project, files, toDirectory, null, null) + } + } + } + } + + override fun getName(): String { + return NAME + } +} diff --git a/plugins/performanceTesting/core/src/com/jetbrains/performancePlugin/commands/dto/MoveFilesData.kt b/plugins/performanceTesting/core/src/com/jetbrains/performancePlugin/commands/dto/MoveFilesData.kt new file mode 100644 index 000000000000..189ad2c34388 --- /dev/null +++ b/plugins/performanceTesting/core/src/com/jetbrains/performancePlugin/commands/dto/MoveFilesData.kt @@ -0,0 +1,3 @@ +package com.jetbrains.performancePlugin.commands.dto + +data class MoveFilesData(val files: List, val toDirectory: String, val spanTag: String)