[kotlin] Move Declarations performance test: first attempt.

GitOrigin-RevId: 067f8d0faab773a9a623867872c28856a6872520
This commit is contained in:
Alexander Chernikov
2024-09-24 21:12:08 +03:00
committed by intellij-monorepo-bot
parent 5fd079acd7
commit d81d302e01
6 changed files with 80 additions and 1 deletions

View File

@@ -0,0 +1,8 @@
package com.intellij.tools.ide.performanceTesting.commands.dto
// Exactly the same class is in `intellij.performanceTesting` module, com.jetbrains.performancePlugin.commands.dto package.
// This is done the same to MoveFilesData classes, located in the very same packages.
// Effectively Move Declarations picks 1..n declarations from the same file and moves it to another file.
// So we need to know the source file, the set of declarations (names), and the target file.
data class MoveDeclarationsData(val fromFile: String, val declarations: List<String>, val toFile: String, val spanTag: String = "")

View File

@@ -828,6 +828,11 @@ fun <T : CommandChain> T.moveFiles(moveFileData: MoveFilesData): T = apply {
addCommand("${CMD_PREFIX}moveFiles $jsonData")
}
fun <T : CommandChain> T.moveDeclarations(moveDeclarationData: MoveDeclarationsData): T = apply {
val jsonData = objectMapper.writeValueAsString(moveDeclarationData)
addCommand("${CMD_PREFIX}moveDeclarations $jsonData")
}
fun <T : CommandChain> T.performGC(): T = apply {
addCommand("${CMD_PREFIX}performGC")
}
@@ -1207,4 +1212,4 @@ fun <T : CommandChain> T.startNewSpan(spanName: String): T = apply {
fun <T : CommandChain> T.stopSpan(spanName: String): T = apply {
addCommand("${CMD_PREFIX}handleSpan $spanName")
}
}

View File

@@ -62,5 +62,6 @@
<orderEntry type="module" module-name="intellij.platform.serviceContainer" />
<orderEntry type="module" module-name="intellij.driver.client" />
<orderEntry type="module" module-name="intellij.tools.ide.starter.bus" />
<orderEntry type="library" name="kotlinc.kotlin-compiler-common" level="project" />
</component>
</module>

View File

@@ -121,6 +121,7 @@ public final class BaseCommandProvider implements CommandProvider {
Map.entry(ExpandProjectViewCommand.PREFIX, ExpandProjectViewCommand::new),
Map.entry(DebugToggleBreakpointCommand.PREFIX, DebugToggleBreakpointCommand::new),
Map.entry(MoveFilesCommand.PREFIX, MoveFilesCommand::new),
Map.entry(MoveKotlinDeclarationsCommand.PREFIX, MoveKotlinDeclarationsCommand::new),
Map.entry(GCCommand.PREFIX, GCCommand::new),
Map.entry(SetupInlineCompletionListenerCommand.PREFIX, SetupInlineCompletionListenerCommand::new),
Map.entry(CallInlineCompletionCommand.PREFIX, CallInlineCompletionCommand::new),

View File

@@ -0,0 +1,56 @@
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.use
import com.intellij.psi.PsiManager
import com.intellij.refactoring.BaseRefactoringProcessor.ConflictsInTestsException.withIgnoredConflicts
import com.intellij.refactoring.move.MoveHandler
import com.jetbrains.performancePlugin.commands.dto.MoveDeclarationsData
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtProperty
// Since we move Kotlin declarations, we have to add kotlin-compiler-common library to the module classpath.
class MoveKotlinDeclarationsCommand(text: String, line: Int) : PerformanceCommandCoroutineAdapter(text, line) {
companion object {
const val NAME = "moveDeclarations"
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 moveDeclarationData = deserializeOptionsFromJson(extractCommandArgument(PREFIX), MoveDeclarationsData::class.java)
val tag = if (moveDeclarationData.spanTag.isNotEmpty()) "_${moveDeclarationData.spanTag}" else ""
// Currently Refactor / Move with K2 supports only top-level declarations.
// We just select all top-level declarations whose names match any provided name.
withContext(Dispatchers.EDT) {
val file = findFile(project, moveDeclarationData.fromFile)
val declarations = psiManager.findFile(file)!!.children.filter {
(it is KtClass || it is KtFunction || it is KtProperty) && moveDeclarationData.declarations.contains(it.name)
}.toTypedArray()
val toFile = psiManager.findDirectory(findFile(project, moveDeclarationData.toFile))
TelemetryManager.getTracer(Scope("MoveDeclarations")).spanBuilder("$NAME$tag").use {
withIgnoredConflicts<Throwable> {
MoveHandler.doMove(project, declarations, toFile, null, null)
}
}
}
}
override fun getName(): String {
return NAME
}
}

View File

@@ -0,0 +1,8 @@
package com.jetbrains.performancePlugin.commands.dto
// Exactly the same class is in `intellij.tools.ide.performanceTesting.commands` module, com.intellij.tools.ide.performanceTesting.commands.dto package.
// This is done the same to MoveFilesData classes, located in the very same packages.
// Effectively Move Declarations picks 1..n declarations from the same file and moves it to another file.
// So we need to know the source file, the set of declarations (names), and the target file.
data class MoveDeclarationsData(val fromFile: String, val declarations: List<String>, val toFile: String, val spanTag: String)