From 9858fb71705d5dbd4a6e3017a83e1846e8dbe4b7 Mon Sep 17 00:00:00 2001 From: Artur Ayukhanov Date: Thu, 14 Dec 2023 21:37:13 +0300 Subject: [PATCH 1/9] =?UTF-8?q?=D0=BC=D0=B0=D0=B3=D0=B8=D1=87=D0=B5=D1=81?= =?UTF-8?q?=D0=BA=D0=B8=D0=B5=20=D0=B4=D0=B0=D1=82=D1=8B=20=D0=BD=D0=B0?= =?UTF-8?q?=D1=85=D0=BE=D0=B4=D0=B8=D0=BC=20=D0=B2=D0=B5=D0=B7=D0=B4=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit кроме присваиваний closes #3206 --- .../diagnostics/MagicDateDiagnostic.java | 91 +++++++++++-------- .../diagnostics/MagicDateDiagnosticTest.java | 32 ++++--- .../diagnostics/MagicDateDiagnostic.bsl | 8 +- 3 files changed, 83 insertions(+), 48 deletions(-) diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java index ab216658a53..b0f4df368f8 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java @@ -29,9 +29,7 @@ import com.github._1c_syntax.bsl.parser.BSLParser; import com.github._1c_syntax.bsl.parser.BSLParserRuleContext; import com.github._1c_syntax.utils.CaseInsensitivePattern; -import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.tree.ParseTree; -import org.antlr.v4.runtime.tree.TerminalNode; import java.util.Arrays; import java.util.HashSet; @@ -83,51 +81,72 @@ public void configure(Map configuration) { authorizedDates.addAll(authD); } - @Override - public ParseTree visitGlobalMethodCall(BSLParser.GlobalMethodCallContext ctx) { - Optional.of(ctx) - .filter(it -> methodPattern.matcher(it.methodName().getText()).matches()) - .map(BSLParser.GlobalMethodCallContext::doCall) - .map(BSLParser.DoCallContext::callParamList) - .filter(callParamList -> paramPattern.matcher(callParamList.getText()).matches()) - .ifPresent(this::checkExclAddDiagnostic); - - return super.visitGlobalMethodCall(ctx); + private static Optional getExpression(Optional contextOptional) { + return contextOptional + .map(BSLParserRuleContext::getParent) + .filter(context -> context.getChildCount() == 1) + .map(BSLParserRuleContext::getParent) + .filter(context -> context.getChildCount() == 1) + .filter(BSLParser.ExpressionContext.class::isInstance); } - @Override - public ParseTree visitConstValue(BSLParser.ConstValueContext ctx) { - TerminalNode tNode = ctx.DATETIME(); - if (tNode != null) { - checkExclAddDiagnostic(ctx); - } + private static boolean insideSimpleDateAssignment(Optional expressionContext) { + return expressionContext + .map(BSLParserRuleContext::getParent) + .filter(BSLParser.AssignmentContext.class::isInstance) + .isPresent(); + } - return ctx; + private static boolean insideAssignmentWithDateMethodForSimpleDate(Optional expressionContext) { + return expressionContext + .map(BSLParserRuleContext::getParent) // callParam + .filter(context -> context.getChildCount() == 1) + .map(BSLParserRuleContext::getParent) // callParamList + .filter(context -> context.getChildCount() == 1) + .map(BSLParserRuleContext::getParent) // doCall + .map(BSLParserRuleContext::getParent) // globalCall - метод Дата(ХХХ) + .filter(BSLParser.GlobalMethodCallContext.class::isInstance) + .map(BSLParser.GlobalMethodCallContext.class::cast) + .filter(context -> methodPattern.matcher(context.methodName().getText()).matches()) + .map(BSLParserRuleContext::getParent) // complexId + .filter(context -> context.getChildCount() == 1) + .map(BSLParserRuleContext::getParent) // member + .filter(context -> context.getChildCount() == 1) + .map(BSLParserRuleContext::getParent) // expression + .filter(context -> context.getChildCount() == 1) + .map(BSLParserRuleContext::getParent) + .filter(BSLParser.AssignmentContext.class::isInstance) + .isPresent(); } - private void checkExclAddDiagnostic(BSLParserRuleContext ctx){ - String checked = ctx.getText(); - if (checked != null && !isExcluded(checked)) { - ParserRuleContext expression; - if (ctx instanceof BSLParser.CallParamListContext){ - expression = ctx.getParent().getParent().getParent().getParent().getParent(); - } else { - expression = ctx.getParent().getParent(); + @Override + public ParseTree visitConstValue(BSLParser.ConstValueContext ctx) { + var tNode = ctx.DATETIME(); + var sNode = ctx.string(); + if ((tNode != null || sNode != null) && isAccepted(ctx)) { + var contextOptional = Optional.of(ctx); + if (sNode != null) { + contextOptional = contextOptional + .filter(constValueContext -> paramPattern.matcher(constValueContext.getText()).matches()); } - if (expression instanceof BSLParser.ExpressionContext - && (!isAssignExpression((BSLParser.ExpressionContext) expression))) { - diagnosticStorage.addDiagnostic(ctx.stop, info.getMessage(checked)); + + final var expressionContext = getExpression(contextOptional); + if (!insideSimpleDateAssignment(expressionContext) + && !insideAssignmentWithDateMethodForSimpleDate(expressionContext)) { + diagnosticStorage.addDiagnostic(ctx, info.getMessage(ctx.getText())); } } - } - private boolean isExcluded(String sIn) { - String s = nonNumberPattern.matcher(sIn).replaceAll(""); - return authorizedDates.contains(s); + return ctx; } - private static boolean isAssignExpression(BSLParser.ExpressionContext expression) { - return (expression.getChildCount() <= 1); + private boolean isAccepted(BSLParserRuleContext ctx) { + String text = ctx.getText(); + return text != null && !text.isEmpty() && !isExcluded(text); } + private boolean isExcluded(String text) { + String s = nonNumberPattern.matcher(text).replaceAll(""); + return authorizedDates.contains(s); + } } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnosticTest.java index 353c823612a..1d1bf82ef31 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnosticTest.java @@ -39,13 +39,20 @@ void test() { List diagnostics = getDiagnostics(); - assertThat(diagnostics).hasSize(5); + assertThat(diagnostics).hasSize(12); assertThat(diagnostics, true) - .hasRange(1, 12, 1, 22) - .hasRange(2, 12, 2, 28) - .hasRange(3, 7, 3, 17) - .hasRange(4, 14, 4, 24) - .hasRange(13, 7, 13, 26); + .hasRange(1, 12, 22) + .hasRange(2, 12, 28) + .hasRange(3, 7, 17) + .hasRange(4, 14, 24) + .hasRange(13, 7, 26) + .hasRange(15, 87, 97) + .hasRange(16, 80, 90) + .hasRange(16, 92, 102) + .hasRange(17, 22, 32) + .hasRange(18, 19, 35) + .hasRange(19, 10, 26) + .hasRange(19, 29, 39); } @@ -53,16 +60,19 @@ void test() { void testConfigure() { Map configuration = diagnosticInstance.getInfo().getDefaultConfiguration(); - configuration.put("authorizedDates", "00010101,00010101000000,000101010000,12340101, 00020101 ,,"); + configuration.put("authorizedDates", "00010101,00010101000000,000101010000,00050101,00020501121314,12340101, 00020101 ,,"); diagnosticInstance.configure(configuration); List diagnostics = getDiagnostics(); - assertThat(diagnostics).hasSize(3); + assertThat(diagnostics).hasSize(5); assertThat(diagnostics, true) - .hasRange(2, 12, 2, 28) - .hasRange(3, 7, 3, 17) - .hasRange(13, 7, 13, 26); + .hasRange(2, 12, 28) + .hasRange(3, 7, 17) + .hasRange(13, 7, 26) + .hasRange(13, 7, 26) + .hasRange(17, 22, 32) + .hasRange(19, 29, 39); } } diff --git a/src/test/resources/diagnostics/MagicDateDiagnostic.bsl b/src/test/resources/diagnostics/MagicDateDiagnostic.bsl index 044f4133257..7f47f947fcd 100644 --- a/src/test/resources/diagnostics/MagicDateDiagnostic.bsl +++ b/src/test/resources/diagnostics/MagicDateDiagnostic.bsl @@ -11,4 +11,10 @@ КонецЦикла; День = Дата("00010101") + Шаг; // исключение День = '0001-01why not?01' + Шаг; // исключение -День = '0001-01why not?02' + Шаг; // ошибка \ No newline at end of file +День = '0001-01why not?02' + Шаг; // ошибка + +ИменаПараметров = СтроковыеФункции.РазложитьСтрокуВМассивПодстрок(ИмяПараметра, , Дата("00050101")); // замечание +ИменаПараметров = СтроковыеФункции.РазложитьСтрокуВМассивПодстрок(ИмяПараметра, "00050101", "00050101"); // замечание +Настройки = Настройки('12350101'); // замечание +Настройки.Свойство("00020501121314", ЗначениеЕдиничногоПараметра); // замечание +Выполнить("00020501121314" + '12350101'); // замечание From 76ddd28dc211e70f8b10f94a4d5dd7b56c126829 Mon Sep 17 00:00:00 2001 From: Artur Ayukhanov Date: Thu, 14 Dec 2023 22:40:10 +0300 Subject: [PATCH 2/9] =?UTF-8?q?=D0=BE=D1=88=D0=B8=D0=B1=D0=BE=D1=87=D0=BD?= =?UTF-8?q?=D0=BE=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=B0=D1=82=D1=8B=D0=B2?= =?UTF-8?q?=D0=B0=D0=BB=D0=B8=D1=81=D1=8C=20=D1=81=D1=82=D1=80=D0=BE=D0=BA?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../diagnostics/MagicDateDiagnostic.java | 32 +++++++++---------- .../diagnostics/MagicDateDiagnostic.bsl | 5 +++ 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java index b0f4df368f8..85cb1298e90 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java @@ -71,16 +71,6 @@ public class MagicDateDiagnostic extends AbstractVisitorDiagnostic { ) private final Set authorizedDates = new HashSet<>(Arrays.asList(DEFAULT_AUTHORIZED_DATES.split(","))); - @Override - public void configure(Map configuration) { - var authorizedDatesString = (String) configuration.getOrDefault("authorizedDates", DEFAULT_AUTHORIZED_DATES); - Set authD = Arrays.stream(authorizedDatesString.split(",")) - .map(String::trim) - .collect(Collectors.toSet()); - authorizedDates.clear(); - authorizedDates.addAll(authD); - } - private static Optional getExpression(Optional contextOptional) { return contextOptional .map(BSLParserRuleContext::getParent) @@ -119,28 +109,36 @@ private static boolean insideAssignmentWithDateMethodForSimpleDate(Optional configuration) { + var authorizedDatesString = (String) configuration.getOrDefault("authorizedDates", DEFAULT_AUTHORIZED_DATES); + Set authD = Arrays.stream(authorizedDatesString.split(",")) + .map(String::trim) + .collect(Collectors.toSet()); + authorizedDates.clear(); + authorizedDates.addAll(authD); + } + @Override public ParseTree visitConstValue(BSLParser.ConstValueContext ctx) { var tNode = ctx.DATETIME(); var sNode = ctx.string(); if ((tNode != null || sNode != null) && isAccepted(ctx)) { - var contextOptional = Optional.of(ctx); - if (sNode != null) { - contextOptional = contextOptional - .filter(constValueContext -> paramPattern.matcher(constValueContext.getText()).matches()); + if (sNode != null && !paramPattern.matcher(ctx.getText()).matches()) { + return defaultResult(); } - final var expressionContext = getExpression(contextOptional); + final var expressionContext = getExpression(Optional.of(ctx)); if (!insideSimpleDateAssignment(expressionContext) && !insideAssignmentWithDateMethodForSimpleDate(expressionContext)) { diagnosticStorage.addDiagnostic(ctx, info.getMessage(ctx.getText())); } } - return ctx; + return defaultResult(); } - private boolean isAccepted(BSLParserRuleContext ctx) { + private boolean isAccepted(BSLParser.ConstValueContext ctx) { String text = ctx.getText(); return text != null && !text.isEmpty() && !isExcluded(text); } diff --git a/src/test/resources/diagnostics/MagicDateDiagnostic.bsl b/src/test/resources/diagnostics/MagicDateDiagnostic.bsl index 7f47f947fcd..cc1fd04b908 100644 --- a/src/test/resources/diagnostics/MagicDateDiagnostic.bsl +++ b/src/test/resources/diagnostics/MagicDateDiagnostic.bsl @@ -18,3 +18,8 @@ Настройки = Настройки('12350101'); // замечание Настройки.Свойство("00020501121314", ЗначениеЕдиничногоПараметра); // замечание Выполнить("00020501121314" + '12350101'); // замечание + +Значение = Метод("%1/%2"); +Если Условие Тогда + ВызватьИсключение "Не указано значение константы ХХХ"; +КонецЕсли; \ No newline at end of file From 473c87b546921d92e276c45c24ac76731ee9f10d Mon Sep 17 00:00:00 2001 From: Artur Ayukhanov Date: Fri, 15 Dec 2023 00:10:10 +0300 Subject: [PATCH 3/9] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=A4=D0=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../diagnostics/MagicDateDiagnostic.java | 42 ++++++++++++++++++- .../diagnostics/MagicDateDiagnosticTest.java | 38 ++++++++--------- .../diagnostics/MagicDateDiagnostic.bsl | 40 +++++++++++++++++- 3 files changed, 98 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java index 85cb1298e90..fc611406a09 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java @@ -58,8 +58,9 @@ public class MagicDateDiagnostic extends AbstractVisitorDiagnostic { ); private static final Pattern paramPattern = CaseInsensitivePattern.compile( - "\"\\d{8}.*" + "\"[0123]{1}\\d{7}\"|\"[0123]{1}\\d{13}\"" ); + private static final Pattern zeroPattern = Pattern.compile("^0+"); private static final Pattern nonNumberPattern = CaseInsensitivePattern.compile( "\\D" @@ -109,6 +110,43 @@ private static boolean insideAssignmentWithDateMethodForSimpleDate(Optional 3999) { + return false; + } + var month = parseInt(strDate.substring(4, 6)); + var day = parseInt(strDate.substring(6, 8)); + if (month < 1 || month > 12 || day < 1 || day > 31) { + return false; + } + if (strDate.length() == 8) { + return true; + } + var hh = parseInt(strDate.substring(8, 10)); + var mm = parseInt(strDate.substring(10, 12)); + var ss = parseInt(strDate.substring(12, 14)); + return hh <= 24 && mm <= 60 && ss <= 60; + } + + private static int parseInt(String text) { + String s = zeroPattern.matcher(text).replaceAll(""); + try { + return Integer.parseInt(s); + } catch (NumberFormatException e) { + return 0; + } + } + @Override public void configure(Map configuration) { var authorizedDatesString = (String) configuration.getOrDefault("authorizedDates", DEFAULT_AUTHORIZED_DATES); @@ -124,7 +162,7 @@ public ParseTree visitConstValue(BSLParser.ConstValueContext ctx) { var tNode = ctx.DATETIME(); var sNode = ctx.string(); if ((tNode != null || sNode != null) && isAccepted(ctx)) { - if (sNode != null && !paramPattern.matcher(ctx.getText()).matches()) { + if (sNode != null && !isValidDate(sNode)) { return defaultResult(); } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnosticTest.java index 1d1bf82ef31..4212193d79d 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnosticTest.java @@ -39,20 +39,21 @@ void test() { List diagnostics = getDiagnostics(); - assertThat(diagnostics).hasSize(12); + assertThat(diagnostics).hasSize(13); assertThat(diagnostics, true) - .hasRange(1, 12, 22) - .hasRange(2, 12, 28) - .hasRange(3, 7, 17) - .hasRange(4, 14, 24) - .hasRange(13, 7, 26) - .hasRange(15, 87, 97) - .hasRange(16, 80, 90) - .hasRange(16, 92, 102) - .hasRange(17, 22, 32) - .hasRange(18, 19, 35) - .hasRange(19, 10, 26) - .hasRange(19, 29, 39); + .hasRange(11, 12, 22) + .hasRange(12, 12, 28) + .hasRange(13, 7, 17) + .hasRange(14, 14, 24) + .hasRange(23, 7, 26) + .hasRange(25, 87, 97) + .hasRange(26, 80, 90) + .hasRange(26, 92, 102) + .hasRange(27, 22, 32) + .hasRange(28, 19, 35) + .hasRange(29, 10, 26) + .hasRange(29, 29, 39) + .hasRange(31, 64, 80); } @@ -67,12 +68,11 @@ void testConfigure() { assertThat(diagnostics).hasSize(5); assertThat(diagnostics, true) - .hasRange(2, 12, 28) - .hasRange(3, 7, 17) - .hasRange(13, 7, 26) - .hasRange(13, 7, 26) - .hasRange(17, 22, 32) - .hasRange(19, 29, 39); + .hasRange(12, 12, 28) + .hasRange(13, 7, 17) + .hasRange(23, 7, 26) + .hasRange(27, 22, 32) + .hasRange(29, 29, 39); } } diff --git a/src/test/resources/diagnostics/MagicDateDiagnostic.bsl b/src/test/resources/diagnostics/MagicDateDiagnostic.bsl index cc1fd04b908..a89df894f87 100644 --- a/src/test/resources/diagnostics/MagicDateDiagnostic.bsl +++ b/src/test/resources/diagnostics/MagicDateDiagnostic.bsl @@ -1,3 +1,13 @@ +Функция МаксимальнаяДата() Экспорт + //Возврат '39991231235959'; // TODO +КонецФункции + +Функция МаксимальнаяДатаПриПродолжении() + //Возврат '39990101000000'; // TODO +КонецФункции + +Процедура Тест3() + День = Дата("00020101"); День = Дата("00020101") + Шаг; // ошибка День = Дата("00020101121314") + Шаг; // ошибка @@ -19,7 +29,35 @@ Настройки.Свойство("00020501121314", ЗначениеЕдиничногоПараметра); // замечание Выполнить("00020501121314" + '12350101'); // замечание +ОтборЭлемента.ПравоеЗначение = Новый СтандартнаяДатаНачала(Дата('19800101000000')); + Значение = Метод("%1/%2"); Если Условие Тогда ВызватьИсключение "Не указано значение константы ХХХ"; -КонецЕсли; \ No newline at end of file +КонецЕсли; + +УИДЗамера = Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000"); +ПосторонниеСимволы = СтрСоединить(СтрРазделить(СтрокаСЧислом, "0123456789", Ложь), ""); +Объект.GetStringValue("2147483649","Software\Buhphone","ProgramPath", Значение); +НедопустимыеСимволы = НедопустимыеСимволыВСтроке(СтрАдрес.АдресСервера, + "0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ_-.:*?"); +НедопустимыеСимволы = НедопустимыеСимволы + "1234567890 "; + +Дата = Метод("04937803-5dba-11df-a1d4-005056c00008"); +Набор.Идентификатор = Новый УникальныйИдентификатор("70425541-23e3-4e5a-8bd3-9587cc949dfa"); + +НецифровыеСимволы = СтрСоединить(СтрРазделить(Значение, "1234567890,.")); +Результат = Сред("0123456789abcdef", ОстатокОтДеления + 1, 1) + Результат; + +Результат.Добавить(СтрокаОбъектаАдресации("10100000", НСтр("ru = 'Почтовый индекс'"))); +КодСтроки = КодРодителя + Прав("00000000" + Формат(Счетчик, "ЧГ="), ЧислоЦифр); +КлючНаборовСвойств = НачалоКлюча + Лев(КлючНазначения + "00000000000000000000000000000000", 32); + +КодыКЛАДР.Регион = Лев(КодКЛАДР, 2) + "00000000000"; +КодыКЛАДР.Район = Лев(КодКЛАДР, 5) + "00000000"; + +//'39990202' +//'39991231235959' +//'39990101000000' + +КонецПроцедуры \ No newline at end of file From 3598cc30a12cdbf7e4c1fb862daa303d228f92a8 Mon Sep 17 00:00:00 2001 From: Artur Ayukhanov Date: Fri, 15 Dec 2023 00:21:04 +0300 Subject: [PATCH 4/9] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D0=BF=D0=B0=D0=B4=D0=B0=D1=8E=D1=89=D0=B8=D0=B9?= =?UTF-8?q?=20=D1=82=D0=B5=D1=81=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../languageserver/diagnostics/MagicDateDiagnosticTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnosticTest.java index 4212193d79d..79f0acb71fb 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnosticTest.java @@ -66,13 +66,13 @@ void testConfigure() { List diagnostics = getDiagnostics(); - assertThat(diagnostics).hasSize(5); + assertThat(diagnostics).hasSize(6); assertThat(diagnostics, true) .hasRange(12, 12, 28) .hasRange(13, 7, 17) .hasRange(23, 7, 26) .hasRange(27, 22, 32) - .hasRange(29, 29, 39); - + .hasRange(29, 29, 39) + .hasRange(31, 64, 80); } } From 6d21f3929dd4c15628746a09f7e697dfd3a45e32 Mon Sep 17 00:00:00 2001 From: Artur Ayukhanov Date: Fri, 15 Dec 2023 17:38:37 +0300 Subject: [PATCH 5/9] =?UTF-8?q?=D0=B8=D1=81=D0=BA=D0=BB=D1=8E=D1=87=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=92=D0=BE=D0=B7=D0=B2=D1=80=D0=B0=D1=82?= =?UTF-8?q?=20=D0=94=D0=B0=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit улучшено описание правила --- docs/diagnostics/MagicDate.md | 13 ++ .../diagnostics/MagicDateDiagnostic.java | 134 ++++++++++-------- .../diagnostics/MagicDateDiagnostic.bsl | 4 +- 3 files changed, 87 insertions(+), 64 deletions(-) diff --git a/docs/diagnostics/MagicDate.md b/docs/diagnostics/MagicDate.md index 9f76aaa598b..986489a1b5c 100644 --- a/docs/diagnostics/MagicDate.md +++ b/docs/diagnostics/MagicDate.md @@ -22,3 +22,16 @@ ХоверБордБудетИзобретен = Неопределено; КонецЕсли; ``` + +Также хорошим решением является использование специального метода с говорящим названием, который возвращает +дату-константу + +```bsl +Функция ДатаИзобретенияХовера() + Возврат '20151021'; +КонецФункции + +Если текДата < ДатаИзобретенияХовера() Тогда + ХоверБордБудетИзобретен = Неопределено; +КонецЕсли; +``` diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java index fc611406a09..eb8df9b7e00 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java @@ -72,42 +72,33 @@ public class MagicDateDiagnostic extends AbstractVisitorDiagnostic { ) private final Set authorizedDates = new HashSet<>(Arrays.asList(DEFAULT_AUTHORIZED_DATES.split(","))); - private static Optional getExpression(Optional contextOptional) { - return contextOptional - .map(BSLParserRuleContext::getParent) - .filter(context -> context.getChildCount() == 1) - .map(BSLParserRuleContext::getParent) - .filter(context -> context.getChildCount() == 1) - .filter(BSLParser.ExpressionContext.class::isInstance); + @Override + public void configure(Map configuration) { + var authorizedDatesString = (String) configuration.getOrDefault("authorizedDates", DEFAULT_AUTHORIZED_DATES); + Set authD = Arrays.stream(authorizedDatesString.split(",")) + .map(String::trim) + .collect(Collectors.toSet()); + authorizedDates.clear(); + authorizedDates.addAll(authD); } - private static boolean insideSimpleDateAssignment(Optional expressionContext) { - return expressionContext - .map(BSLParserRuleContext::getParent) - .filter(BSLParser.AssignmentContext.class::isInstance) - .isPresent(); - } + @Override + public ParseTree visitConstValue(BSLParser.ConstValueContext ctx) { + var tNode = ctx.DATETIME(); + var sNode = ctx.string(); + if ((tNode != null || sNode != null) && isAccepted(ctx)) { + if (sNode != null && !isValidDate(sNode)) { + return defaultResult(); + } - private static boolean insideAssignmentWithDateMethodForSimpleDate(Optional expressionContext) { - return expressionContext - .map(BSLParserRuleContext::getParent) // callParam - .filter(context -> context.getChildCount() == 1) - .map(BSLParserRuleContext::getParent) // callParamList - .filter(context -> context.getChildCount() == 1) - .map(BSLParserRuleContext::getParent) // doCall - .map(BSLParserRuleContext::getParent) // globalCall - метод Дата(ХХХ) - .filter(BSLParser.GlobalMethodCallContext.class::isInstance) - .map(BSLParser.GlobalMethodCallContext.class::cast) - .filter(context -> methodPattern.matcher(context.methodName().getText()).matches()) - .map(BSLParserRuleContext::getParent) // complexId - .filter(context -> context.getChildCount() == 1) - .map(BSLParserRuleContext::getParent) // member - .filter(context -> context.getChildCount() == 1) - .map(BSLParserRuleContext::getParent) // expression - .filter(context -> context.getChildCount() == 1) - .map(BSLParserRuleContext::getParent) - .filter(BSLParser.AssignmentContext.class::isInstance) - .isPresent(); + final var expressionContext = getExpression(Optional.of(ctx)); + if (!insideSimpleDateAssignment(expressionContext) && !insideReturnSimpleDate(expressionContext) + && !insideAssignmentWithDateMethodForSimpleDate(expressionContext)) { + diagnosticStorage.addDiagnostic(ctx, info.getMessage(ctx.getText())); + } + } + + return defaultResult(); } private static boolean isValidDate(BSLParser.StringContext ctx) { @@ -147,35 +138,6 @@ private static int parseInt(String text) { } } - @Override - public void configure(Map configuration) { - var authorizedDatesString = (String) configuration.getOrDefault("authorizedDates", DEFAULT_AUTHORIZED_DATES); - Set authD = Arrays.stream(authorizedDatesString.split(",")) - .map(String::trim) - .collect(Collectors.toSet()); - authorizedDates.clear(); - authorizedDates.addAll(authD); - } - - @Override - public ParseTree visitConstValue(BSLParser.ConstValueContext ctx) { - var tNode = ctx.DATETIME(); - var sNode = ctx.string(); - if ((tNode != null || sNode != null) && isAccepted(ctx)) { - if (sNode != null && !isValidDate(sNode)) { - return defaultResult(); - } - - final var expressionContext = getExpression(Optional.of(ctx)); - if (!insideSimpleDateAssignment(expressionContext) - && !insideAssignmentWithDateMethodForSimpleDate(expressionContext)) { - diagnosticStorage.addDiagnostic(ctx, info.getMessage(ctx.getText())); - } - } - - return defaultResult(); - } - private boolean isAccepted(BSLParser.ConstValueContext ctx) { String text = ctx.getText(); return text != null && !text.isEmpty() && !isExcluded(text); @@ -185,4 +147,52 @@ private boolean isExcluded(String text) { String s = nonNumberPattern.matcher(text).replaceAll(""); return authorizedDates.contains(s); } + + private static Optional getExpression(Optional constValue) { + return constValue + .map(BSLParserRuleContext::getParent) + .filter(context -> context.getChildCount() == 1) + .map(BSLParserRuleContext::getParent) + .filter(context -> context.getChildCount() == 1) + .filter(BSLParser.ExpressionContext.class::isInstance) + .map(BSLParser.ExpressionContext.class::cast); + } + + private static boolean insideSimpleDateAssignment(Optional expression) { + return insideContext(expression, BSLParser.AssignmentContext.class); + } + + private static boolean insideContext(Optional expression, + Class assignmentContextClass) { + return expression + .map(BSLParserRuleContext::getParent) + .filter(assignmentContextClass::isInstance) + .isPresent(); + } + + private static boolean insideReturnSimpleDate(Optional expression) { + return insideContext(expression, BSLParser.ReturnStatementContext.class); + } + + private static boolean insideAssignmentWithDateMethodForSimpleDate(Optional expression) { + return expression + .map(BSLParserRuleContext::getParent) // callParam + .filter(context -> context.getChildCount() == 1) + .map(BSLParserRuleContext::getParent) // callParamList + .filter(context -> context.getChildCount() == 1) + .map(BSLParserRuleContext::getParent) // doCall + .map(BSLParserRuleContext::getParent) // globalCall - метод Дата(ХХХ) + .filter(BSLParser.GlobalMethodCallContext.class::isInstance) + .map(BSLParser.GlobalMethodCallContext.class::cast) + .filter(context -> methodPattern.matcher(context.methodName().getText()).matches()) + .map(BSLParserRuleContext::getParent) // complexId + .filter(context -> context.getChildCount() == 1) + .map(BSLParserRuleContext::getParent) // member + .filter(context -> context.getChildCount() == 1) + .map(BSLParserRuleContext::getParent) // expression + .filter(context -> context.getChildCount() == 1) + .map(BSLParserRuleContext::getParent) + .filter(BSLParser.AssignmentContext.class::isInstance) + .isPresent(); + } } diff --git a/src/test/resources/diagnostics/MagicDateDiagnostic.bsl b/src/test/resources/diagnostics/MagicDateDiagnostic.bsl index a89df894f87..f83a88c487c 100644 --- a/src/test/resources/diagnostics/MagicDateDiagnostic.bsl +++ b/src/test/resources/diagnostics/MagicDateDiagnostic.bsl @@ -1,9 +1,9 @@ Функция МаксимальнаяДата() Экспорт - //Возврат '39991231235959'; // TODO + Возврат '39991231235959'; КонецФункции Функция МаксимальнаяДатаПриПродолжении() - //Возврат '39990101000000'; // TODO + Возврат '39990101000000'; КонецФункции Процедура Тест3() From f9d0f3fc1a464233a6707475104b4b1946fd7729 Mon Sep 17 00:00:00 2001 From: Artur Ayukhanov Date: Sun, 17 Dec 2023 10:20:55 +0300 Subject: [PATCH 6/9] =?UTF-8?q?=D0=B4=D0=BE=D0=BF.=D1=82=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D1=8B=20=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - значения по умолчанию - условия - тернарный оператор --- .../diagnostics/MagicDateDiagnosticTest.java | 18 +++++++++++++----- .../diagnostics/MagicDateDiagnostic.bsl | 12 ++++++++---- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnosticTest.java index 79f0acb71fb..199057693a1 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnosticTest.java @@ -39,7 +39,7 @@ void test() { List diagnostics = getDiagnostics(); - assertThat(diagnostics).hasSize(13); + assertThat(diagnostics).hasSize(18); assertThat(diagnostics, true) .hasRange(11, 12, 22) .hasRange(12, 12, 28) @@ -53,8 +53,12 @@ void test() { .hasRange(28, 19, 35) .hasRange(29, 10, 26) .hasRange(29, 29, 39) - .hasRange(31, 64, 80); - + .hasRange(31, 64, 80) + .hasRange(58, 17, 27) + .hasRange(58, 29, 45) + .hasRange(58, 47, 63) + .hasRange(60, 19, 29) + .hasRange(65, 22, 32); } @Test @@ -66,13 +70,17 @@ void testConfigure() { List diagnostics = getDiagnostics(); - assertThat(diagnostics).hasSize(6); + assertThat(diagnostics).hasSize(10); assertThat(diagnostics, true) .hasRange(12, 12, 28) .hasRange(13, 7, 17) .hasRange(23, 7, 26) .hasRange(27, 22, 32) .hasRange(29, 29, 39) - .hasRange(31, 64, 80); + .hasRange(31, 64, 80) + .hasRange(58, 17, 27) + .hasRange(58, 29, 45) + .hasRange(58, 47, 63) + .hasRange(65, 22, 32); } } diff --git a/src/test/resources/diagnostics/MagicDateDiagnostic.bsl b/src/test/resources/diagnostics/MagicDateDiagnostic.bsl index f83a88c487c..aaf8626edc8 100644 --- a/src/test/resources/diagnostics/MagicDateDiagnostic.bsl +++ b/src/test/resources/diagnostics/MagicDateDiagnostic.bsl @@ -56,8 +56,12 @@ КодыКЛАДР.Регион = Лев(КодКЛАДР, 2) + "00000000000"; КодыКЛАДР.Район = Лев(КодКЛАДР, 5) + "00000000"; -//'39990202' -//'39991231235959' -//'39990101000000' +Значение = ?(А = '39990202', '39991231235959', '39990101000000'); -КонецПроцедуры \ No newline at end of file +Если Сейчас < Дата("12340101") Тогда +КонецЕсли; + +КонецПроцедуры + +Функция Метод(Дата1 = '39990202') +КонецФункции From eccb841c127c14a1aeee2ab3d1fc34a080919233 Mon Sep 17 00:00:00 2001 From: Artur Ayukhanov Date: Mon, 18 Dec 2023 18:11:36 +0300 Subject: [PATCH 7/9] =?UTF-8?q?=D0=B2=D1=8B=D0=B4=D0=B5=D0=BB=D0=B8=D0=BB?= =?UTF-8?q?=20=D0=BA=D0=BE=D0=BD=D1=81=D1=82=D0=B0=D0=BD=D1=82=D1=83=20MAX?= =?UTF-8?q?=5FYEAR=5FBY=5F1C=203999?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bsl/languageserver/diagnostics/MagicDateDiagnostic.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java index eb8df9b7e00..fa0cb641566 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java @@ -65,6 +65,7 @@ public class MagicDateDiagnostic extends AbstractVisitorDiagnostic { private static final Pattern nonNumberPattern = CaseInsensitivePattern.compile( "\\D" ); + public static final int MAX_YEAR_BY_1C = 3999; @DiagnosticParameter( type = String.class, @@ -112,7 +113,7 @@ private static boolean isValidDate(BSLParser.StringContext ctx) { private static boolean isValidDate(String strDate) { var year = parseInt(strDate.substring(0, 4)); - if (year < 1 || year > 3999) { + if (year < 1 || year > MAX_YEAR_BY_1C) { return false; } var month = parseInt(strDate.substring(4, 6)); From d2b92dfcbcd842ab3698c8e065c15f6484bad258 Mon Sep 17 00:00:00 2001 From: Artur Ayukhanov Date: Tue, 4 Jun 2024 10:38:05 +0300 Subject: [PATCH 8/9] =?UTF-8?q?=D0=9C=D0=B0=D0=BA=D1=81=D0=B8=D0=BC=D0=B0?= =?UTF-8?q?=D0=BB=D1=8C=D0=BD=D0=B0=D1=8F=20=D0=B4=D0=B0=D1=82=D0=B0=20999?= =?UTF-8?q?9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bsl/languageserver/diagnostics/MagicDateDiagnostic.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java index 37ae8273d59..362eace6414 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java @@ -65,7 +65,7 @@ public class MagicDateDiagnostic extends AbstractVisitorDiagnostic { private static final Pattern nonNumberPattern = CaseInsensitivePattern.compile( "\\D" ); - public static final int MAX_YEAR_BY_1C = 3999; + public static final int MAX_YEAR_BY_1C = 9999; @DiagnosticParameter( type = String.class, From 247cd8c5ea826079d5e22e52b581ad17ae4145fb Mon Sep 17 00:00:00 2001 From: Artur Ayukhanov Date: Tue, 4 Jun 2024 10:42:35 +0300 Subject: [PATCH 9/9] =?UTF-8?q?=D1=82=D0=B5=D1=81=D1=82=20=D0=BD=D0=B0=20?= =?UTF-8?q?=D0=BC=D0=B0=D0=BA=D1=81=D0=B8=D0=BC=D0=B0=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D1=83=D1=8E=20=D0=B4=D0=B0=D1=82=D1=83=209999=D0=B3.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/resources/diagnostics/MagicDateDiagnostic.bsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/resources/diagnostics/MagicDateDiagnostic.bsl b/src/test/resources/diagnostics/MagicDateDiagnostic.bsl index aaf8626edc8..201c9c8311c 100644 --- a/src/test/resources/diagnostics/MagicDateDiagnostic.bsl +++ b/src/test/resources/diagnostics/MagicDateDiagnostic.bsl @@ -3,7 +3,7 @@ КонецФункции Функция МаксимальнаяДатаПриПродолжении() - Возврат '39990101000000'; + Возврат '99990101000000'; КонецФункции Процедура Тест3()