mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[evaluation-plugin] LME-610 The refactoring to get rid of a big number of useless thread blocks
Merge-request: IJ-MR-179004 Merged-by: Roman Vasiliev <Roman.Vasiliev@jetbrains.com> GitOrigin-RevId: 2469fe2d5af7f5286bf08356cc496daad690fe55
This commit is contained in:
committed by
intellij-monorepo-bot
parent
2be04f6162
commit
2bca8e145b
@@ -2,11 +2,11 @@
|
||||
package com.intellij.cce.actions
|
||||
|
||||
import com.intellij.cce.core.CodeFragment
|
||||
import com.intellij.cce.processor.GenerateActionsProcessor
|
||||
import com.intellij.cce.processor.ActionGenerator
|
||||
import com.intellij.cce.util.FileTextUtil.computeChecksum
|
||||
|
||||
class ActionsGenerator(private val processor: GenerateActionsProcessor) {
|
||||
fun generate(code: CodeFragment): FileActions {
|
||||
class ActionsGenerator(private val processor: ActionGenerator) {
|
||||
suspend fun generate(code: CodeFragment): FileActions {
|
||||
val actions = processor.buildActions(code)
|
||||
return FileActions(code.path, computeChecksum(code.text), actions.count { it is CallFeature }, actions)
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ class FusLogsSaver(private val finalStorageDir: Path, private val allowedGroups:
|
||||
require(finalStorageDir.exists())
|
||||
}
|
||||
|
||||
override fun <T> invokeRememberingLogs(action: () -> T): T {
|
||||
override suspend fun <T> invokeRememberingLogs(action: suspend () -> T): T {
|
||||
val logFilter: (LogEvent) -> Boolean = if (allowedGroups != null) { log -> log.group.id in allowedGroups }
|
||||
else { _ -> true }
|
||||
|
||||
|
||||
@@ -12,8 +12,10 @@ import java.util.concurrent.CopyOnWriteArrayList
|
||||
import java.util.concurrent.Executor
|
||||
|
||||
object MockFUSCollector {
|
||||
fun <T> collectLogEvents(parentDisposable: Disposable,
|
||||
action: () -> T): Pair<List<LogEvent>, T> {
|
||||
suspend fun <T> collectLogEvents(
|
||||
parentDisposable: Disposable,
|
||||
action: suspend () -> T,
|
||||
): Pair<List<LogEvent>, T> {
|
||||
|
||||
val mockLoggerProvider = MockStatisticsEventLoggerProvider("ML")
|
||||
val llmcLoggerProvider = MockStatisticsEventLoggerProvider("LLMC")
|
||||
@@ -81,7 +83,7 @@ private class MockStatisticsEventLoggerProvider(recorderId: String) : Statistics
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> collectingFusLogs(logEventFilter: (LogEvent) -> Boolean, action: () -> T): Pair<T, List<LogEvent>> = Disposer.newDisposable().use { lifetime ->
|
||||
suspend fun <T> collectingFusLogs(logEventFilter: (LogEvent) -> Boolean, action: suspend () -> T): Pair<T, List<LogEvent>> = Disposer.newDisposable().use { lifetime ->
|
||||
val (allFusLogs, result) = MockFUSCollector.collectLogEvents(lifetime, action)
|
||||
val mlFusLogs: List<LogEvent> = allFusLogs.filter { logEventFilter(it) }
|
||||
result to mlFusLogs
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ class ActionInvokingInterpreter(private val invokersFactory: InvokersFactory,
|
||||
private val filter: InterpretFilter,
|
||||
private val order: InterpretationOrder) {
|
||||
|
||||
fun interpret(fileActions: FileActions, sessionHandler: (Session) -> Unit): List<Session> {
|
||||
suspend fun interpret(fileActions: FileActions, sessionHandler: (Session) -> Unit): List<Session> {
|
||||
val actionsInvoker = invokersFactory.createActionsInvoker()
|
||||
val featureInvoker = invokersFactory.createFeatureInvoker()
|
||||
val fileOpener = FileOpener(fileActions.path, actionsInvoker)
|
||||
@@ -40,7 +40,7 @@ class ActionInvokingInterpreter(private val invokersFactory: InvokersFactory,
|
||||
}
|
||||
is CallFeature -> {
|
||||
if (shouldCompleteToken) {
|
||||
val session = featureInvoker.callFeature(action.expectedText, action.offset, action.nodeProperties, action.sessionId.id)
|
||||
val session = featureInvoker.call(action.expectedText, action.offset, action.nodeProperties, action.sessionId.id)
|
||||
sessions.add(session)
|
||||
sessionHandler(session)
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ interface ActionsInvoker {
|
||||
fun delay(seconds: Int)
|
||||
fun openFile(file: String): String
|
||||
fun closeFile(file: String)
|
||||
fun optimiseImports(file: String)
|
||||
suspend fun optimiseImports(file: String)
|
||||
fun isOpen(file: String): Boolean
|
||||
fun save()
|
||||
fun getText(): String
|
||||
|
||||
+3
-5
@@ -10,14 +10,12 @@ import com.intellij.cce.evaluation.data.EvalDataDescription
|
||||
/**
|
||||
* Feature invoker that add an abstraction layer over evaluation data storage format.
|
||||
*/
|
||||
interface BindingFeatureInvoker : FeatureInvoker {
|
||||
fun invoke(properties: TokenProperties): BoundEvalData
|
||||
interface BindingFeatureInvoker : AsyncFeatureInvoker {
|
||||
suspend fun invoke(properties: TokenProperties): BoundEvalData
|
||||
|
||||
override fun callFeature(expectedText: String, offset: Int, properties: TokenProperties, sessionId: String): Session =
|
||||
override suspend fun call(expectedText: String, offset: Int, properties: TokenProperties, sessionId: String): Session =
|
||||
invoke(properties).session(expectedText, offset, properties, sessionId)
|
||||
|
||||
override fun comparator(generated: String, expected: String): Boolean = true
|
||||
|
||||
infix fun <T, B : Bindable<T>> B.bind(value: T): Binding<B> = Binding.create(this, value)
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,16 @@ package com.intellij.cce.interpreter
|
||||
import com.intellij.cce.core.Session
|
||||
import com.intellij.cce.core.TokenProperties
|
||||
|
||||
interface FeatureInvoker {
|
||||
interface AsyncFeatureInvoker {
|
||||
suspend fun call(expectedText: String, offset: Int, properties: TokenProperties, sessionId: String): Session
|
||||
}
|
||||
|
||||
interface FeatureInvoker : AsyncFeatureInvoker {
|
||||
fun callFeature(expectedText: String, offset: Int, properties: TokenProperties, sessionId: String): Session
|
||||
|
||||
fun comparator(generated: String, expected: String, ): Boolean
|
||||
|
||||
override suspend fun call(expectedText: String, offset: Int, properties: TokenProperties, sessionId: String): Session {
|
||||
return callFeature(expectedText, offset, properties, sessionId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,5 +2,5 @@ package com.intellij.cce.interpreter
|
||||
|
||||
interface InvokersFactory {
|
||||
fun createActionsInvoker(): ActionsInvoker
|
||||
fun createFeatureInvoker(): FeatureInvoker
|
||||
fun createFeatureInvoker(): AsyncFeatureInvoker
|
||||
}
|
||||
|
||||
+1
-2
@@ -11,8 +11,7 @@ import com.intellij.cce.report.CardLayout
|
||||
* The invocation result is easily presentable as a card in an evaluation report.
|
||||
*/
|
||||
interface PresentableFeatureInvoker : BindingFeatureInvoker {
|
||||
// TODO suspend to get rid of runBlockingCancellable everywhere
|
||||
override fun invoke(properties: TokenProperties): PresentableEvalData
|
||||
override suspend fun invoke(properties: TokenProperties): PresentableEvalData
|
||||
}
|
||||
|
||||
data class PresentableEvalData(
|
||||
|
||||
@@ -6,5 +6,5 @@ data class LLMJudgeResult(
|
||||
)
|
||||
|
||||
interface LLMJudge {
|
||||
fun computeLLMJudgeScoreSync(question: String, aiaResponse: String, reference: String): LLMJudgeResult
|
||||
suspend fun computeLLMJudgeScoreSync(question: String, aiaResponse: String, reference: String): LLMJudgeResult
|
||||
}
|
||||
|
||||
+1
-1
@@ -4,5 +4,5 @@ package com.intellij.cce.processor
|
||||
import com.intellij.cce.core.CodeFragment
|
||||
|
||||
interface CodeFragmentProcessor {
|
||||
fun process(code: CodeFragment) = Unit
|
||||
suspend fun processFragment(code: CodeFragment): Unit = Unit
|
||||
}
|
||||
|
||||
+2
-2
@@ -10,7 +10,7 @@ abstract class EvaluationRootProcessor : CodeFragmentProcessor {
|
||||
class DefaultEvaluationRootProcessor : EvaluationRootProcessor() {
|
||||
private var evaluationRoot: CodeFragment? = null
|
||||
|
||||
override fun process(code: CodeFragment) {
|
||||
override suspend fun processFragment(code: CodeFragment) {
|
||||
evaluationRoot = code
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ class DefaultEvaluationRootProcessor : EvaluationRootProcessor() {
|
||||
class EvaluationRootByRangeProcessor(private val startOffset: Int, private val endOffset: Int) : EvaluationRootProcessor() {
|
||||
private var evaluationRoot: CodeFragment? = null
|
||||
|
||||
override fun process(code: CodeFragment) {
|
||||
override suspend fun processFragment(code: CodeFragment) {
|
||||
evaluationRoot = CodeFragment(startOffset, endOffset - startOffset)
|
||||
evaluationRoot?.path = code.path
|
||||
evaluationRoot?.text = code.text
|
||||
|
||||
+25
-9
@@ -5,16 +5,32 @@ import com.intellij.cce.actions.Action
|
||||
import com.intellij.cce.actions.ActionsBuilder
|
||||
import com.intellij.cce.core.CodeFragment
|
||||
|
||||
abstract class GenerateActionsProcessor : CodeFragmentProcessor {
|
||||
private lateinit var actionsBuilder: ActionsBuilder
|
||||
abstract class ActionGenerator : CodeFragmentProcessor {
|
||||
protected lateinit var actionsBuilder: ActionsBuilder
|
||||
|
||||
suspend fun buildActions(code: CodeFragment): List<Action> {
|
||||
actionsBuilder = ActionsBuilder()
|
||||
processFragment(code)
|
||||
return actionsBuilder.build()
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AsyncActionGenerator : ActionGenerator() {
|
||||
open suspend fun process(code: CodeFragment): Unit = Unit
|
||||
|
||||
final override suspend fun processFragment(code: CodeFragment): Unit = process(code)
|
||||
|
||||
protected suspend fun actions(init: suspend ActionsBuilder.() -> Unit) {
|
||||
init(actionsBuilder)
|
||||
}
|
||||
}
|
||||
|
||||
abstract class GenerateActionsProcessor : ActionGenerator() {
|
||||
open fun process(code: CodeFragment): Unit = Unit
|
||||
|
||||
final override suspend fun processFragment(code: CodeFragment): Unit = process(code)
|
||||
|
||||
protected fun actions(init: ActionsBuilder.() -> Unit) {
|
||||
init(actionsBuilder)
|
||||
}
|
||||
|
||||
fun buildActions(code: CodeFragment): List<Action> {
|
||||
actionsBuilder = ActionsBuilder()
|
||||
process(code)
|
||||
return actionsBuilder.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,9 +7,10 @@ interface Progress {
|
||||
fun finish() = Unit
|
||||
fun isCanceled(): Boolean
|
||||
|
||||
fun wrapWithProgress(block: (Progress) -> Unit) {
|
||||
suspend fun <T> wrapWithProgress(block: suspend (Progress) -> T): T {
|
||||
start()
|
||||
block(this)
|
||||
val result = block(this)
|
||||
finish()
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package com.intellij.cce.workspace.storages
|
||||
|
||||
interface LogsSaver {
|
||||
fun <T> invokeRememberingLogs(action: () -> T): T
|
||||
suspend fun <T> invokeRememberingLogs(action: suspend () -> T): T
|
||||
|
||||
fun save(languageName: String?, trainingPercentage: Int)
|
||||
}
|
||||
|
||||
class NoLogsSaver : LogsSaver {
|
||||
override fun <T> invokeRememberingLogs(action: () -> T): T = action()
|
||||
override suspend fun <T> invokeRememberingLogs(action: suspend () -> T): T = action()
|
||||
|
||||
override fun save(languageName: String?, trainingPercentage: Int) = Unit
|
||||
}
|
||||
@@ -17,7 +17,7 @@ fun logsSaverIf(condition: Boolean, createSaver: () -> LogsSaver): LogsSaver = i
|
||||
private fun makeNestingCollector(saverA: LogsSaver,
|
||||
saverB: LogsSaver
|
||||
) = object : LogsSaver {
|
||||
override fun <T> invokeRememberingLogs(action: () -> T): T {
|
||||
override suspend fun <T> invokeRememberingLogs(action: suspend () -> T): T {
|
||||
return saverA.invokeRememberingLogs {
|
||||
saverB.invokeRememberingLogs(action)
|
||||
}
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ class StatLogsSaver(private val logsTemporaryStoragePath: Path, private val fina
|
||||
private val formatter = SimpleDateFormat("dd_MM_yyyy")
|
||||
private val sessionIds = linkedSetOf<String>()
|
||||
|
||||
override fun <T> invokeRememberingLogs(action: () -> T): T = action()
|
||||
override suspend fun <T> invokeRememberingLogs(action: suspend () -> T): T = action()
|
||||
|
||||
override fun save(languageName: String?, trainingPercentage: Int) {
|
||||
val logsDir = logsTemporaryStoragePath.toFile()
|
||||
|
||||
+3
-3
@@ -23,10 +23,10 @@ abstract class CodeFragmentBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
protected fun findRoot(code: CodeFragment, rootProcessor: EvaluationRootProcessor): CodeFragment {
|
||||
rootProcessor.process(code)
|
||||
protected suspend fun findRoot(code: CodeFragment, rootProcessor: EvaluationRootProcessor): CodeFragment {
|
||||
rootProcessor.processFragment(code)
|
||||
return rootProcessor.getRoot() ?: throw NullRootException(code.path)
|
||||
}
|
||||
|
||||
abstract fun build(file: VirtualFile, rootProcessor: EvaluationRootProcessor, featureName: String): CodeFragment?
|
||||
abstract suspend fun build(file: VirtualFile, rootProcessor: EvaluationRootProcessor, featureName: String): CodeFragment?
|
||||
}
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ open class CodeFragmentFromPsiBuilder(private val project: Project, val language
|
||||
|
||||
open fun getVisitors(): List<EvaluationVisitor> = EvaluationVisitor.EP_NAME.extensionList
|
||||
|
||||
override fun build(file: VirtualFile, rootProcessor: EvaluationRootProcessor, featureName: String): CodeFragment? {
|
||||
override suspend fun build(file: VirtualFile, rootProcessor: EvaluationRootProcessor, featureName: String): CodeFragment? {
|
||||
val psiFile = dumbService.runReadActionInSmartMode<PsiFile?> {
|
||||
PsiManager.getInstance(project).findFile(file)
|
||||
}
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import com.intellij.cce.util.text
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
|
||||
class CodeFragmentFromTextBuilder : CodeFragmentBuilder() {
|
||||
override fun build(file: VirtualFile, rootProcessor: EvaluationRootProcessor, featureName: String): CodeFragment {
|
||||
override suspend fun build(file: VirtualFile, rootProcessor: EvaluationRootProcessor, featureName: String): CodeFragment {
|
||||
val text = file.text()
|
||||
val codeFragment = CodeFragment(0, text.length)
|
||||
codeFragment.text = text
|
||||
|
||||
+38
-19
@@ -20,12 +20,12 @@ import com.intellij.cce.evaluation.FinishEvaluationStep
|
||||
import com.intellij.cce.evaluation.allPreliminarySteps
|
||||
import com.intellij.cce.evaluation.step.ReportGenerationStep
|
||||
import com.intellij.cce.evaluation.step.SetupStatsCollectorStep
|
||||
import com.intellij.cce.evaluation.step.runInIntellij
|
||||
import com.intellij.cce.evaluation.step.run
|
||||
import com.intellij.cce.util.ExceptionsUtil.stackTraceToString
|
||||
import com.intellij.cce.workspace.Config
|
||||
import com.intellij.cce.workspace.ConfigFactory
|
||||
import com.intellij.cce.workspace.EvaluationWorkspace
|
||||
import com.intellij.openapi.application.ApplicationStarter
|
||||
import com.intellij.openapi.application.ModernApplicationStarter
|
||||
import com.intellij.openapi.application.ex.ApplicationEx.FORCE_EXIT
|
||||
import com.intellij.openapi.application.ex.ApplicationManagerEx
|
||||
import com.intellij.openapi.diagnostic.currentClassLogger
|
||||
@@ -35,12 +35,9 @@ import kotlin.io.path.exists
|
||||
import kotlin.io.path.isDirectory
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
internal class CompletionEvaluationStarter : ApplicationStarter {
|
||||
override val requiredModality: Int
|
||||
get() = ApplicationStarter.NOT_IN_EDT
|
||||
|
||||
override fun main(args: List<String>) {
|
||||
fun run() = MainEvaluationCommand("ml-evaluate")
|
||||
internal class CompletionEvaluationStarter : ModernApplicationStarter() {
|
||||
override suspend fun start(args: List<String>) {
|
||||
val command = MainEvaluationCommand("ml-evaluate")
|
||||
.subcommands(
|
||||
FullCommand(),
|
||||
GenerateActionsCommand(),
|
||||
@@ -55,11 +52,16 @@ internal class CompletionEvaluationStarter : ApplicationStarter {
|
||||
it.extend(command)
|
||||
}
|
||||
}
|
||||
.main(args.toList().subList(1, args.size))
|
||||
|
||||
val startTimestamp = System.currentTimeMillis()
|
||||
try {
|
||||
run()
|
||||
command.main(args.toList().subList(1, args.size))
|
||||
for (subcommand in command.registeredSubcommands()) {
|
||||
if (subcommand is EvaluationCommand) {
|
||||
subcommand.postponedRun()
|
||||
}
|
||||
}
|
||||
|
||||
val delta = 5_000 - (System.currentTimeMillis() - startTimestamp)
|
||||
if (delta > 0) {
|
||||
Thread.sleep(delta) // for graceful shutdown
|
||||
@@ -78,6 +80,8 @@ internal class CompletionEvaluationStarter : ApplicationStarter {
|
||||
|
||||
protected val featureName by argument(name = "Feature name").default("rename")
|
||||
|
||||
private var postponed: Boolean = false
|
||||
|
||||
protected fun <T : EvaluationStrategy> loadConfig(configPath: Path, strategySerializer: StrategySerializer<T>): Config {
|
||||
try {
|
||||
println("Load config: $configPath")
|
||||
@@ -91,25 +95,40 @@ internal class CompletionEvaluationStarter : ApplicationStarter {
|
||||
}
|
||||
}
|
||||
|
||||
protected fun runPreliminarySteps(feature: EvaluableFeature<*>, workspace: EvaluationWorkspace) {
|
||||
abstract suspend fun asyncRun()
|
||||
|
||||
final override fun run() {
|
||||
// Clikt doesn't support async execution. And there is no way to get the selected command.
|
||||
// So in this blocking method we only save the intention to run the command.
|
||||
// Actual execution should be performed later with the postponedRun method.
|
||||
postponed = true
|
||||
}
|
||||
|
||||
suspend fun postponedRun() {
|
||||
if (postponed) {
|
||||
asyncRun()
|
||||
}
|
||||
}
|
||||
|
||||
protected suspend fun runPreliminarySteps(feature: EvaluableFeature<*>, workspace: EvaluationWorkspace) {
|
||||
for (step in allPreliminarySteps(feature)) {
|
||||
println("Starting preliminary step: ${step.name}")
|
||||
step.runInIntellij(null, workspace)
|
||||
step.run(workspace)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MainEvaluationCommand(name: String) : EvaluationCommand(name, "Evaluate code completion quality in headless mode") {
|
||||
override fun run() = Unit
|
||||
override suspend fun asyncRun() = Unit
|
||||
}
|
||||
|
||||
abstract class EvaluationCommandBase(name: String, help: String) : EvaluationCommand(name, help) {
|
||||
private val configPath by argument(name = "config-path", help = "Path to config").default(ConfigFactory.DEFAULT_CONFIG_NAME)
|
||||
|
||||
override fun run() {
|
||||
override suspend fun asyncRun() {
|
||||
val feature = EvaluableFeature.forFeature(featureName) ?: throw Exception("No support for the $featureName")
|
||||
val config = loadConfig(Paths.get(configPath), feature.getStrategySerializer())
|
||||
val workspace = EvaluationWorkspace.create(config, SetupStatsCollectorStep.statsCollectorLogsDirectory)
|
||||
val workspace = EvaluationWorkspace.create(config, SetupStatsCollectorStep.statsCollectorLogsDirectory, debug = true)
|
||||
val datasetContext = DatasetContext(workspace, workspace, configPath)
|
||||
runPreliminarySteps(feature, workspace)
|
||||
feature.prepareEnvironment(config, workspace).use { environment ->
|
||||
@@ -147,7 +166,7 @@ internal class CompletionEvaluationStarter : ApplicationStarter {
|
||||
private val generateReport by option(names = arrayOf("--generate-report", "-r"), help = "Generate report").flag()
|
||||
private val reorderElements by option(names = arrayOf("--reorder-elements", "-e"), help = "Reorder elements").flag()
|
||||
|
||||
override fun run() {
|
||||
override suspend fun asyncRun() {
|
||||
val feature = EvaluableFeature.forFeature(featureName) ?: throw Exception("No support for the feature")
|
||||
val workspace = EvaluationWorkspace.open(workspacePath, SetupStatsCollectorStep.statsCollectorLogsDirectory)
|
||||
val datasetContext = DatasetContext(workspace, workspace, null)
|
||||
@@ -170,7 +189,7 @@ internal class CompletionEvaluationStarter : ApplicationStarter {
|
||||
|
||||
abstract fun getWorkspaces(): List<String>
|
||||
|
||||
override fun run() {
|
||||
override suspend fun asyncRun() {
|
||||
val workspacesToCompare = getWorkspaces()
|
||||
val feature = EvaluableFeature.forFeature(featureName) ?: throw Exception("No support for the feature")
|
||||
val config = workspacesToCompare.map { EvaluationWorkspace.open(it, SetupStatsCollectorStep.statsCollectorLogsDirectory) }.buildMultipleEvaluationsConfig(
|
||||
@@ -207,7 +226,7 @@ internal class CompletionEvaluationStarter : ApplicationStarter {
|
||||
help = "Generate merged report for all evaluation workspaces in a directory") {
|
||||
private val root by argument(name = "directory", help = "Root directory for evaluation workspaces")
|
||||
|
||||
override fun run() {
|
||||
override suspend fun asyncRun() {
|
||||
val workspacesToMerge = readWorkspacesFromDirectory(root)
|
||||
val feature = EvaluableFeature.forFeature(featureName) ?: throw Exception("No support for the feature")
|
||||
val config = workspacesToMerge.map { EvaluationWorkspace.open(it, SetupStatsCollectorStep.statsCollectorLogsDirectory) }.buildMultipleEvaluationsConfig(
|
||||
@@ -234,7 +253,7 @@ internal class CompletionEvaluationStarter : ApplicationStarter {
|
||||
feature,
|
||||
)
|
||||
|
||||
step.runInIntellij(null, outputWorkspace)
|
||||
step.run(outputWorkspace)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+13
-11
@@ -18,7 +18,8 @@ import com.intellij.cce.filter.EvaluationFilter
|
||||
import com.intellij.cce.filter.EvaluationFilterReader
|
||||
import com.intellij.cce.interpreter.FeatureInvoker
|
||||
import com.intellij.cce.metric.Metric
|
||||
import com.intellij.cce.processor.GenerateActionsProcessor
|
||||
import com.intellij.cce.processor.ActionGenerator
|
||||
import com.intellij.cce.processor.AsyncActionGenerator
|
||||
import com.intellij.cce.report.GeneratorDirectories
|
||||
import com.intellij.cce.report.MultiLineFileReportGenerator
|
||||
import com.intellij.cce.util.FilesHelper
|
||||
@@ -29,6 +30,7 @@ import com.intellij.cce.workspace.ConfigFactory
|
||||
import com.intellij.cce.workspace.EvaluationWorkspace
|
||||
import com.intellij.cce.workspace.storages.FeaturesStorage
|
||||
import com.intellij.cce.workspace.storages.FullLineLogsStorage
|
||||
import com.intellij.openapi.application.readAction
|
||||
import com.intellij.openapi.application.runInEdt
|
||||
import com.intellij.openapi.application.runReadAction
|
||||
import com.intellij.openapi.editor.Document
|
||||
@@ -52,7 +54,7 @@ internal class ContextCollectionEvaluationCommand : CompletionEvaluationStarter.
|
||||
help = "Path to config"
|
||||
).default(ConfigFactory.DEFAULT_CONFIG_NAME)
|
||||
|
||||
override fun run() {
|
||||
override suspend fun asyncRun() {
|
||||
val feature = EvaluableFeature.forFeature(featureName) ?: error("There is no support for the $featureName")
|
||||
val config = loadConfig(Paths.get(configPath), feature.getStrategySerializer())
|
||||
val workspace = EvaluationWorkspace.create(config, SetupStatsCollectorStep.statsCollectorLogsDirectory)
|
||||
@@ -73,10 +75,10 @@ internal class ContextCollectionEvaluationCommand : CompletionEvaluationStarter.
|
||||
feature.name,
|
||||
environment.featureInvoker
|
||||
) {
|
||||
override fun prepareDataset(datasetContext: DatasetContext, progress: Progress) {
|
||||
val files = runReadAction {
|
||||
FilesHelper.getFilesOfLanguage(project, actions.evaluationRoots, actions.ignoreFileNames, actions.language)
|
||||
}.sortedBy { it.name }
|
||||
override suspend fun prepareDataset(datasetContext: DatasetContext, progress: Progress) {
|
||||
val files = readAction {
|
||||
FilesHelper.getFilesOfLanguage(project, actions.evaluationRoots, actions.ignoreFileNames, actions.language).sortedBy { it.name }
|
||||
}
|
||||
val strategy = config.strategy as CompletionContextCollectionStrategy
|
||||
val sampled = files.shuffled(Random(strategy.samplingSeed)).take(strategy.samplesCount).sortedBy { it.name }
|
||||
generateActions(datasetContext, actions.language, sampled, evaluationRootInfo, progress)
|
||||
@@ -142,12 +144,12 @@ private class ContextCollectionActionsInvoker(
|
||||
}
|
||||
}
|
||||
|
||||
private class ContextCollectionMultiLineProcessor(private val strategy: CompletionContextCollectionStrategy) : GenerateActionsProcessor() {
|
||||
override fun process(code: CodeFragment) {
|
||||
private class ContextCollectionMultiLineProcessor(private val strategy: CompletionContextCollectionStrategy) : AsyncActionGenerator() {
|
||||
override suspend fun process(code: CodeFragment) {
|
||||
actions {
|
||||
runReadAction {
|
||||
readAction {
|
||||
check(code is CodeFragmentWithPsi)
|
||||
val file = code.psi.dereference() as? PsiFile ?: return@runReadAction
|
||||
val file = code.psi.dereference() as? PsiFile ?: return@readAction
|
||||
val project = file.project
|
||||
val document = PsiDocumentManager.getInstance(project).getDocument(file)
|
||||
checkNotNull(document) { "There should've been a document instance for $file (${file.virtualFile})" }
|
||||
@@ -278,7 +280,7 @@ private class ContextCollectionStrategySerializer : StrategySerializer<Completio
|
||||
}
|
||||
|
||||
internal class ContextCollectionFeature : EvaluableFeatureBase<CompletionContextCollectionStrategy>("completion-context") {
|
||||
override fun getGenerateActionsProcessor(strategy: CompletionContextCollectionStrategy, project: Project): GenerateActionsProcessor {
|
||||
override fun getGenerateActionsProcessor(strategy: CompletionContextCollectionStrategy, project: Project): ActionGenerator {
|
||||
return ContextCollectionMultiLineProcessor(strategy)
|
||||
}
|
||||
|
||||
|
||||
@@ -12,12 +12,12 @@ class CsvEnvironment(
|
||||
override val datasetRef: DatasetRef,
|
||||
private val chunkSize: Int,
|
||||
private val targetField: String,
|
||||
private val featureInvoker: FeatureInvoker,
|
||||
private val featureInvoker: AsyncFeatureInvoker,
|
||||
) : SimpleFileEnvironment {
|
||||
|
||||
override val preparationDescription: String = "Checking that CSV file exists"
|
||||
|
||||
override fun initialize(datasetContext: DatasetContext) {
|
||||
override suspend fun initialize(datasetContext: DatasetContext) {
|
||||
super.initialize(datasetContext)
|
||||
|
||||
val datasetPath = datasetContext.path(datasetRef)
|
||||
@@ -49,7 +49,7 @@ class CsvEnvironment(
|
||||
val (target, features) = props.value
|
||||
val call = callFeature(target, props.offset, features)
|
||||
ChunkHelper.Result(
|
||||
featureInvoker.callFeature(call.expectedText, call.offset, call.nodeProperties, call.sessionId.id),
|
||||
featureInvoker.call(call.expectedText, call.offset, call.nodeProperties, call.sessionId.id),
|
||||
"$target <- ${features.toList().joinToString(", ") { "${it.first} = ${it.second}" }}",
|
||||
call
|
||||
)
|
||||
|
||||
@@ -11,7 +11,7 @@ sealed interface DatasetRef {
|
||||
|
||||
val name: String
|
||||
|
||||
fun prepare(datasetContext: DatasetContext)
|
||||
suspend fun prepare(datasetContext: DatasetContext)
|
||||
|
||||
fun resultPath(datasetContext: DatasetContext): Path = datasetContext.path(name)
|
||||
|
||||
@@ -58,7 +58,7 @@ sealed interface DatasetRef {
|
||||
internal data class AbsoluteRef(val relativePath: String) : DatasetRef {
|
||||
override val name: String = Path.of(relativePath).name.toString()
|
||||
|
||||
override fun prepare(datasetContext: DatasetContext) {
|
||||
override suspend fun prepare(datasetContext: DatasetContext) {
|
||||
val path = resultPath(datasetContext)
|
||||
check(path.exists()) {
|
||||
"Path ${relativePath} doesn't exist: ${path.absolutePathString()}"
|
||||
@@ -71,7 +71,7 @@ internal data class AbsoluteRef(val relativePath: String) : DatasetRef {
|
||||
internal data class ConfigRelativeRef(val relativePath: String) : DatasetRef {
|
||||
override val name: String = Path.of(relativePath).normalize().toString()
|
||||
|
||||
override fun prepare(datasetContext: DatasetContext) {
|
||||
override suspend fun prepare(datasetContext: DatasetContext) {
|
||||
val path = resultPath(datasetContext)
|
||||
|
||||
check(path.exists()) {
|
||||
@@ -90,7 +90,7 @@ internal data class ConfigRelativeRef(val relativePath: String) : DatasetRef {
|
||||
}
|
||||
|
||||
internal data class ExistingRef(override val name: String) : DatasetRef {
|
||||
override fun prepare(datasetContext: DatasetContext) {
|
||||
override suspend fun prepare(datasetContext: DatasetContext) {
|
||||
val path = datasetContext.path(name)
|
||||
|
||||
check(path.exists()) {
|
||||
@@ -112,7 +112,7 @@ internal data class RemoteFileRef(private val url: String) : DatasetRef {
|
||||
}
|
||||
}
|
||||
|
||||
override fun prepare(datasetContext: DatasetContext) {
|
||||
override suspend fun prepare(datasetContext: DatasetContext) {
|
||||
val path = datasetContext.path(name)
|
||||
|
||||
if (path.exists()) {
|
||||
@@ -145,7 +145,7 @@ internal data class RemoteFileRef(private val url: String) : DatasetRef {
|
||||
}
|
||||
|
||||
internal data class AiPlatformFileRef(override val name: String): DatasetRef {
|
||||
override fun prepare(datasetContext: DatasetContext) { }
|
||||
override suspend fun prepare(datasetContext: DatasetContext) { }
|
||||
}
|
||||
|
||||
private val LOG = fileLogger()
|
||||
+11
-19
@@ -4,15 +4,11 @@ package com.intellij.cce.actions
|
||||
import com.intellij.cce.core.*
|
||||
import com.intellij.cce.evaluable.EvaluationStrategy
|
||||
import com.intellij.cce.evaluable.common.CommonActionsInvoker
|
||||
import com.intellij.cce.evaluation.EvaluationChunk
|
||||
import com.intellij.cce.evaluation.EvaluationEnvironment
|
||||
import com.intellij.cce.evaluation.EvaluationRootInfo
|
||||
import com.intellij.cce.evaluation.EvaluationStep
|
||||
import com.intellij.cce.evaluation.step.runInIntellij
|
||||
import com.intellij.cce.evaluation.*
|
||||
import com.intellij.cce.interpreter.*
|
||||
import com.intellij.cce.processor.ActionGenerator
|
||||
import com.intellij.cce.processor.DefaultEvaluationRootProcessor
|
||||
import com.intellij.cce.processor.EvaluationRootByRangeProcessor
|
||||
import com.intellij.cce.processor.GenerateActionsProcessor
|
||||
import com.intellij.cce.util.ExceptionsUtil.stackTraceToString
|
||||
import com.intellij.cce.util.FilesHelper
|
||||
import com.intellij.cce.util.Progress
|
||||
@@ -20,12 +16,11 @@ import com.intellij.cce.util.Summary
|
||||
import com.intellij.cce.util.text
|
||||
import com.intellij.cce.visitor.CodeFragmentBuilder
|
||||
import com.intellij.cce.workspace.Config
|
||||
import com.intellij.cce.workspace.EvaluationWorkspace
|
||||
import com.intellij.cce.workspace.info.FileErrorInfo
|
||||
import com.intellij.cce.workspace.storages.storage.ActionsSingleFileStorage
|
||||
import com.intellij.configurationStore.StoreUtil.saveSettings
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.ReadAction
|
||||
import com.intellij.openapi.application.readAction
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
@@ -39,10 +34,10 @@ open class ProjectActionsEnvironment(
|
||||
private val sessionsLimit: Int?,
|
||||
private val evaluationRootInfo: EvaluationRootInfo,
|
||||
val project: Project,
|
||||
val processor: GenerateActionsProcessor,
|
||||
val processor: ActionGenerator,
|
||||
override val setupSteps: List<EvaluationStep>,
|
||||
private val featureName: String,
|
||||
val featureInvoker: FeatureInvoker,
|
||||
val featureInvoker: AsyncFeatureInvoker,
|
||||
) : EvaluationEnvironment {
|
||||
private val datasetRef = config.sourceFile.run {
|
||||
val sf = this ?: ""
|
||||
@@ -56,17 +51,17 @@ open class ProjectActionsEnvironment(
|
||||
|
||||
override val preparationDescription: String = "Generating actions by selected files"
|
||||
|
||||
override fun initialize(datasetContext: DatasetContext) {
|
||||
override suspend fun initialize(datasetContext: DatasetContext) {
|
||||
datasetRef?.prepare(datasetContext)
|
||||
}
|
||||
|
||||
override fun prepareDataset(datasetContext: DatasetContext, progress: Progress) {
|
||||
override suspend fun prepareDataset(datasetContext: DatasetContext, progress: Progress) {
|
||||
if (datasetRef != null) {
|
||||
val finalPath = DatasetRefConverter().convert(datasetRef, datasetContext, project) ?: datasetContext.path(datasetRef)
|
||||
datasetContext.replaceActionsStorage(ActionsSingleFileStorage(finalPath))
|
||||
}
|
||||
else {
|
||||
val filesForEvaluation = ReadAction.compute<List<VirtualFile>, Throwable> {
|
||||
val filesForEvaluation = readAction {
|
||||
FilesHelper.getFilesOfLanguage(project, config.evaluationRoots, config.ignoreFileNames, config.language)
|
||||
}
|
||||
|
||||
@@ -99,7 +94,7 @@ open class ProjectActionsEnvironment(
|
||||
}
|
||||
}
|
||||
|
||||
protected fun generateActions(
|
||||
protected suspend fun generateActions(
|
||||
datasetContext: DatasetContext,
|
||||
languageName: String?,
|
||||
files: Collection<VirtualFile>,
|
||||
@@ -171,9 +166,6 @@ open class ProjectActionsEnvironment(
|
||||
actionsSummarizer.save(datasetContext)
|
||||
}
|
||||
|
||||
override fun execute(step: EvaluationStep, workspace: EvaluationWorkspace): EvaluationWorkspace? =
|
||||
step.runInIntellij(project, workspace)
|
||||
|
||||
override fun close() {
|
||||
ProjectOpeningUtils.closeProject(project)
|
||||
|
||||
@@ -248,7 +240,7 @@ open class ProjectActionsEnvironment(
|
||||
override val name: String = fileActions.path
|
||||
override val sessionsExist: Boolean = fileActions.sessionsCount > 0
|
||||
|
||||
override fun evaluate(
|
||||
override suspend fun evaluate(
|
||||
handler: InterpretationHandler,
|
||||
filter: InterpretFilter,
|
||||
order: InterpretationOrder,
|
||||
@@ -256,7 +248,7 @@ open class ProjectActionsEnvironment(
|
||||
): EvaluationChunk.Result {
|
||||
val factory = object : InvokersFactory {
|
||||
override fun createActionsInvoker(): ActionsInvoker = CommonActionsInvoker(project)
|
||||
override fun createFeatureInvoker(): FeatureInvoker = featureInvoker
|
||||
override fun createFeatureInvoker(): AsyncFeatureInvoker = featureInvoker
|
||||
}
|
||||
val actionInterpreter = ActionInvokingInterpreter(factory, handler, filter, order)
|
||||
return EvaluationChunk.Result(
|
||||
|
||||
@@ -28,14 +28,14 @@ class ChunkHelper(
|
||||
fun <T> chunks(
|
||||
chunkSize: Int,
|
||||
entities: Sequence<T>,
|
||||
evaluate: ChunkHelper.(Props<T>) -> Result,
|
||||
evaluate: suspend ChunkHelper.(Props<T>) -> Result,
|
||||
): Sequence<EvaluationChunk> {
|
||||
return entities.chunked(chunkSize).mapIndexed { index, values ->
|
||||
object : EvaluationChunk {
|
||||
override val datasetName: String = this@ChunkHelper.datasetName
|
||||
override val name: String = "${chunkNamePrefix}:${chunkSize * index}-${chunkSize * index + values.size - 1}"
|
||||
|
||||
override fun evaluate(
|
||||
override suspend fun evaluate(
|
||||
handler: InterpretationHandler,
|
||||
filter: InterpretFilter,
|
||||
order: InterpretationOrder,
|
||||
@@ -81,7 +81,7 @@ class ChunkHelper(
|
||||
layoutManager: LayoutManager,
|
||||
chunkSize: Int,
|
||||
entities: Sequence<T>,
|
||||
evaluate: ChunkHelper.(Props<T>) -> PresentableResult,
|
||||
evaluate: suspend ChunkHelper.(Props<T>) -> PresentableResult,
|
||||
): Sequence<EvaluationChunk> {
|
||||
return chunks(chunkSize, entities) { props ->
|
||||
var call: CallFeature? = null
|
||||
@@ -111,7 +111,7 @@ class ChunkHelper(
|
||||
|
||||
fun presentableChunk(
|
||||
layoutManager: LayoutManager,
|
||||
evaluate: ChunkHelper.(Props<Unit>) -> PresentableResult
|
||||
evaluate: suspend ChunkHelper.(Props<Unit>) -> PresentableResult
|
||||
): Sequence<EvaluationChunk> = presentableChunks(layoutManager, 1, sequenceOf(Unit)) { evaluate(it) }
|
||||
|
||||
fun callFeature(target: String, offset: Int, features: Map<String, String>): CallFeature {
|
||||
|
||||
@@ -10,8 +10,8 @@ import com.intellij.cce.evaluation.SetupSdkPreferences
|
||||
import com.intellij.cce.evaluation.SetupSdkStepFactory
|
||||
import com.intellij.cce.evaluation.step.CheckProjectSdkStep
|
||||
import com.intellij.cce.evaluation.step.DropProjectSdkStep
|
||||
import com.intellij.cce.interpreter.FeatureInvoker
|
||||
import com.intellij.cce.processor.GenerateActionsProcessor
|
||||
import com.intellij.cce.interpreter.AsyncFeatureInvoker
|
||||
import com.intellij.cce.processor.ActionGenerator
|
||||
import com.intellij.cce.report.BasicFileReportGenerator
|
||||
import com.intellij.cce.report.FileReportGenerator
|
||||
import com.intellij.cce.report.GeneratorDirectories
|
||||
@@ -30,12 +30,12 @@ abstract class EvaluableFeatureBase<T : EvaluationStrategy>(override val name: S
|
||||
/**
|
||||
* how to prepare the context before the feature invocation
|
||||
*/
|
||||
abstract fun getGenerateActionsProcessor(strategy: T, project: Project): GenerateActionsProcessor
|
||||
abstract fun getGenerateActionsProcessor(strategy: T, project: Project): ActionGenerator
|
||||
|
||||
/**
|
||||
* how to call the feature
|
||||
*/
|
||||
abstract fun getFeatureInvoker(project: Project, language: Language, strategy: T): FeatureInvoker
|
||||
abstract fun getFeatureInvoker(project: Project, language: Language, strategy: T): AsyncFeatureInvoker
|
||||
|
||||
abstract fun getEvaluationSteps(language: Language, strategy: T): List<EvaluationStep>
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ import com.intellij.cce.report.FileReportGenerator
|
||||
import com.intellij.cce.report.GeneratorDirectories
|
||||
import com.intellij.cce.workspace.Config
|
||||
import com.intellij.cce.workspace.EvaluationWorkspace
|
||||
import com.intellij.openapi.progress.runBlockingCancellable
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
/**
|
||||
@@ -56,11 +55,9 @@ class LayoutManager(
|
||||
) {
|
||||
private val globalLayout = AtomicReference(workspace.layout)
|
||||
|
||||
fun processData(f: suspend () -> PresentableEvalData): PresentableEvalData {
|
||||
val data = runBlockingCancellable {
|
||||
PresentableEvalData.augment(augmenters) {
|
||||
f()
|
||||
}
|
||||
suspend fun processData(f: suspend () -> PresentableEvalData): PresentableEvalData {
|
||||
val data = PresentableEvalData.augment(augmenters) {
|
||||
f()
|
||||
}
|
||||
try {
|
||||
processData(data)
|
||||
|
||||
+3
-3
@@ -16,7 +16,6 @@ import com.intellij.openapi.editor.impl.TrailingSpacesStripper
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager
|
||||
import com.intellij.openapi.fileEditor.OpenFileDescriptor
|
||||
import com.intellij.openapi.progress.runBlockingCancellable
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
@@ -29,6 +28,7 @@ import com.intellij.util.progress.sleepCancellable
|
||||
import java.io.File
|
||||
import java.nio.file.Paths
|
||||
|
||||
// TODO rewrite without blocking
|
||||
class CommonActionsInvoker(private val project: Project) : ActionsInvoker {
|
||||
init {
|
||||
TestModeFlags.set(CompletionAutoPopupHandler.ourTestingAutopopup, true)
|
||||
@@ -126,10 +126,10 @@ class CommonActionsInvoker(private val project: Project) : ActionsInvoker {
|
||||
FileEditorManager.getInstance(project).closeFile(virtualFile)
|
||||
}
|
||||
|
||||
override fun optimiseImports(file: String) {
|
||||
override suspend fun optimiseImports(file: String) {
|
||||
LOG.info("Optimise imports in file: $file")
|
||||
val virtualFile = LocalFileSystem.getInstance().findFileByIoFile(File(fullPath(file)))!!
|
||||
return runBlockingCancellable { ImportOptimiser.optimiseImports(project, virtualFile) }
|
||||
return ImportOptimiser.optimiseImports(project, virtualFile)
|
||||
}
|
||||
|
||||
override fun isOpen(file: String): Boolean = readActionInSmartMode(project) {
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ class ConflictEnvironment(
|
||||
override val name: String = "${fileConflict.hash} - ${fileConflict.fileName}"
|
||||
override val datasetName: String = datasetRef.name
|
||||
|
||||
override fun evaluate(
|
||||
override suspend fun evaluate(
|
||||
handler: InterpretationHandler,
|
||||
filter: InterpretFilter, // TODO should we use it somehow?
|
||||
order: InterpretationOrder, // TODO should we use somehow?
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ class ActionsInterpretationHandler(
|
||||
logsSaverIf(config.interpret.saveFusLogs) { workspace.fusLogsSaver }
|
||||
).asCompositeLogsSaver()
|
||||
|
||||
fun invoke(environment: EvaluationEnvironment, workspace: EvaluationWorkspace, indicator: Progress) {
|
||||
suspend fun invoke(environment: EvaluationEnvironment, workspace: EvaluationWorkspace, indicator: Progress) {
|
||||
var sessionsCount: Int
|
||||
val computingTime = measureTimeMillis {
|
||||
sessionsCount = environment.sessionCount(datasetContext)
|
||||
|
||||
@@ -14,7 +14,7 @@ interface EvaluationChunk {
|
||||
|
||||
val sessionsExist: Boolean get() = true
|
||||
|
||||
fun evaluate(
|
||||
suspend fun evaluate(
|
||||
handler: InterpretationHandler,
|
||||
filter: InterpretFilter,
|
||||
order: InterpretationOrder,
|
||||
|
||||
@@ -4,9 +4,7 @@ import com.intellij.cce.actions.DatasetContext
|
||||
import com.intellij.cce.actions.DatasetRef
|
||||
import com.intellij.cce.evaluation.data.Bindable
|
||||
import com.intellij.cce.evaluation.data.Binding
|
||||
import com.intellij.cce.evaluation.step.runInIntellij
|
||||
import com.intellij.cce.util.Progress
|
||||
import com.intellij.cce.workspace.EvaluationWorkspace
|
||||
|
||||
/**
|
||||
* Environment represents resources needed for an evaluation.
|
||||
@@ -19,17 +17,15 @@ interface EvaluationEnvironment : AutoCloseable {
|
||||
|
||||
val preparationDescription: String
|
||||
|
||||
fun initialize(datasetContext: DatasetContext)
|
||||
suspend fun initialize(datasetContext: DatasetContext)
|
||||
|
||||
fun prepareDataset(datasetContext: DatasetContext, progress: Progress)
|
||||
suspend fun prepareDataset(datasetContext: DatasetContext, progress: Progress)
|
||||
|
||||
fun sessionCount(datasetContext: DatasetContext): Int
|
||||
|
||||
// TODO should return something closeable for large files
|
||||
fun chunks(datasetContext: DatasetContext): Sequence<EvaluationChunk>
|
||||
|
||||
fun execute(step: EvaluationStep, workspace: EvaluationWorkspace): EvaluationWorkspace?
|
||||
|
||||
// place here just for convenience, should be final protected by meaning
|
||||
infix fun <T, B : Bindable<T>> B.bind(value: T): Binding<B> = Binding.create(this, value)
|
||||
}
|
||||
@@ -42,16 +38,13 @@ interface SimpleFileEnvironment : EvaluationEnvironment {
|
||||
|
||||
override val preparationDescription: String get() = "Checking that dataset file is available"
|
||||
|
||||
override fun initialize(datasetContext: DatasetContext) {
|
||||
override suspend fun initialize(datasetContext: DatasetContext) {
|
||||
datasetRef.prepare(datasetContext)
|
||||
}
|
||||
|
||||
override fun prepareDataset(datasetContext: DatasetContext, progress: Progress) {
|
||||
override suspend fun prepareDataset(datasetContext: DatasetContext, progress: Progress) {
|
||||
}
|
||||
|
||||
override fun execute(step: EvaluationStep, workspace: EvaluationWorkspace): EvaluationWorkspace? =
|
||||
step.runInIntellij(null, workspace)
|
||||
|
||||
override fun close() {
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,25 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.cce.evaluation
|
||||
|
||||
import com.intellij.cce.evaluation.step.run
|
||||
import com.intellij.cce.workspace.EvaluationWorkspace
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
class EvaluationProcess private constructor (
|
||||
private val environment: EvaluationEnvironment,
|
||||
private val steps: List<EvaluationStep>,
|
||||
private val finalStep: FinishEvaluationStep?
|
||||
) {
|
||||
companion object {
|
||||
fun build(environment: EvaluationEnvironment, stepFactory: StepFactory, init: Builder.() -> Unit): EvaluationProcess {
|
||||
suspend fun build(environment: EvaluationEnvironment, stepFactory: StepFactory, init: Builder.() -> Unit): EvaluationProcess {
|
||||
environment.initialize(stepFactory.datasetContext)
|
||||
val builder = Builder()
|
||||
builder.init()
|
||||
return builder.build(environment, stepFactory)
|
||||
return builder.build(stepFactory)
|
||||
}
|
||||
}
|
||||
|
||||
fun start(workspace: EvaluationWorkspace): EvaluationWorkspace {
|
||||
suspend fun start(workspace: EvaluationWorkspace): EvaluationWorkspace {
|
||||
val stats = mutableMapOf<String, Long>()
|
||||
var currentWorkspace = workspace
|
||||
var hasError = false
|
||||
@@ -27,7 +27,7 @@ class EvaluationProcess private constructor (
|
||||
if (hasError && step !is UndoableEvaluationStep.UndoStep) continue
|
||||
println("Starting step: ${step.name} (${step.description})")
|
||||
val duration = measureTimeMillis {
|
||||
val result = environment.execute(step, currentWorkspace)
|
||||
val result = step.run(currentWorkspace)
|
||||
if (result == null) {
|
||||
hasError = true
|
||||
} else {
|
||||
@@ -47,7 +47,7 @@ class EvaluationProcess private constructor (
|
||||
var shouldGenerateReports: Boolean = false
|
||||
var shouldReorderElements: Boolean = false
|
||||
|
||||
fun build(environment: EvaluationEnvironment, factory: StepFactory): EvaluationProcess {
|
||||
fun build(factory: StepFactory): EvaluationProcess {
|
||||
val steps = mutableListOf<EvaluationStep>()
|
||||
val isTestingEnvironment = ApplicationManager.getApplication().isUnitTestMode
|
||||
|
||||
@@ -92,7 +92,7 @@ class EvaluationProcess private constructor (
|
||||
steps.add(step.undoStep())
|
||||
}
|
||||
|
||||
return EvaluationProcess(environment, steps, factory.finishEvaluationStep().takeIf { !isTestingEnvironment })
|
||||
return EvaluationProcess(steps, factory.finishEvaluationStep().takeIf { !isTestingEnvironment })
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -18,7 +18,7 @@ class ActionsInterpretationStep(
|
||||
|
||||
override val description: String = "Interpretation of generated actions"
|
||||
|
||||
override fun runInBackground(workspace: EvaluationWorkspace, progress: Progress): EvaluationWorkspace {
|
||||
override suspend fun runInBackground(workspace: EvaluationWorkspace, progress: Progress): EvaluationWorkspace {
|
||||
val resultWorkspace =
|
||||
if (newWorkspace) EvaluationWorkspace.create(config, SetupStatsCollectorStep.statsCollectorLogsDirectory)
|
||||
else workspace
|
||||
|
||||
+12
-24
@@ -9,41 +9,29 @@ import com.intellij.cce.util.Progress
|
||||
import com.intellij.cce.util.TeamcityProgress
|
||||
import com.intellij.cce.util.isUnderTeamCity
|
||||
import com.intellij.cce.workspace.EvaluationWorkspace
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.progress.Task
|
||||
import com.intellij.openapi.progress.impl.BackgroundableProcessIndicator
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.util.concurrency.FutureResult
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
|
||||
interface BackgroundEvaluationStep : EvaluationStep {
|
||||
fun runInBackground(workspace: EvaluationWorkspace, progress: Progress): EvaluationWorkspace
|
||||
suspend fun runInBackground(workspace: EvaluationWorkspace, progress: Progress): EvaluationWorkspace
|
||||
}
|
||||
|
||||
fun EvaluationStep.runInIntellij(project: Project?, workspace: EvaluationWorkspace): EvaluationWorkspace? {
|
||||
suspend fun EvaluationStep.run(workspace: EvaluationWorkspace): EvaluationWorkspace? {
|
||||
return when (this) {
|
||||
is ForegroundEvaluationStep -> start(workspace)
|
||||
is BackgroundEvaluationStep -> {
|
||||
val result = FutureResult<EvaluationWorkspace?>()
|
||||
val task = object : Task.Backgroundable(project, name, true) {
|
||||
override fun run(indicator: ProgressIndicator) {
|
||||
createProgress(title).wrapWithProgress {
|
||||
result.set(runInBackground(workspace, it))
|
||||
}
|
||||
createProgress(name).wrapWithProgress {
|
||||
try {
|
||||
runInBackground(workspace, it)
|
||||
}
|
||||
|
||||
override fun onCancel() {
|
||||
evaluationAbortedHandler.onCancel(this.title)
|
||||
result.set(null)
|
||||
catch (e: CancellationException) {
|
||||
evaluationAbortedHandler.onCancel(name)
|
||||
throw e
|
||||
}
|
||||
|
||||
override fun onThrowable(error: Throwable) {
|
||||
evaluationAbortedHandler.onError(error, this.title)
|
||||
result.set(null)
|
||||
catch (e: Throwable) {
|
||||
evaluationAbortedHandler.onError(e, name)
|
||||
null
|
||||
}
|
||||
}
|
||||
ProgressManager.getInstance().runProcessWithProgressAsynchronously(task, BackgroundableProcessIndicator(task))
|
||||
return result.get()
|
||||
}
|
||||
else -> throw IllegalStateException("Unexpected type of `$this`")
|
||||
}
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ abstract class CreateWorkspaceStep(
|
||||
private val handler: TwoWorkspaceHandler
|
||||
) : BackgroundEvaluationStep {
|
||||
|
||||
override fun runInBackground(workspace: EvaluationWorkspace, progress: Progress): EvaluationWorkspace {
|
||||
override suspend fun runInBackground(workspace: EvaluationWorkspace, progress: Progress): EvaluationWorkspace {
|
||||
val newWorkspace = EvaluationWorkspace.create(config, SetupStatsCollectorStep.statsCollectorLogsDirectory)
|
||||
handler.invoke(workspace, newWorkspace, progress)
|
||||
return newWorkspace
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ class DatasetPreparationStep(
|
||||
|
||||
override val description: String = environment.preparationDescription
|
||||
|
||||
override fun runInBackground(workspace: EvaluationWorkspace, progress: Progress): EvaluationWorkspace {
|
||||
override suspend fun runInBackground(workspace: EvaluationWorkspace, progress: Progress): EvaluationWorkspace {
|
||||
environment.prepareDataset(datasetContext, progress)
|
||||
return workspace
|
||||
}
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ class ReportGenerationStep<T : EvaluationStrategy>(
|
||||
else emptyList()
|
||||
private val sessionLookupFilter: SessionLookupsFilter = SessionLookupsFilter(lookupFilters)
|
||||
|
||||
override fun runInBackground(workspace: EvaluationWorkspace, progress: Progress): EvaluationWorkspace {
|
||||
override suspend fun runInBackground(workspace: EvaluationWorkspace, progress: Progress): EvaluationWorkspace {
|
||||
val workspaces = inputWorkspaces ?: listOf(workspace)
|
||||
val configs = workspaces.map { it.readConfig(feature.getStrategySerializer()) }
|
||||
val evaluationTitles = configs.map { it.reports.evaluationTitle }
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.intellij.cce.util
|
||||
|
||||
import com.intellij.openapi.progress.runBlockingCancellable
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.engine.java.Java
|
||||
import io.ktor.client.plugins.HttpRequestRetry
|
||||
@@ -36,7 +35,7 @@ private val httpClient: HttpClient by lazy {
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun httpGetSuspend(url: String, authToken: String?): ByteArray {
|
||||
suspend fun httpGet(url: String, authToken: String?): ByteArray {
|
||||
val response = httpClient.get(url) {
|
||||
headers {
|
||||
if (authToken != null) {
|
||||
@@ -51,10 +50,3 @@ private suspend fun httpGetSuspend(url: String, authToken: String?): ByteArray {
|
||||
|
||||
return response.bodyAsBytes()
|
||||
}
|
||||
|
||||
fun httpGet(url: String, authToken: String?): ByteArray {
|
||||
//todo refac eval framework to make it work with suspend funs
|
||||
return runBlockingCancellable {
|
||||
httpGetSuspend(url, authToken)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user