Skip to content

Commit 88b3ab2

Browse files
authored
Multiline warnings (#323)
* Multiline comments What's done: * Added support multiline warnings Closes #321
1 parent 5812123 commit 88b3ab2

File tree

10 files changed

+325
-26
lines changed

10 files changed

+325
-26
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/* ;warn:1:1: [FILE_NAME_MATCH_CLASS] file name is incorrect - it should match with the class described in it if there is the only one class declared: GenericFunctionTest.kt vs ClassName */
2+
package org.cqfn.save.test.paragraph1.naming.generic
3+
4+
private class ClassName<T> {
5+
private fun <Template, T> lock(body: ((Template?) -> T?)?, value: Template?): T? {
6+
try {
7+
val variableName: Template
8+
/* ;warn:17: [VARIABLE_NAME_INCORRECT_FORMAT] variable name should
9+
* be in lowerCamelCase and should contain only latin (ASCII)
10+
* letters or numbers and should start from lower letter: variableT
11+
* */
12+
val variableT: T
13+
println(variableT)
14+
return body!!(variableName)
15+
} finally {
16+
println()
17+
}
18+
}
19+
20+
/* ;warn:20:5: [MISSING_KDOC_ON_FUNCTION] all public, internal and protected
21+
* functions should have Kdoc with proper tags: foo */
22+
fun foo(var1: T, var2: ((T?) -> T?)?) {
23+
lock<T, T>(var2, var1)
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[general]
2+
tags = ["tag1"]
3+
description = "Chapter 4 tests: with multilines warning"
4+
suiteName = "Directory: Chapter4"
5+
expectedWarningsPattern = "/\\* ;warn:?(.*):(\\d*): (.+)"
6+
expectedWarningsMiddlePattern = "\\* (.*)"
7+
expectedWarningsEndPattern = "(.*)?\\*/"
8+
9+
[warn]
10+
lineCaptureGroup = 1
11+
columnCaptureGroup = 2
12+
messageCaptureGroup = 3

save-common/src/commonMain/kotlin/org/cqfn/save/core/plugin/PluginConfig.kt

+9
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ interface PluginConfig {
6868
* @property expectedWarningsPattern - pattern with warnings that are expected from the test file
6969
* @property runConfigPattern everything from the capture group will be split by comma and then by `=`
7070
* @property timeOutMillis command execution time for one test
71+
* @property expectedWarningsMiddlePattern
72+
* @property expectedWarningsEndPattern
7173
*/
7274
@Serializable
7375
data class GeneralConfig(
@@ -77,6 +79,8 @@ data class GeneralConfig(
7779
val suiteName: String? = null,
7880
val excludedTests: List<String>? = null,
7981
val expectedWarningsPattern: Regex? = null,
82+
val expectedWarningsMiddlePattern: Regex? = null,
83+
val expectedWarningsEndPattern: Regex? = null,
8084
val runConfigPattern: Regex? = null,
8185
val timeOutMillis: Long? = null,
8286
) : PluginConfig {
@@ -87,6 +91,7 @@ data class GeneralConfig(
8791
override var configLocation: Path = "undefined_toml_location".toPath()
8892
override val resourceNamePatternStr: String = ".*"
8993

94+
@Suppress("ComplexMethod")
9095
override fun mergeWith(otherConfig: PluginConfig): PluginConfig {
9196
val other = otherConfig as GeneralConfig
9297
val mergedTag = other.tags?.let {
@@ -102,6 +107,8 @@ data class GeneralConfig(
102107
this.suiteName ?: other.suiteName,
103108
this.excludedTests ?: other.excludedTests,
104109
this.expectedWarningsPattern ?: other.expectedWarningsPattern,
110+
this.expectedWarningsMiddlePattern ?: other.expectedWarningsMiddlePattern,
111+
this.expectedWarningsEndPattern ?: other.expectedWarningsEndPattern,
105112
this.runConfigPattern ?: other.runConfigPattern,
106113
this.timeOutMillis ?: other.timeOutMillis,
107114
).also { it.configLocation = this.configLocation }
@@ -128,6 +135,8 @@ data class GeneralConfig(
128135
suiteName,
129136
excludedTests ?: emptyList(),
130137
expectedWarningsPattern ?: defaultExpectedWarningPattern,
138+
expectedWarningsMiddlePattern,
139+
expectedWarningsEndPattern,
131140
runConfigPattern ?: defaultRunConfigPattern,
132141
timeOutMillis ?: 10_000L,
133142
).also { it.configLocation = this.configLocation }

save-core/src/commonNonJsTest/kotlin/org/cqfn/save/core/MergeConfigsTest.kt

+4-4
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ class MergeConfigsTest {
3939
private val warningsOutputPattern1 = Regex(".*")
4040
private val warningsOutputPattern2 = Regex("\\w+ - (\\d+)/(\\d+) - (.*)$")
4141
private val warnConfig1 = WarnPluginConfig("execCmd1", warningsOutputPattern2,
42-
false, false, 1, ", ", 1, 1, 1, 1, 1, 1, 1, false, null)
42+
false, false, 1, ", ", 1, 1, 1, 1, 1, 1, 1, 1, 1, false, null)
4343
private val warnConfig2 = WarnPluginConfig("execCmd2", warningsOutputPattern1,
44-
true, true, 1, ", ", 2, 2, 2, 2, 2, 2, 2, true, null)
44+
true, true, 1, ", ", 2, 2, 2, 1, 1, 2, 2, 2, 2, true, null)
4545
private val warnConfig3 = WarnPluginConfig("execCmd3", warningsOutputPattern2,
4646
warningTextHasColumn = false, batchSize = 1, lineCaptureGroup = 3, columnCaptureGroup = 3, messageCaptureGroup = 3,
4747
fileNameCaptureGroupOut = 3, lineCaptureGroupOut = 3, columnCaptureGroupOut = 3, messageCaptureGroupOut = 3)
@@ -121,7 +121,7 @@ class MergeConfigsTest {
121121
val expectedGeneralConfig =
122122
GeneralConfig("", listOf("Tag11", "Tag12", "Tag21"), "Description2", "suiteName2", listOf("excludedTests: test3"), runConfigPattern = extraFlagsPattern1)
123123
val expectedWarnConfig = WarnPluginConfig("execCmd3", warningsOutputPattern2,
124-
true, false, 1, ", ", 3, 3, 3, 3, 3, 3, 3, true, null)
124+
true, false, 1, ", ", 3, 3, 3, 1, 1, 3, 3, 3, 3, true, null)
125125
val expectedFixConfig = FixPluginConfig("fixCmd2", 1, "Suffix")
126126

127127
val actualGeneralConfig = config2.pluginConfigs.filterIsInstance<GeneralConfig>().first()
@@ -147,7 +147,7 @@ class MergeConfigsTest {
147147
val expectedGeneralConfig =
148148
GeneralConfig("", listOf("Tag11", "Tag12", "Tag21", "Tag31", "Tag32"), "Description2", "suiteName4", listOf("excludedTests: test7"), runConfigPattern = extraFlagsPattern2)
149149
val expectedWarnConfig = WarnPluginConfig("execCmd4", warningsOutputPattern2,
150-
true, false, 1, ", ", 4, 4, 4, 4, 4, 4, 4, true, null)
150+
true, false, 1, ", ", 4, 4, 4, 1, 1, 4, 4, 4, 4, true, null)
151151
val expectedFixConfig = FixPluginConfig("fixCmd4", 1, "Suffix")
152152

153153
val actualGeneralConfig = config4.pluginConfigs.filterIsInstance<GeneralConfig>().first()

save-core/src/commonNonJsTest/kotlin/org/cqfn/save/core/ValidationTest.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class ValidationTest {
4242
assertEquals(
4343
"""
4444
Error: Couldn't find `execCmd` in [general] section of `${generalConfig.configLocation}` config.
45-
Current configuration: execCmd=null, tags=null, description=null, suiteName=null, excludedTests=null, expectedWarningsPattern=null, runConfigPattern=null, timeOutMillis=null
45+
Current configuration: ${generalConfig.toString().substringAfter("(").substringBefore(")")}
4646
Please provide it in this, or at least in one of the parent configs.
4747
""".trimIndent(),
4848
ex.message

save-core/src/commonNonJsTest/kotlin/org/cqfn/save/core/integration/WarnDirTest.kt

+5
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,9 @@ class WarnDirTest {
1919
fun `execute warn plugin on the directory chapter3`() {
2020
runTestsWithDiktat(listOf("warn-dir/chapter3"), 1)
2121
}
22+
23+
@Test
24+
fun `execute warn plugin on the directory chapter4`() {
25+
runTestsWithDiktat(listOf("warn-dir/chapter4"), 1)
26+
}
2227
}

save-plugins/fix-and-warn-plugin/src/commonNonJsTest/kotlin/org/cqfn/save/plugins/fixandwarn/FixAndWarnPluginTest.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ class FixAndWarnPluginTest {
7878
FixPluginConfig(fixExecutionCmd, batchSize = 1),
7979
WarnPluginConfig(warnExecutionCmd,
8080
Regex("(.+):(\\d+):(\\d+): (.+)"),
81-
true, true, 1, ", ", 1, 2, 3, 1, 2, 3, 4
81+
true, true, 1, ", ", 1, 2, 3, 1, 1, 1, 2, 3, 4
8282
)
8383
),
8484
GeneralConfig("", listOf(""), "", "", expectedWarningsPattern = Regex("// ;warn:(\\d+):(\\d+): (.*)"), runConfigPattern = defaultExtraConfigPattern)

save-plugins/warn-plugin/src/commonMain/kotlin/org/cqfn/save/plugin/warn/WarnPlugin.kt

+75-20
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@ import org.cqfn.save.plugin.warn.utils.ResultsChecker
1919
import org.cqfn.save.plugin.warn.utils.Warning
2020
import org.cqfn.save.plugin.warn.utils.extractWarning
2121
import org.cqfn.save.plugin.warn.utils.getLineNumber
22+
import org.cqfn.save.plugin.warn.utils.getLineNumberAndMessage
2223

2324
import okio.FileNotFoundException
2425
import okio.FileSystem
2526
import okio.Path
27+
2628
import kotlin.random.Random
2729

2830
private typealias WarningMap = Map<String, List<Warning>>
@@ -232,28 +234,81 @@ class WarnPlugin(
232234
generalConfig: GeneralConfig
233235
): List<Warning> {
234236
val linesFile = fs.readLines(this)
235-
return linesFile
236-
.mapIndexed { index, line ->
237-
val newLine = line.getLineNumber(
238-
generalConfig.expectedWarningsPattern!!,
239-
warnPluginConfig.lineCaptureGroup,
240-
warnPluginConfig.linePlaceholder!!,
241-
index + 1,
237+
return generalConfig.expectedWarningsEndPattern?.let {
238+
collectionMultilineWarnings(
239+
warnPluginConfig,
240+
generalConfig,
241+
linesFile,
242+
this,
243+
)
244+
}
245+
?: run {
246+
collectionSingleWarnings(
247+
warnPluginConfig,
248+
generalConfig,
249+
linesFile,
242250
this,
243-
linesFile
244251
)
245-
with(warnPluginConfig) {
246-
line.extractWarning(
247-
generalConfig.expectedWarningsPattern!!,
248-
this@collectWarningsWithLineNumbers.name,
249-
newLine,
250-
columnCaptureGroup,
251-
messageCaptureGroup!!,
252-
benchmarkMode!!
253-
)
254-
}
255252
}
256-
.filterNotNull()
257-
.sortedBy { warn -> warn.message }
258253
}
254+
255+
private fun collectionMultilineWarnings(
256+
warnPluginConfig: WarnPluginConfig,
257+
generalConfig: GeneralConfig,
258+
linesFile: List<String>,
259+
file: Path,
260+
): List<Warning> = linesFile.mapIndexed { index, line ->
261+
val newLineAndMessage = line.getLineNumberAndMessage(
262+
generalConfig.expectedWarningsPattern!!,
263+
generalConfig.expectedWarningsEndPattern!!,
264+
generalConfig.expectedWarningsMiddlePattern!!,
265+
warnPluginConfig.messageCaptureGroupMiddle!!,
266+
warnPluginConfig.messageCaptureGroupEnd!!,
267+
warnPluginConfig.lineCaptureGroup,
268+
warnPluginConfig.linePlaceholder!!,
269+
warnPluginConfig.messageCaptureGroup!!,
270+
index + 1,
271+
file,
272+
linesFile,
273+
)
274+
with(warnPluginConfig) {
275+
line.extractWarning(
276+
generalConfig.expectedWarningsPattern!!,
277+
file.name,
278+
newLineAndMessage?.first,
279+
newLineAndMessage?.second,
280+
columnCaptureGroup,
281+
)
282+
}
283+
}
284+
.filterNotNull()
285+
.sortedBy { warn -> warn.message }
286+
287+
private fun collectionSingleWarnings(
288+
warnPluginConfig: WarnPluginConfig,
289+
generalConfig: GeneralConfig,
290+
linesFile: List<String>,
291+
file: Path,
292+
): List<Warning> = linesFile.mapIndexed { index, line ->
293+
val newLine = line.getLineNumber(
294+
generalConfig.expectedWarningsPattern!!,
295+
warnPluginConfig.lineCaptureGroup,
296+
warnPluginConfig.linePlaceholder!!,
297+
index + 1,
298+
file,
299+
linesFile,
300+
)
301+
with(warnPluginConfig) {
302+
line.extractWarning(
303+
generalConfig.expectedWarningsPattern!!,
304+
file.name,
305+
newLine,
306+
columnCaptureGroup,
307+
messageCaptureGroup!!,
308+
benchmarkMode!!,
309+
)
310+
}
311+
}
312+
.filterNotNull()
313+
.sortedBy { warn -> warn.message }
259314
}

save-plugins/warn-plugin/src/commonMain/kotlin/org/cqfn/save/plugin/warn/WarnPluginConfig.kt

+8
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ import kotlinx.serialization.UseSerializers
5151
* @property testToolResFileOutput file with actual warnings
5252
* @property ignoreLines mutable list of patterns that later will be ignored in test files
5353
* @property benchmarkMode whether to ignore the warning messages
54+
* @property messageCaptureGroupMiddle
55+
* @property messageCaptureGroupEnd
5456
*/
5557
@Serializable
5658
data class WarnPluginConfig(
@@ -63,6 +65,8 @@ data class WarnPluginConfig(
6365
val lineCaptureGroup: Long? = null,
6466
val columnCaptureGroup: Long? = null,
6567
val messageCaptureGroup: Long? = null,
68+
val messageCaptureGroupMiddle: Long? = null,
69+
val messageCaptureGroupEnd: Long? = null,
6670
val fileNameCaptureGroupOut: Long? = null,
6771
val lineCaptureGroupOut: Long? = null,
6872
val columnCaptureGroupOut: Long? = null,
@@ -109,6 +113,8 @@ data class WarnPluginConfig(
109113
this.lineCaptureGroup ?: other.lineCaptureGroup,
110114
this.columnCaptureGroup ?: other.columnCaptureGroup,
111115
this.messageCaptureGroup ?: other.messageCaptureGroup,
116+
this.messageCaptureGroupMiddle ?: other.messageCaptureGroupMiddle,
117+
this.messageCaptureGroupEnd ?: other.messageCaptureGroupEnd,
112118
this.fileNameCaptureGroupOut ?: other.fileNameCaptureGroupOut,
113119
this.lineCaptureGroupOut ?: other.lineCaptureGroupOut,
114120
this.columnCaptureGroupOut ?: other.columnCaptureGroupOut,
@@ -171,6 +177,8 @@ data class WarnPluginConfig(
171177
newLineCaptureGroup,
172178
newColumnCaptureGroup,
173179
newMessageCaptureGroup,
180+
messageCaptureGroupMiddle ?: 1,
181+
messageCaptureGroupEnd ?: 1,
174182
newFileNameCaptureGroupOut,
175183
newLineCaptureGroupOut,
176184
newColumnCaptureGroupOut,

0 commit comments

Comments
 (0)