Skip to content

Commit 45cb21a

Browse files
authored
Merge pull request #534 from fwcd/diagnostics-config
Make diagnostic level configurable and add option to disable diagnostics
2 parents 4cdff98 + cf22a49 commit 45cb21a

File tree

9 files changed

+96
-32
lines changed

9 files changed

+96
-32
lines changed

detekt.yml

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@ comments:
77

88
complexity:
99
excludes: ["**/src/test/resources/**"]
10-
10+
1111
empty-blocks:
12-
excludes: ["**/src/test/resources/**"]
13-
12+
excludes: ["**/src/test/**"]
13+
1414
exceptions:
15-
excludes: ["**/src/test/resources/**"]
15+
excludes: ["**/src/test/**"]
1616
SwallowedException:
1717
ignoredExceptionTypes:
18+
- CancellationException
1819
- InterruptedException
1920
- MalformedURLException
2021
- NumberFormatException
@@ -29,8 +30,12 @@ performance:
2930

3031
potential-bugs:
3132
excludes: ["**/src/test/resources/**"]
32-
33+
3334
style:
3435
excludes: ["**/src/test/resources/**"]
3536
MaxLineLength:
3637
active: false
38+
WildcardImport:
39+
excludeImports:
40+
- java.util.*
41+
- org.hamcrest.Matchers.*

server/src/main/kotlin/org/javacs/kt/Configuration.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.google.gson.JsonDeserializer
66
import com.google.gson.JsonElement
77
import com.google.gson.JsonParseException
88
import org.eclipse.lsp4j.InitializeParams
9+
import org.eclipse.lsp4j.DiagnosticSeverity
910
import java.lang.reflect.Type
1011
import java.nio.file.InvalidPathException
1112
import java.nio.file.Path
@@ -20,7 +21,11 @@ public data class CompletionConfiguration(
2021
val snippets: SnippetsConfiguration = SnippetsConfiguration()
2122
)
2223

