Skip to content

Commit 2e850e8

Browse files
Refactor UI and Utils related logic (#357)
1 parent bb17d56 commit 2e850e8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+850
-863
lines changed

clion-plugin/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ all configuration options.
4343
1. Open plugin settings in settings - Tools - UTBot Settings
4444
2. Click `detect paths`. It will try to get source paths, build dir paths from CLion
4545
CMake model.
46-
3. Specify absolute path to build folder, it should be different from build folder that CLion uses,
46+
3. Specify absolute path to build directory, it should be different from build directory that CLion uses,
4747
because there can be conflicts between UTBotCpp and CLion. For example, if CLion uses `project_path/cmake-build-debug`,
4848
then you can specify `project_path/utbot_build`.
4949
4. For target path specify `/utbot/auto/target/path`

clion-plugin/src/main/kotlin/org/utbot/cpp/clion/plugin/UTBotStartupActivity.kt

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,24 @@ import org.utbot.cpp.clion.plugin.client.ClientManager
99
import org.utbot.cpp.clion.plugin.settings.pluginSettings
1010
import org.utbot.cpp.clion.plugin.settings.settings
1111
import org.utbot.cpp.clion.plugin.ui.wizard.UTBotWizard
12-
import org.utbot.cpp.clion.plugin.utils.getCurrentClient
1312
import org.utbot.cpp.clion.plugin.utils.invokeOnEdt
1413

1514
class UTBotStartupActivity : StartupActivity {
1615
override fun runActivity(project: Project) {
17-
// we initialize Client here, so that initialization will not happen when user issues first
18-
// generation request which would cause a UI freeze
16+
// We initialize Client here, so that initialization will not happen
17+
// when user issues first generation request which would cause a UI freeze.
1918
initializeClient(project)
20-
guessPathsOnFirstProjectOpen(project)
21-
showWizardOnFirstProjectOpen(project)
19+
guessPathsOnFirstOpen(project)
20+
showWizardOnFirstOpen(project)
2221
}
2322

24-
private fun showWizardOnFirstProjectOpen(project: Project) {
23+
// Here we address the service ClientManager for the first time so that it
24+
// will be initialized by the ide and Client will be created.
25+
// Client in turn will create a grpc channel and start heart-beating the server.
26+
private fun initializeClient(project: Project) = project.service<ClientManager>()
27+
28+
29+
private fun showWizardOnFirstOpen(project: Project) {
2530
if (pluginSettings.isFirstLaunch && !Client.IS_TEST_MODE) {
2631
pluginSettings.isFirstLaunch = false
2732
invokeOnEdt {
@@ -30,14 +35,7 @@ class UTBotStartupActivity : StartupActivity {
3035
}
3136
}
3237

33-
private fun initializeClient(project: Project) {
34-
// Here we address the service ClientManager for the first time so that it
35-
// will be initialized by the ide and Client will be created.
36-
// Client in turn will create a grpc channel and start heartbeating the server
37-
project.service<ClientManager>()
38-
}
39-
40-
private fun guessPathsOnFirstProjectOpen(project: Project) {
38+
private fun guessPathsOnFirstOpen(project: Project) {
4139
RunOnceUtil.runOnceForProject(project, "Guess UTBot paths in settings") {
4240
project.settings.predictPaths()
4341
}

clion-plugin/src/main/kotlin/org/utbot/cpp/clion/plugin/actions/generate/RunWithCoverageAction.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class RunWithCoverageAction(val element: PsiElement) : BaseGenerateTestsAction()
1414
override fun actionPerformed(e: AnActionEvent) {
1515
logger.debug("Action RunWithCoverageAction was called")
1616

17-
val testArgs = TestNameAndTestSuite.getFromPsiElement(element)
17+
val testArgs = TestNameAndTestSuite.create(element)
1818
val suiteName = testArgs.suite
1919
val testedMethodName = testArgs.name
2020
val filePath = e.getRequiredData(CommonDataKeys.VIRTUAL_FILE).path

clion-plugin/src/main/kotlin/org/utbot/cpp/clion/plugin/client/Client.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import kotlinx.coroutines.SupervisorJob
1212
import kotlinx.coroutines.cancel
1313
import kotlinx.coroutines.delay
1414
import kotlinx.coroutines.isActive
15+
import kotlinx.coroutines.job
1516
import kotlinx.coroutines.launch
1617
import kotlinx.coroutines.runBlocking
1718
import kotlinx.coroutines.withTimeout
@@ -21,7 +22,6 @@ import org.utbot.cpp.clion.plugin.grpc.getProjectConfigGrpcRequest
2122
import org.utbot.cpp.clion.plugin.listeners.ConnectionStatus
2223
import org.utbot.cpp.clion.plugin.listeners.UTBotEventsListener
2324
import org.utbot.cpp.clion.plugin.settings.projectIndependentSettings
24-
import org.utbot.cpp.clion.plugin.utils.hasChildren
2525
import org.utbot.cpp.clion.plugin.utils.logger
2626
import testsgen.Testgen
2727

@@ -52,15 +52,15 @@ class Client(
5252
exception.printStackTrace()
5353
}
5454

55-
val dispatcher = Dispatchers.IO
55+
private val dispatcher = Dispatchers.IO
5656

5757
// coroutine scope for requests that don't have a lifetime of a plugin, e.g. generation requests
5858
// this division is needed for testing: when in test we send a generate request to server, we need to wait
5959
// until it completes, the indicator that all such requests have completed is that this scope has no children
60-
val requestsCS: CoroutineScope = CoroutineScope(dispatcher + excHandler + SupervisorJob())
60+
private val requestsCS: CoroutineScope = CoroutineScope(dispatcher + excHandler + SupervisorJob())
6161

6262
// coroutine scope for suspending functions that can live entire plugin lifetime, e.g. server logs, gtest logs, heartbeat
63-
val servicesCS: CoroutineScope = CoroutineScope(dispatcher + excHandler + SupervisorJob())
63+
private val servicesCS: CoroutineScope = CoroutineScope(dispatcher + excHandler + SupervisorJob())
6464

6565
init {
6666
logger.info { "Connecting to server on host: ${projectIndependentSettings.serverName} , port: ${projectIndependentSettings.port}" }
@@ -192,7 +192,7 @@ class Client(
192192
fun waitForServerRequestsToFinish(timeout: Long = SERVER_TIMEOUT) {
193193
runBlocking {
194194
withTimeout(timeout) {
195-
while (requestsCS.hasChildren()) {
195+
while (requestsCS.coroutineContext.job.children.any()) {
196196
delay(DELAY_TIME)
197197
}
198198
}

clion-plugin/src/main/kotlin/org/utbot/cpp/clion/plugin/client/LoggingChannels.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import kotlinx.coroutines.flow.catch
77
import kotlinx.coroutines.flow.collect
88
import org.utbot.cpp.clion.plugin.grpc.getDummyGrpcRequest
99
import org.utbot.cpp.clion.plugin.grpc.getLogChannelGrpcRequest
10-
import org.utbot.cpp.clion.plugin.ui.userLog.OutputProvider
10+
import org.utbot.cpp.clion.plugin.ui.services.OutputProvider
1111
import org.utbot.cpp.clion.plugin.ui.userLog.UTBotConsole
1212
import org.utbot.cpp.clion.plugin.utils.invokeOnEdt
1313
import org.utbot.cpp.clion.plugin.utils.logger

clion-plugin/src/main/kotlin/org/utbot/cpp/clion/plugin/client/handlers/ProjectConfigurationHandler.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import org.utbot.cpp.clion.plugin.utils.notifyError
1515
import org.utbot.cpp.clion.plugin.utils.notifyInfo
1616
import org.utbot.cpp.clion.plugin.utils.notifyUnknownResponse
1717
import org.utbot.cpp.clion.plugin.utils.notifyWarning
18-
import org.utbot.cpp.clion.plugin.utils.refreshAndFindIOFile
18+
import org.utbot.cpp.clion.plugin.utils.refreshAndFindNioFile
1919
import testsgen.Testgen
2020

2121
abstract class ProjectConfigResponseHandler(
@@ -58,8 +58,9 @@ class CheckProjectConfigurationHandler(
5858
val missingFileName =
5959
if (response.type == Testgen.ProjectConfigStatus.LINK_COMMANDS_JSON_NOT_FOUND) "link_commands.json" else "compile_commands.json"
6060
notifyError(
61-
"Project is not configured properly: $missingFileName is missing in the build folder.",
62-
project, AskServerToGenerateJsonForProjectConfiguration()
61+
"Project is not configured properly: file $missingFileName is missed in the build directory",
62+
project,
63+
AskServerToGenerateJsonForProjectConfiguration(),
6364
)
6465
}
6566
Testgen.ProjectConfigStatus.BUILD_DIR_SAME_AS_PROJECT -> {
@@ -97,7 +98,7 @@ class CreateBuildDirHandler(
9798
}
9899
else -> notifyUnknownResponse(response, project)
99100
}
100-
refreshAndFindIOFile(project.settings.buildDirPath.toString())
101+
refreshAndFindNioFile(project.settings.buildDirPath)
101102
}
102103
}
103104

@@ -116,6 +117,6 @@ class GenerateJsonHandler(
116117
)
117118
else -> notifyUnknownResponse(response, project)
118119
}
119-
refreshAndFindIOFile(project.settings.buildDirPath.toString())
120+
refreshAndFindNioFile(project.settings.buildDirPath)
120121
}
121122
}

clion-plugin/src/main/kotlin/org/utbot/cpp/clion/plugin/client/handlers/StreamHandlerWithProgress.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ abstract class StreamHandlerWithProgress<T>(
2727
override fun onFinish() {
2828
super.onFinish()
2929
invokeOnEdt {
30-
indicator.complete()
30+
indicator.finish()
3131
}
3232
}
3333

clion-plugin/src/main/kotlin/org/utbot/cpp/clion/plugin/client/handlers/TestsStreamHandler.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import com.intellij.openapi.project.Project
44
import kotlinx.coroutines.Job
55
import kotlinx.coroutines.flow.Flow
66
import org.utbot.cpp.clion.plugin.utils.convertFromRemotePathIfNeeded
7-
import org.utbot.cpp.clion.plugin.utils.createFileAndMakeDirs
7+
import org.utbot.cpp.clion.plugin.utils.createFileWithText
88
import org.utbot.cpp.clion.plugin.utils.logger
9-
import org.utbot.cpp.clion.plugin.utils.refreshAndFindIOFile
9+
import org.utbot.cpp.clion.plugin.utils.refreshAndFindNioFile
1010
import testsgen.Testgen
1111
import testsgen.Util
1212
import java.nio.file.Path
@@ -42,7 +42,7 @@ class TestsStreamHandler(
4242

4343
if (sourceCode.code.isNotEmpty()) {
4444
project.logger.trace { "Creating generated test file: $filePath." }
45-
createFileAndMakeDirs(
45+
createFileWithText(
4646
filePath,
4747
sourceCode.code
4848
)
@@ -54,7 +54,7 @@ class TestsStreamHandler(
5454
" and ${sourceCode.errorMethodsNumber} tests in error suite"
5555
project.logger.info { "$infoMessage: $filePath" }
5656

57-
refreshAndFindIOFile(filePath)
57+
refreshAndFindNioFile(filePath)
5858
}
5959
}
6060

Lines changed: 15 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,114 +1,36 @@
11
package org.utbot.cpp.clion.plugin.client.logger
22

3-
import com.intellij.execution.ui.ConsoleViewContentType
43
import com.intellij.openapi.components.Service
5-
import com.intellij.openapi.components.service
64
import com.intellij.openapi.project.Project
7-
import org.utbot.cpp.clion.plugin.ui.userLog.OutputProvider
8-
import org.utbot.cpp.clion.plugin.utils.invokeOnEdt
9-
import java.time.LocalDateTime
10-
import java.time.format.DateTimeFormatter
11-
12-
enum class Level(val text: String) {
13-
TRACE("TRACE"), DEBUG("DEBUG"), INFO("INFO"), WARN("WARN"), ERROR("ERROR"), OFF("OFF")
14-
}
15-
16-
interface Writer {
17-
fun write(message: LogMessage)
18-
}
19-
20-
interface Formatter {
21-
fun format(message: LogMessage): String
22-
}
23-
24-
class SimpleFormatter : Formatter {
25-
override fun format(message: LogMessage): String {
26-
val dateTime = DateTimeFormatter.ofPattern("HH:mm:ss.SSSS").format(message.dateTime)
27-
return "$dateTime | ${message.fileName}:${message.line} [${message.threadName}] " +
28-
"|${message.level.text}| ${message.messageSupplier()} \n"
29-
}
30-
}
31-
32-
data class LogMessage(
33-
val messageSupplier: () -> (String),
34-
val line: Int,
35-
val fileName: String,
36-
val threadName: String,
37-
val methodName: String,
38-
val level: Level,
39-
val dateTime: LocalDateTime = LocalDateTime.now(),
40-
) {
41-
constructor(message: () -> String, level: Level, frame: StackTraceElement) :
42-
this(
43-
message,
44-
frame.lineNumber,
45-
frame.fileName ?: "Unknown file",
46-
Thread.currentThread().name,
47-
frame.methodName,
48-
level
49-
)
50-
}
51-
52-
class ConsoleWriter(project: Project) : Writer {
53-
private val console = project.service<OutputProvider>().clientOutputChannel.outputConsole
54-
private val formatter = SimpleFormatter()
55-
override fun write(message: LogMessage) {
56-
val type = when (message.level) {
57-
Level.INFO -> ConsoleViewContentType.NORMAL_OUTPUT
58-
Level.WARN -> ConsoleViewContentType.LOG_WARNING_OUTPUT
59-
Level.ERROR -> ConsoleViewContentType.LOG_ERROR_OUTPUT
60-
Level.DEBUG -> ConsoleViewContentType.LOG_DEBUG_OUTPUT
61-
else -> ConsoleViewContentType.NORMAL_OUTPUT
62-
}
63-
invokeOnEdt {
64-
console.print(formatter.format(message), type)
65-
}
66-
}
67-
}
68-
69-
class SystemWriter : Writer {
70-
private val formatter = SimpleFormatter()
71-
override fun write(message: LogMessage) {
72-
println(formatter.format(message))
73-
}
74-
}
755

766
@Service
77-
class ClientLogger(private val project: Project) {
78-
var level = Level.TRACE
7+
class ClientLogger(project: Project) {
8+
var level = LogLevel.TRACE
799
set(value) {
8010
info { "Setting new log level: ${value.text}" }
8111
field = value
8212
}
8313

84-
val writers: MutableList<Writer> = mutableListOf(ConsoleWriter(project))
14+
val logWriters: MutableList<LogWriter> = mutableListOf(ConsoleWriter(project))
8515

86-
fun info(message: () -> String) {
87-
log(message, Level.INFO)
88-
}
16+
fun info(message: () -> String) = log(message, LogLevel.INFO)
8917

90-
fun warn(message: () -> String) {
91-
log(message, Level.WARN)
92-
}
18+
fun warn(message: () -> String) = log(message, LogLevel.WARN)
9319

94-
fun error(message: () -> String) {
95-
log(message, Level.ERROR)
96-
}
20+
fun error(message: () -> String) = log(message, LogLevel.ERROR)
9721

98-
fun debug(message: () -> String) {
99-
log(message, Level.DEBUG)
100-
}
22+
fun debug(message: () -> String) = log(message, LogLevel.DEBUG)
10123

102-
fun trace(message: () -> String) {
103-
log(message, Level.TRACE)
104-
}
24+
fun trace(message: () -> String) = log(message, LogLevel.TRACE)
10525

106-
fun log(messageSupplier: () -> (String), level: Level, depth: Int = 3) {
107-
if (level.ordinal < this.level.ordinal)
26+
private fun log(messageSupplier: () -> (String), level: LogLevel, depth: Int = 3) {
27+
if (level.ordinal < this.level.ordinal){
10828
return
109-
val logMessage: LogMessage = LogMessage(messageSupplier, level, Thread.currentThread().stackTrace[depth + 1])
110-
writers.forEach {
111-
it.write(logMessage)
29+
}
30+
31+
val logMessage = LogMessage(messageSupplier, level, Thread.currentThread().stackTrace[depth + 1])
32+
for (writer in logWriters) {
33+
writer.write(logMessage)
11234
}
11335
}
11436
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package org.utbot.cpp.clion.plugin.client.logger
2+
3+
import java.time.format.DateTimeFormatter
4+
5+
object LogFormatter {
6+
fun format(message: LogMessage): String {
7+
val dateTime = DateTimeFormatter.ofPattern("HH:mm:ss.SSSS").format(message.dateTime)
8+
return "$dateTime | ${message.fileName}:${message.line} [${message.threadName}] " +
9+
"|${message.level.text}| ${message.messageSupplier()} \n"
10+
}
11+
}
12+
13+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package org.utbot.cpp.clion.plugin.client.logger
2+
3+
enum class LogLevel(val text: String) {
4+
TRACE("TRACE"),
5+
DEBUG("DEBUG"),
6+
INFO("INFO"),
7+
WARN("WARN"),
8+
ERROR("ERROR"),
9+
OFF("OFF"),
10+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.utbot.cpp.clion.plugin.client.logger
2+
3+
import java.time.LocalDateTime
4+
5+
data class LogMessage(
6+
val messageSupplier: () -> (String),
7+
val line: Int,
8+
val fileName: String,
9+
val threadName: String,
10+
val methodName: String,
11+
val level: LogLevel,
12+
val dateTime: LocalDateTime = LocalDateTime.now(),
13+
) {
14+
constructor(message: () -> String, level: LogLevel, frame: StackTraceElement) :
15+
this(
16+
message,
17+
frame.lineNumber,
18+
frame.fileName ?: "Unknown file",
19+
Thread.currentThread().name,
20+
frame.methodName,
21+
level
22+
)
23+
}

0 commit comments

Comments
 (0)