Skip to content

Commit

Permalink
Add support for rule-dependent severities
Browse files Browse the repository at this point in the history
Fixes #95.
  • Loading branch information
valentjn committed Aug 10, 2021
1 parent 7a2f4f9 commit ac6147f
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 21 deletions.
3 changes: 3 additions & 0 deletions changelog.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
<action type="add" issue="#71">
Add non-server batch mode via `--input-documents`
</action>
<action type="add" issue="#95">
Add support for rule-dependent diagnostic severities in [`ltex.diagnosticSeverity`](https://valentjn.github.io/vscode-ltex/docs/settings.html#ltexdiagnosticseverity)
</action>
<action type="add" issue="vscode-ltex#366">
Add support for vowel dummies in LaTeX (`"vowelDummy"` in [`ltex.latex.commands`](https://valentjn.github.io/vscode-ltex/docs/settings.html#ltexlatexcommands)) and Markdown (`"vowelDummy"` in [`ltex.markdown.nodes`](https://valentjn.github.io/vscode-ltex/docs/settings.html#ltexmarkdownnodes))
</action>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import org.eclipse.lsp4j.CodeActionKind
import org.eclipse.lsp4j.CodeActionParams
import org.eclipse.lsp4j.Command
import org.eclipse.lsp4j.Diagnostic
import org.eclipse.lsp4j.DiagnosticSeverity
import org.eclipse.lsp4j.Range
import org.eclipse.lsp4j.ResourceOperation
import org.eclipse.lsp4j.TextDocumentEdit
Expand All @@ -36,7 +37,14 @@ class CodeActionGenerator(
val diagnostic = Diagnostic()
diagnostic.range = Range(document.convertPosition(match.fromPos),
document.convertPosition(match.toPos))
diagnostic.severity = this.settingsManager.settings.diagnosticSeverity

val diagnosticSeverityMap: Map<String, DiagnosticSeverity> =
this.settingsManager.settings.diagnosticSeverity
var diagnosticSeverity: DiagnosticSeverity? = diagnosticSeverityMap[match.ruleId]
if (diagnosticSeverity == null) diagnosticSeverity = diagnosticSeverityMap["default"]
if (diagnosticSeverity == null) diagnosticSeverity = DiagnosticSeverity.Information
diagnostic.severity = diagnosticSeverity

diagnostic.source = "LTeX"
diagnostic.message = match.message.replace(SUGGESTION_REGEX, "'$1'") + " \u2013 " + match.ruleId
return diagnostic
Expand Down
89 changes: 75 additions & 14 deletions src/main/kotlin/org/bsplines/ltexls/settings/Settings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ data class Settings(
private val _languageToolHttpServerUri: String? = null,
private val _logLevel: Level? = null,
private val _sentenceCacheSize: Long? = null,
private val _diagnosticSeverity: DiagnosticSeverity? = null,
private val _diagnosticSeverity: Map<String, DiagnosticSeverity>? = null,
private val _checkFrequency: CheckFrequency? = null,
private val _clearDiagnosticsWhenClosingFile: Boolean? = null,
) {
Expand Down Expand Up @@ -74,8 +74,8 @@ data class Settings(
get() = (this._logLevel ?: Level.FINE)
val sentenceCacheSize: Long
get() = (this._sentenceCacheSize ?: DEFAULT_SENTENCE_CACHE_SIZE)
val diagnosticSeverity: DiagnosticSeverity
get() = (this._diagnosticSeverity ?: DiagnosticSeverity.Information)
val diagnosticSeverity: Map<String, DiagnosticSeverity>
get() = (this._diagnosticSeverity ?: DEFAULT_DIAGNOSTIC_SEVERITY)
val checkFrequency: CheckFrequency
get() = (this._checkFrequency ?: CheckFrequency.Edit)
val clearDiagnosticsWhenClosingFile: Boolean
Expand Down Expand Up @@ -174,6 +174,8 @@ data class Settings(
val DEFAULT_ENABLED = setOf(
"bibtex", "latex", "html", "markdown", "org", "restructuredtext", "rsweave")
private const val DEFAULT_SENTENCE_CACHE_SIZE = 2000L
private val DEFAULT_DIAGNOSTIC_SEVERITY: Map<String, DiagnosticSeverity> =
mapOf(Pair("default", DiagnosticSeverity.Information))

@Suppress("LongMethod")
fun fromJson(
Expand Down Expand Up @@ -229,11 +231,8 @@ data class Settings(
),
)
val sentenceCacheSize: Long? = getSettingFromJsonAsLong(jsonSettings, "sentenceCacheSize")
val diagnosticSeverity: DiagnosticSeverity? = getSettingFromJsonAsEnum(
jsonSettings,
"diagnosticSeverity",
DiagnosticSeverity::class.java.enumConstants,
)
val diagnosticSeverity: Map<String, DiagnosticSeverity>? =
getDiagnosticSeverityFromJson(jsonSettings)
val checkFrequency: CheckFrequency? = getSettingFromJsonAsEnum(
jsonSettings,
"checkFrequency",
Expand Down Expand Up @@ -320,18 +319,43 @@ data class Settings(
}
}

private fun getDiagnosticSeverityFromJson(
jsonSettings: JsonElement,
): Map<String, DiagnosticSeverity>? {
val jsonElement: JsonElement? =
getSettingFromJsonAsJsonElement(jsonSettings, "diagnosticSeverity")

return if (jsonElement == null) {
null
} else if (jsonElement.isJsonObject) {
convertJsonObjectToMapOfEnums(
jsonElement.asJsonObject,
DiagnosticSeverity::class.java.enumConstants,
)
} else if (jsonElement.isJsonPrimitive) {
val jsonPrimitive: JsonPrimitive = jsonElement.asJsonPrimitive

if (jsonPrimitive.isString) {
val enumValue: DiagnosticSeverity? = convertStringToEnum(
jsonPrimitive.asString,
DiagnosticSeverity::class.java.enumConstants,
)
if (enumValue != null) mapOf(Pair("default", enumValue)) else null
} else {
null
}
} else {
null
}
}

private fun <T> getSettingFromJsonAsEnum(
jsonSettings: JsonElement,
name: String,
enumValues: Array<T>,
): T? {
val enumString: String = getSettingFromJsonAsString(jsonSettings, name) ?: return null

for (enumValue: T in enumValues) {
if (enumValue.toString().equals(enumString, ignoreCase = true)) return enumValue
}

return null
return convertStringToEnum(enumString, enumValues)
}

private fun getSettingFromJsonAsJsonElement(
Expand Down Expand Up @@ -506,6 +530,43 @@ data class Settings(
return map
}

private fun <T> convertJsonObjectToMapOfEnums(
obj: JsonObject?,
enumValues: Array<T>,
): Map<String, T>? {
if (obj == null) return null
val map = HashMap<String, T>()

for (entry: Map.Entry<String, JsonElement> in obj.entrySet()) {
val enumValue: T? = convertJsonElementToEnum(entry.value, enumValues)
if (enumValue != null) map[entry.key] = enumValue
}

return map
}

private fun <T> convertJsonElementToEnum(jsonElement: JsonElement, enumValues: Array<T>): T? {
return if (jsonElement.isJsonPrimitive) {
val jsonPrimitive: JsonPrimitive = jsonElement.asJsonPrimitive

if (jsonPrimitive.isString) {
convertStringToEnum(jsonPrimitive.asString, enumValues)
} else {
null
}
} else {
null
}
}

private fun <T> convertStringToEnum(enumString: String, enumValues: Array<T>): T? {
for (enumValue: T in enumValues) {
if (enumValue.toString().equals(enumString, ignoreCase = true)) return enumValue
}

return null
}

private fun mergeMapOfListsIntoMapOfSets(
mapOfLists: Map<String, List<String>>?,
): Map<String, Set<String>>? {
Expand Down
26 changes: 20 additions & 6 deletions src/test/kotlin/org/bsplines/ltexls/settings/SettingsTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ class SettingsTest {
assertEquals(1337, settings.sentenceCacheSize)
settings2 = compareSettings(settings, settings2, true)

settings = settings.copy(_diagnosticSeverity = DiagnosticSeverity.Error)
assertEquals(DiagnosticSeverity.Error, settings.diagnosticSeverity)
settings = settings.copy(_diagnosticSeverity = mapOf(Pair("ruleId", DiagnosticSeverity.Error)))
assertEquals(mapOf(Pair("ruleId", DiagnosticSeverity.Error)), settings.diagnosticSeverity)
settings2 = compareSettings(settings, settings2, false)

settings = settings.copy(_checkFrequency = Settings.CheckFrequency.Manual)
Expand Down Expand Up @@ -270,19 +270,33 @@ class SettingsTest {

jsonSettings.addProperty("diagnosticSeverity", "error")
settings = Settings.fromJson(jsonSettings, jsonWorkspaceSpecificSettings)
assertEquals(DiagnosticSeverity.Error, settings.diagnosticSeverity)
assertEquals(mapOf(Pair("default", DiagnosticSeverity.Error)), settings.diagnosticSeverity)

jsonSettings.addProperty("diagnosticSeverity", "warning")
settings = Settings.fromJson(jsonSettings, jsonWorkspaceSpecificSettings)
assertEquals(DiagnosticSeverity.Warning, settings.diagnosticSeverity)
assertEquals(mapOf(Pair("default", DiagnosticSeverity.Warning)), settings.diagnosticSeverity)

jsonSettings.addProperty("diagnosticSeverity", "information")
settings = Settings.fromJson(jsonSettings, jsonWorkspaceSpecificSettings)
assertEquals(DiagnosticSeverity.Information, settings.diagnosticSeverity)
assertEquals(
mapOf(Pair("default", DiagnosticSeverity.Information)),
settings.diagnosticSeverity,
)

jsonSettings.addProperty("diagnosticSeverity", "hint")
settings = Settings.fromJson(jsonSettings, jsonWorkspaceSpecificSettings)
assertEquals(DiagnosticSeverity.Hint, settings.diagnosticSeverity)
assertEquals(mapOf(Pair("default", DiagnosticSeverity.Hint)), settings.diagnosticSeverity)

val diagnosticSeverity = JsonObject()
diagnosticSeverity.addProperty("ruleId", "warning")
diagnosticSeverity.addProperty("default", "error")

jsonSettings.add("diagnosticSeverity", diagnosticSeverity)
settings = Settings.fromJson(jsonSettings, jsonWorkspaceSpecificSettings)
assertEquals(
mapOf(Pair("ruleId", DiagnosticSeverity.Warning), Pair("default", DiagnosticSeverity.Error)),
settings.diagnosticSeverity,
)

jsonSettings.addProperty("checkFrequency", "edit")
settings = Settings.fromJson(jsonSettings, jsonWorkspaceSpecificSettings)
Expand Down

0 comments on commit ac6147f

Please sign in to comment.