23-
public data class LintingConfiguration(
24+
public data class DiagnosticsConfiguration(
25+
/** Whether diagnostics are enabled. */
26+
var enabled: Boolean = true,
27+
/** The minimum severity of enabled diagnostics. */
28+
var level: DiagnosticSeverity = DiagnosticSeverity.Hint,
2429
/** The time interval between subsequent lints in ms. */
2530
var debounceTime: Long = 250L
2631
)
@@ -85,7 +90,7 @@ class GsonPathConverter : JsonDeserializer<Path?> {
8590
public data class Configuration(
8691
val compiler: CompilerConfiguration = CompilerConfiguration(),
8792
val completion: CompletionConfiguration = CompletionConfiguration(),
88-
val linting: LintingConfiguration = LintingConfiguration(),
93+
val diagnostics: DiagnosticsConfiguration = DiagnosticsConfiguration(),
8994
var indexing: IndexingConfiguration = IndexingConfiguration(),
9095
val externalSources: ExternalSourcesConfiguration = ExternalSourcesConfiguration(),
9196
val hints: InlayHintsConfiguration = InlayHintsConfiguration()

server/src/main/kotlin/org/javacs/kt/KotlinTextDocumentService.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class KotlinTextDocumentService(
4646
private lateinit var client: LanguageClient
4747
private val async = AsyncExecutor()
4848

49-
var debounceLint = Debouncer(Duration.ofMillis(config.linting.debounceTime))
49+
var debounceLint = Debouncer(Duration.ofMillis(config.diagnostics.debounceTime))
5050
val lintTodo = mutableSetOf<URI>()
5151
var lintCount = 0
5252

@@ -267,7 +267,7 @@ class KotlinTextDocumentService(
267267
}
268268

269269
public fun updateDebouncer() {
270-
debounceLint = Debouncer(Duration.ofMillis(config.linting.debounceTime))
270+
debounceLint = Debouncer(Duration.ofMillis(config.diagnostics.debounceTime))
271271
}
272272

273273
fun lintAll() {
@@ -305,7 +305,9 @@ class KotlinTextDocumentService(
305305
}
306306

307307
private fun reportDiagnostics(compiled: Collection<URI>, kotlinDiagnostics: Diagnostics) {
308-
val langServerDiagnostics = kotlinDiagnostics.flatMap(::convertDiagnostic)
308+
val langServerDiagnostics = kotlinDiagnostics
309+
.flatMap(::convertDiagnostic)
310+
.filter { config.diagnostics.enabled && it.second.severity <= config.diagnostics.level }
309311
val byFile = langServerDiagnostics.groupBy({ it.first }, { it.second })
310312

311313
for ((uri, diagnostics) in byFile) {

server/src/main/kotlin/org/javacs/kt/KotlinWorkspaceService.kt

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,13 @@ class KotlinWorkspaceService(
8080
}
8181
}
8282

83+
@Suppress("LongMethod", "CyclomaticComplexMethod", "NestedBlockDepth")
8384
override fun didChangeConfiguration(params: DidChangeConfigurationParams) {
8485
val settings = params.settings as? JsonObject
8586
settings?.get("kotlin")?.asJsonObject?.apply {
8687
// Update deprecated configuration keys
8788
get("debounceTime")?.asLong?.let {
88-
config.linting.debounceTime = it
89+
config.diagnostics.debounceTime = it
8990
docService.updateDebouncer()
9091
}
9192
get("snippetsEnabled")?.asBoolean?.let { config.completion.snippets.enabled = it }
@@ -110,12 +111,27 @@ class KotlinWorkspaceService(
110111
get("chainedHints")?.asBoolean?.let { hints.chainedHints = it }
111112
}
112113

113-
// Update linter options
114-
get("linting")?.asJsonObject?.apply {
115-
val linting = config.linting
116-
get("debounceTime")?.asLong?.let {
117-
linting.debounceTime = it
118-
docService.updateDebouncer()
114+
// Update diagnostics options
115+
// Note that the 'linting' key is deprecated and only kept
116+
// for backwards compatibility.
117+
for (diagnosticsKey in listOf("linting", "diagnostics")) {
118+
get(diagnosticsKey)?.asJsonObject?.apply {
119+
val diagnostics = config.diagnostics
120+
get("enabled")?.asBoolean?.let {
121+
diagnostics.enabled = it
122+
}
123+
get("level")?.asString?.let {
124+
diagnostics.level = when (it.lowercase()) {
125+
"error" -> DiagnosticSeverity.Error
126+
"warning" -> DiagnosticSeverity.Warning
127+
"information" -> DiagnosticSeverity.Information
128+
else -> DiagnosticSeverity.Hint
129+
}
130+
}
131+
get("debounceTime")?.asLong?.let {
132+
diagnostics.debounceTime = it
133+
docService.updateDebouncer()
134+
}
119135
}
120136
}
121137

server/src/test/kotlin/org/javacs/kt/LintTest.kt renamed to server/src/test/kotlin/org/javacs/kt/DiagnosticTest.kt

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,51 @@ package org.javacs.kt
22

33
import java.util.concurrent.CancellationException
44
import org.eclipse.lsp4j.Diagnostic
5+
import org.eclipse.lsp4j.DiagnosticSeverity
56
import org.eclipse.lsp4j.DocumentSymbolParams
67
import org.eclipse.lsp4j.PublishDiagnosticsParams
78
import org.eclipse.lsp4j.TextDocumentIdentifier
89
import org.hamcrest.Matchers.*
910
import org.junit.Assert.assertThat
1011
import org.junit.Test
1112

12-
class LintTest : SingleFileTestFixture("lint", "LintErrors.kt") {
13-
@Test fun `report error on open`() {
13+
class DiagnosticTest : SingleFileTestFixture("diagnostic", "Diagnostics.kt") {
14+
@Test fun `report diagnostics on open`() {
1415
languageServer.textDocumentService.debounceLint.waitForPendingTask()
1516

16-
assertThat(diagnostics, not(empty<Diagnostic>()))
17+
assertThat(diagnostics, hasSize(2))
18+
assertThat(errors, hasSize(1))
19+
assertThat(warnings, hasSize(1))
20+
}
21+
22+
@Test fun `report only errors`() {
23+
languageServer.config.diagnostics.level = DiagnosticSeverity.Error
24+
25+
// Trigger a diagnostics update via a dummy change.
26+
replace(file, 6, 1, "", " ")
27+
languageServer.textDocumentService.debounceLint.waitForPendingTask()
28+
29+
assertThat(diagnostics, hasSize(1))
30+
assertThat(errors, hasSize(1))
31+
assertThat(warnings, empty<Diagnostic>())
32+
}
33+
34+
@Test fun `disable diagnostics`() {
35+
languageServer.config.diagnostics.enabled = false
36+
37+
// Trigger a diagnostics update via a dummy change.
38+
replace(file, 1, 1, "", " ")
39+
languageServer.textDocumentService.debounceLint.waitForPendingTask()
40+
41+
assertThat(diagnostics, empty<Diagnostic>())
1742
}
1843

1944
@Test fun `only lint once for many edits in a short period`() {
2045
var text = "1"
21-
for (i in 1..10) {
46+
repeat(10) {
2247
val newText = text + "1"
2348

24-
replace(file, 3, 16, text, newText)
49+
replace(file, 7, 16, text, newText)
2550
text = newText
2651
}
2752

@@ -36,12 +61,12 @@ class LintTest : SingleFileTestFixture("lint", "LintErrors.kt") {
3661
languageServer.textDocumentService.debounceLint.waitForPendingTask()
3762
languageServer.textDocumentService.lintRecompilationCallback = {
3863
if (callbackCount++ == 0) {
39-
diagnostics.clear()
40-
replace(file, 3, 9, "return 11", "")
64+
replace(file, 7, 9, "return 11", "")
4165
languageServer.textDocumentService.documentSymbol(DocumentSymbolParams(TextDocumentIdentifier(uri(file).toString()))).get()
4266
}
4367
}
44-
replace(file, 3, 16, "", "1")
68+
replace(file, 6, 9, "Foo()", "")
69+
replace(file, 7, 16, "", "1")
4570

4671
while (callbackCount < 2) {
4772
try {

server/src/test/kotlin/org/javacs/kt/HoverTest.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package org.javacs.kt
22

33
import org.hamcrest.Matchers.*
44
import org.junit.Assert.assertThat
5+
import org.junit.Ignore
56
import org.junit.Test
67

78
class HoverLiteralsTest : SingleFileTestFixture("hover", "Literals.kt") {
@@ -52,6 +53,7 @@ class HoverObjectReferenceTest : SingleFileTestFixture("hover", "ObjectReference
5253
}
5354
}
5455

56+
@Ignore
5557
class HoverRecoverTest : SingleFileTestFixture("hover", "Recover.kt") {
5658
@Test fun `incrementally repair a single-expression function`() {
5759
replace(file, 2, 9, "\"Foo\"", "intFunction()")

server/src/test/kotlin/org/javacs/kt/LanguageServerTestFixture.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@ import java.util.concurrent.CompletableFuture
1111
abstract class LanguageServerTestFixture(relativeWorkspaceRoot: String) : LanguageClient {
1212
val workspaceRoot = absoluteWorkspaceRoot(relativeWorkspaceRoot)
1313
val languageServer = createLanguageServer()
14-
val diagnostics = mutableListOf<Diagnostic>()
14+
15+
var diagnostics = listOf<Diagnostic>()
16+
val errors: List<Diagnostic>
17+
get() = diagnostics.filter { it.severity == DiagnosticSeverity.Error }
18+
val warnings: List<Diagnostic>
19+
get() = diagnostics.filter { it.severity == DiagnosticSeverity.Warning }
1520

1621
fun absoluteWorkspaceRoot(relativeWorkspaceRoot: String): Path {
1722
val testResources = testResourcesRoot()
@@ -146,7 +151,7 @@ abstract class LanguageServerTestFixture(relativeWorkspaceRoot: String) : Langua
146151
// LanguageClient functions
147152

148153
override fun publishDiagnostics(diagnostics: PublishDiagnosticsParams) {
149-
this.diagnostics.addAll(diagnostics.diagnostics)
154+
this.diagnostics = diagnostics.diagnostics
150155
}
151156

152157
override fun showMessageRequest(request: ShowMessageRequestParams?): CompletableFuture<MessageActionItem>? {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
@Deprecated("")
2+
private class Foo {}
3+
4+
private class Diagnostics {
5+
fun foo() {
6+
Foo()
7+
return 1
8+
}
9+
}

server/src/test/resources/lint/LintErrors.kt

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)