diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DiagnosticHelper.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DiagnosticHelper.java index cbbaa65b7d1..b039474f6c2 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DiagnosticHelper.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DiagnosticHelper.java @@ -28,8 +28,11 @@ import org.antlr.v4.runtime.tree.ParseTree; import org.jspecify.annotations.Nullable; +import java.lang.reflect.Field; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.StringJoiner; @@ -122,6 +125,7 @@ public static void configureDiagnostic(BSLDiagnostic diagnostic, @Nullable Map configuration.containsKey(diagnosticParameterInfo.getName()) @@ -130,14 +134,39 @@ public static void configureDiagnostic(BSLDiagnostic diagnostic, @Nullable Map + * Для полей типа {@link List} значение может прийти как строка (элементы через запятую — + * например, из SonarQube UI) либо как JSON-массив (десериализуется Jackson в {@link List}). + * В обоих случаях возвращается {@code List}. Для остальных полей значение + * возвращается без изменений. + * + * @param field Целевое поле диагностики + * @param value Значение из конфигурации ({@code String}, {@code List} и т.п.) + * @return Значение, пригодное для присвоения полю + */ + private static @Nullable Object castParameterValue(Field field, @Nullable Object value) { + if (value == null) { + return null; + } + if (List.class.isAssignableFrom(field.getType())) { + if (value instanceof List list) { + return list.stream().map(String::valueOf).toList(); + } + return asStringList(value.toString()); + } + return value; + } + /** * Настроить параметры диагностики с фильтрацией по именам параметров. * @@ -158,6 +187,23 @@ public static void configureDiagnostic(BSLDiagnostic diagnostic, configureDiagnostic(diagnostic, newConfiguration); } + /** + * Разбирает строку с элементами через запятую в список строк. + *

+ * Используется как для значения параметра-списка из конфигурации в строковой форме + * (SonarQube UI, «старые» конфиги), так и для инициализации поля значением по умолчанию. + * Элементы обрезаются по краям от пробелов; пустые элементы отбрасываются. + * + * @param value Строка с элементами через запятую + * @return Список строк без пустых элементов + */ + public static List asStringList(String value) { + return Arrays.stream(value.split(",")) + .map(String::trim) + .filter(element -> !element.isEmpty()) + .toList(); + } + /** * Создает PATTERN из строки со словами с разделителем ',' (запятая) (используется в параметрах диагностики). * При создании паттерна удаляются концевые пробелы слов diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic.java index 0c4dc258edf..94f54ddc858 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic.java @@ -106,9 +106,9 @@ public class TypoDiagnostic extends AbstractDiagnostic { private int minWordLength = DEFAULT_MIN_WORD_LENGTH; @DiagnosticParameter( - type = String.class + type = List.class ) - private String userWordsToIgnore = DEFAULT_USER_WORDS_TO_IGNORE; + private List userWordsToIgnore = DiagnosticHelper.asStringList(DEFAULT_USER_WORDS_TO_IGNORE); /** * Готовый список слов для игнорирования @@ -130,8 +130,9 @@ public void configure(Map configuration) { private Set makeWordsToIgnore() { var delimiter = ','; var exceptions = SPACES_PATTERN.matcher(info.getResourceString("diagnosticExceptions")).replaceAll(""); - if (!userWordsToIgnore.isEmpty()) { - exceptions += delimiter + SPACES_PATTERN.matcher(userWordsToIgnore).replaceAll(""); + var userWords = String.join(String.valueOf(delimiter), userWordsToIgnore); + if (!userWords.isEmpty()) { + exceptions += delimiter + SPACES_PATTERN.matcher(userWords).replaceAll(""); } // добавим к переданным строки в разных регистрах diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/info/DiagnosticParameterInfo.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/info/DiagnosticParameterInfo.java index af5a816461b..2471188ff91 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/info/DiagnosticParameterInfo.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/info/DiagnosticParameterInfo.java @@ -58,6 +58,10 @@ private Object castDiagnosticParameterValue(String valueToCast) { value = Float.parseFloat(valueToCast); } else if (type == String.class) { value = valueToCast; + } else if (type == List.class) { + // Параметр-список: внешнее (config/SonarQube) представление по умолчанию — строка через запятую. + // В List значение разбирается при применении конфигурации (см. DiagnosticHelper). + value = valueToCast; } else { throw new IllegalArgumentException("Unsupported diagnostic parameter type " + type); } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnosticTest.java index c39801429c4..af7768e9f56 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnosticTest.java @@ -112,4 +112,18 @@ void testConfigureUserWordsToIgnoreWithSpaces() { assertThat(diagnostics, true) .hasRange(8, 13, 8, 18); } + + @Test + void testConfigureUserWordsToIgnoreAsList() { + + Map configuration = diagnosticInstance.getInfo().getDefaultConfiguration(); + configuration.put("userWordsToIgnore", List.of("Варинаты", "Атмена")); + diagnosticInstance.configure(configuration); + + List diagnostics = getDiagnostics(); + + assertThat(diagnostics).hasSize(1); + assertThat(diagnostics, true) + .hasRange(8, 13, 8, 18); + } }