From c1d49f518cf6e321ff7dd9dd8a0b172f5de81e5b Mon Sep 17 00:00:00 2001 From: Andrey Ovsyankin Date: Mon, 3 Jun 2024 19:26:19 +0300 Subject: [PATCH 01/13] =?UTF-8?q?=D0=97=D0=B0=D0=B3=D0=BE=D1=82=D0=BE?= =?UTF-8?q?=D0=B2=D0=BA=D0=B0=20=D0=B4=D0=B8=D0=B0=D0=B3=D0=BD=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D0=B8=D0=BA=D0=B8=20=D0=B8=20=D0=BA=D1=80=D0=B0=D1=81?= =?UTF-8?q?=D0=BD=D1=8B=D0=B9=20=D1=82=D0=B5=D1=81=D1=82=20=D0=BD=D0=B0=20?= =?UTF-8?q?=D0=BF=D0=BE=D1=81=D1=82=D1=80=D0=BE=D0=B8=D1=82=D0=B5=D0=BB?= =?UTF-8?q?=D1=8C=20=D0=B2=D1=8B=D1=80=D0=B0=D0=B6=D0=B5=D0=BD=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/diagnostics/DoubleNegatives.md | 30 ++++++++++++++ docs/en/diagnostics/DoubleNegatives.md | 28 +++++++++++++ .../DoubleNegativesDiagnostic.java | 38 ++++++++++++++++++ .../DoubleNegativesDiagnostic_en.properties | 2 + .../DoubleNegativesDiagnostic_ru.properties | 2 + .../DoubleNegativesDiagnosticTest.java | 25 ++++++++++++ .../ExpressionParseTreeRewriterTest.java | 19 +++++++++ .../diagnostics/DoubleNegativesDiagnostic.bsl | 40 +++++++++++++++++++ 8 files changed, 184 insertions(+) create mode 100644 docs/diagnostics/DoubleNegatives.md create mode 100644 docs/en/diagnostics/DoubleNegatives.md create mode 100644 src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java create mode 100644 src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic_en.properties create mode 100644 src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic_ru.properties create mode 100644 src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnosticTest.java create mode 100644 src/test/resources/diagnostics/DoubleNegativesDiagnostic.bsl diff --git a/docs/diagnostics/DoubleNegatives.md b/docs/diagnostics/DoubleNegatives.md new file mode 100644 index 00000000000..dfc19134c94 --- /dev/null +++ b/docs/diagnostics/DoubleNegatives.md @@ -0,0 +1,30 @@ +# Двойные отрицания (DoubleNegatives) + + +## Описание диагностики + +Использование двойных отрицаний усложняет понимание кода и может приводить к ошибкам, когда вместо истины разработчик "в уме" вычислил Ложь, или наоборот. +Двойные отрицания рекомендуется заменять на выражения условий, которые прямо выражают намерения автора. + +## Примеры + +### Неправильно + +```bsl +Если Не ТаблицаЗначений.Найти(ИскомоеЗначение, "Колонка") <> Неопределено Тогда + // Сделать действие +КонецЕсли; +``` + +### Правильно + +```bsl +Если ТаблицаЗначений.Найти(ИскомоеЗначение, "Колонка") = Неопределено Тогда + // Сделать действие +КонецЕсли; +``` + +## Источники + + +* Источник: [Remove double negative](https://www.refactoring.com/catalog/removeDoubleNegative.html) \ No newline at end of file diff --git a/docs/en/diagnostics/DoubleNegatives.md b/docs/en/diagnostics/DoubleNegatives.md new file mode 100644 index 00000000000..5a960bb659c --- /dev/null +++ b/docs/en/diagnostics/DoubleNegatives.md @@ -0,0 +1,28 @@ +# Double negatives (DoubleNegatives) + + +## Description + +Using double negatives complicates the understanding of the code and can lead to errors when instead of truth the developer "in his mind" calculated False, or vice versa. It is recommended to replace double negatives with conditions that directly express the author's intentions. + +## Examples + +### Wrong + +```bsl +If Not ValueTable.Find(ValueToSearch, "Column") <> Undefined Тогда + // Act +EndIf; +``` + +### Correct + +```bsl +If ValueTable.Find(ValueToSearch, "Column") = Undefined Тогда + // Act +EndIf; +``` + +## Sources + +* Источник: [Remove double negative](https://www.refactoring.com/catalog/removeDoubleNegative.html) \ No newline at end of file diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java new file mode 100644 index 00000000000..94952ad9608 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java @@ -0,0 +1,38 @@ +package com.github._1c_syntax.bsl.languageserver.diagnostics; + +import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticMetadata; +import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticSeverity; +import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticTag; +import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticType; +import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.ExpressionParseTreeRewriter; +import com.github._1c_syntax.bsl.parser.BSLParser; +import org.antlr.v4.runtime.tree.ParseTree; + +@DiagnosticMetadata( + type = DiagnosticType.CODE_SMELL, + severity = DiagnosticSeverity.MAJOR, + minutesToFix = 3, + tags = { + DiagnosticTag.BRAINOVERLOAD, + DiagnosticTag.BADPRACTICE + } +) +public class DoubleNegativesDiagnostic extends AbstractVisitorDiagnostic { + + private static final int MIN_EXPRESSION_SIZE = 3; + + @Override + public ParseTree visitExpression(BSLParser.ExpressionContext ctx) { + + if (sufficientSize(ctx)) + return ctx; + + var tree = ExpressionParseTreeRewriter.buildExpressionTree(ctx); + + return ctx; + } + + private static boolean sufficientSize(BSLParser.ExpressionContext ctx) { + return ctx.children.size() < MIN_EXPRESSION_SIZE; + } +} diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic_en.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic_en.properties new file mode 100644 index 00000000000..5349a4b9fcc --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic_en.properties @@ -0,0 +1,2 @@ +diagnosticMessage=Using double negatives complicates understandong of code +diagnosticName=Double negatives diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic_ru.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic_ru.properties new file mode 100644 index 00000000000..06fb1ed09ea --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic_ru.properties @@ -0,0 +1,2 @@ +diagnosticMessage=Использование двойных отрицаний усложняет понимание кода +diagnosticName=Двойные отрицания diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnosticTest.java new file mode 100644 index 00000000000..9a571e52415 --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnosticTest.java @@ -0,0 +1,25 @@ +package com.github._1c_syntax.bsl.languageserver.diagnostics; + +import org.eclipse.lsp4j.Diagnostic; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static com.github._1c_syntax.bsl.languageserver.util.Assertions.assertThat; + +class DoubleNegativesDiagnosticTest extends AbstractDiagnosticTest { + DoubleNegativesDiagnosticTest() { + super(DoubleNegativesDiagnostic.class); + } + + @Test + void test() { + + List diagnostics = getDiagnostics(); + + assertThat(diagnostics, true) + .hasRange(3, 6, 3, 74) + ; + + } +} diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ExpressionParseTreeRewriterTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ExpressionParseTreeRewriterTest.java index 01b2415ae2d..11c50bf5fa5 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ExpressionParseTreeRewriterTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ExpressionParseTreeRewriterTest.java @@ -317,6 +317,25 @@ void realLifeHardExpression() { assertThat(binary.getRight().cast().getOperator()).isEqualTo(BslOperator.EQUAL); } + @Test + void notOperatorPriority() { + var code = "А = Не Разыменование.Метод() = Неопределено"; + + var expressionTree = getExpressionTree(code); + + assertThat(expressionTree.getNodeType()).isEqualTo(ExpressionNodeType.UNARY_OP); + + var unary = expressionTree.cast(); + assertThat(unary.getOperator()).isEqualTo(BslOperator.NOT); + assertThat(unary.getOperand()).isInstanceOf(BinaryOperationNode.class); + + var binary = unary.getOperand().cast(); + assertThat(binary.getOperator()).isEqualTo(BslOperator.EQUAL); + assertThat(binary.getLeft().getNodeType()).isEqualTo(ExpressionNodeType.CALL); + assertThat(binary.getRight().getNodeType()).isEqualTo(ExpressionNodeType.LITERAL); + + } + BslExpression getExpressionTree(String code) { var expression = parse(code); return ExpressionParseTreeRewriter.buildExpressionTree(expression); diff --git a/src/test/resources/diagnostics/DoubleNegativesDiagnostic.bsl b/src/test/resources/diagnostics/DoubleNegativesDiagnostic.bsl new file mode 100644 index 00000000000..24799667ebd --- /dev/null +++ b/src/test/resources/diagnostics/DoubleNegativesDiagnostic.bsl @@ -0,0 +1,40 @@ +// Выражение в условии +Если Не ТаблицаЗначений.Найти(ИскомоеЗначение, "Колонка") <> Неопределено Тогда + // Сделать действие +КонецЕсли; + +// Отрицание с проверкой на литерал + +А = Не Отказ = Ложь; +А = Не (Отказ = Ложь); +А = Не Отказ <> Ложь; +А = Не (Отказ <> Ложь); +А = Не НекотороеЗначение() <> Неопределено; +А = Не Неопределено <> НекотороеЗначение(); +А = Не (А <> Неопределено); // срабатывает +А = Не А <> Неопределено И Б = 5; // срабатывает +А = Не (А <> Неопределено и Б = 5); // не срабатывает +А = Не (А <> Неопределено или Б = 5); // не срабатывает +А = Не (Б = 5 и А <> Неопределено); // не срабатывает + +Пока Не Таблица.Данные <> Неопределено Цикл +КонецЦикла; + +Б = Не (Не А = 1 или Б <> Неопределено); // срабатывает на "Не А = 1" +Б = Не (А <> 1 или Не Б <> Неопределено); // срабатывает на "Не Б <> Неопределено" +Б = Не (А <> 1 или Не Б = Неопределено); // не срабатывает на "Не Б <> Неопределено" т.к. сравнения вида Не Х = Неопределено популярны + +Если Не Т.Найти(Значение) = Неопределено Тогда + // не срабатывает, т.к. популярный код +КонецЕсли; + +// Отрицание с проверкой на неравенство нелитералу + +А = Не (Отказ <> НеЛитерал); // срабатывает +А = Не СложнаяФункция() <> НеЛитерал; // срабатывает + +Б = Не (А = 1 или Б <> НеЛитерал); // не срабатывает + +// Прямое двойное отрицание + +Б = Не (Не Значение); \ No newline at end of file From 1ed6cfefa6dbd25f884ccf64268d1a600547f616 Mon Sep 17 00:00:00 2001 From: Andrey Ovsyankin Date: Mon, 3 Jun 2024 20:11:49 +0300 Subject: [PATCH 02/13] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=BA=D1=80?= =?UTF-8?q?=D0=B0=D1=81=D0=BD=D1=8B=D1=85=20=D1=82=D0=B5=D1=81=D1=82=D0=BE?= =?UTF-8?q?=D0=B2=20"NOT"=20=D0=B4=D0=BB=D1=8F=20=D0=BF=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=BE=D0=B8=D1=82=D0=B5=D0=BB=D1=8F=20=D0=B2=D1=8B=D1=80?= =?UTF-8?q?=D0=B0=D0=B6=D0=B5=D0=BD=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ExpressionTreeBuildingVisitor.java | 4 ---- .../ExpressionParseTreeRewriterTest.java | 21 ++++++++++++++++++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java index 178e5d79883..53c8019f6ba 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java @@ -149,10 +149,6 @@ public ParseTree visitMember(BSLParser.MemberContext ctx) { dispatchChild.accept(this); } - if (unaryModifier != null) { - buildOperation(); - } - return ctx; } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ExpressionParseTreeRewriterTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ExpressionParseTreeRewriterTest.java index 11c50bf5fa5..028ede22c6c 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ExpressionParseTreeRewriterTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ExpressionParseTreeRewriterTest.java @@ -331,7 +331,26 @@ void notOperatorPriority() { var binary = unary.getOperand().cast(); assertThat(binary.getOperator()).isEqualTo(BslOperator.EQUAL); - assertThat(binary.getLeft().getNodeType()).isEqualTo(ExpressionNodeType.CALL); + assertThat(binary.getLeft().cast().getOperator()).isEqualTo(BslOperator.DEREFERENCE); + assertThat(binary.getRight().getNodeType()).isEqualTo(ExpressionNodeType.LITERAL); + + } + + @Test + void notOperatorPriority_with_parenthesis() { + var code = "А = Не (Разыменование.Метод() = Неопределено)"; + + var expressionTree = getExpressionTree(code); + + assertThat(expressionTree.getNodeType()).isEqualTo(ExpressionNodeType.UNARY_OP); + + var unary = expressionTree.cast(); + assertThat(unary.getOperator()).isEqualTo(BslOperator.NOT); + assertThat(unary.getOperand()).isInstanceOf(BinaryOperationNode.class); + + var binary = unary.getOperand().cast(); + assertThat(binary.getOperator()).isEqualTo(BslOperator.EQUAL); + assertThat(binary.getLeft().cast().getOperator()).isEqualTo(BslOperator.DEREFERENCE); assertThat(binary.getRight().getNodeType()).isEqualTo(ExpressionNodeType.LITERAL); } From 8daad34bab88d9044718ca4d2d835f7634996352 Mon Sep 17 00:00:00 2001 From: Andrey Ovsyankin Date: Tue, 4 Jun 2024 19:37:20 +0300 Subject: [PATCH 03/13] =?UTF-8?q?=D0=9D=D0=BE=D0=B2=D1=8B=D0=B9=20=D0=B2?= =?UTF-8?q?=D0=B8=D0=B4=20=D0=B4=D0=B8=D0=B0=D0=B3=D0=BD=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D0=B8=D0=BA=D0=B8=20-=20=D0=BF=D0=BE=20=D0=B4=D0=B5=D1=80?= =?UTF-8?q?=D0=B5=D0=B2=D1=83=20=D0=B2=D1=8B=D1=80=D0=B0=D0=B6=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B9=20=D0=B8=20=D0=B5=D1=89=D0=B5=20=D0=BA=D1=80=D0=B0?= =?UTF-8?q?=D1=81=D0=BD=D1=8B=D0=B5=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BF=D1=80=D0=B8=D0=BE=D1=80=D0=B8=D1=82=D0=B5?= =?UTF-8?q?=D1=82=20=D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AbstractExpressionTreeDiagnostic.java | 91 +++++++++++++++++++ .../DoubleNegativesDiagnostic.java | 57 +++++++++--- .../IdenticalExpressionsDiagnostic.java | 50 ++++++---- .../expressiontree/BinaryOperationNode.java | 8 +- .../utils/expressiontree/BslExpression.java | 8 +- .../expressiontree/BslOperationNode.java | 2 +- .../ExpressionParseTreeRewriter.java | 44 --------- .../ExpressionTreeBuildingVisitor.java | 22 ++++- .../expressiontree/ExpressionTreeVisitor.java | 53 +++++++++++ .../expressiontree/TerminalSymbolNode.java | 2 +- .../DoubleNegativesDiagnosticTest.java | 10 +- .../ExpressionParseTreeRewriterTest.java | 19 +++- .../utils/ExpressionTreeComparersTest.java | 4 +- 13 files changed, 282 insertions(+), 88 deletions(-) create mode 100644 src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractExpressionTreeDiagnostic.java delete mode 100644 src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionParseTreeRewriter.java create mode 100644 src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeVisitor.java diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractExpressionTreeDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractExpressionTreeDiagnostic.java new file mode 100644 index 00000000000..d6d13c383af --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractExpressionTreeDiagnostic.java @@ -0,0 +1,91 @@ +package com.github._1c_syntax.bsl.languageserver.diagnostics; + +import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; +import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticInfo; +import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.ExpressionTreeBuildingVisitor; +import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.ExpressionTreeVisitor; +import com.github._1c_syntax.bsl.parser.BSLParser; +import lombok.Getter; +import lombok.Setter; +import org.antlr.v4.runtime.tree.ParseTree; +import org.eclipse.lsp4j.Diagnostic; + +import java.util.List; + +/** + * Диагностика, анализирующая выражения BSL и предоставляющая для этого Expression Tree + */ +public abstract class AbstractExpressionTreeDiagnostic extends ExpressionTreeVisitor implements BSLDiagnostic { + @Getter + @Setter + protected DiagnosticInfo info; + protected final DiagnosticStorage diagnosticStorage = new DiagnosticStorage(this); + protected DocumentContext documentContext; + + @Override + public final List getDiagnostics(DocumentContext documentContext) { + this.documentContext = documentContext; + diagnosticStorage.clearDiagnostics(); + + var expressionTreeBuilder = new ExpressionTreeBuilder(); + expressionTreeBuilder.visitFile(documentContext.getAst()); + + return diagnosticStorage.getDiagnostics(); + } + + /** + * При входе в выражение вызывается данный метод. + * Переопределяя его можно оценить - имеет ли смысл строить дерево выражения, или данное выражение не подходит. + * Позволяет сократить время на построение дерева, если это не требуется для данного AST. + * @param ctx - выражение, которое в данный момент посещается. + * @return + * - если надо прекратить обход в глубину и построить Expression Tree на данном выражении - надо вернуть ACCEPT + * - если надо пройти дальше и посетить дочерние выражения, не затрагивая данное - надо вернуть VISIT_CHILDREN + * - если надо пропустить выражение, не ходить глубже и не строить Expression Tree - надо вернуть SKIP + */ + protected ExpressionVisitorDecision onExpressionEnter(BSLParser.ExpressionContext ctx) { + return ExpressionVisitorDecision.ACCEPT; + } + + /** + * Стратегия по построению дерева выражения на основе выражения AST + */ + protected enum ExpressionVisitorDecision { + + /** + * Не обрабатывать выражение + */ + SKIP, + + /** + * Обработать данное выражение (построить для него ExpressionTree) + */ + ACCEPT, + + /** + * Пропустить данное выражение и обойти вложенные в него выражения + */ + VISIT_CHILDREN; + } + + private class ExpressionTreeBuilder extends ExpressionTreeBuildingVisitor { + @Override + public ParseTree visitExpression(BSLParser.ExpressionContext ctx) { + + var result = onExpressionEnter(ctx); + return switch (result) { + case SKIP -> ctx; + case ACCEPT -> { + super.visitExpression(ctx); + var expressionTree = getExpressionTree(); + if (expressionTree != null) // нашлись выражения в предложенном файле + visitTopLevelExpression(expressionTree); + + yield ctx; + } + case VISIT_CHILDREN -> super.visitChildren(ctx); + }; + } + } + +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java index 94952ad9608..8a7d27e6f63 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java @@ -4,9 +4,13 @@ import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticSeverity; import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticTag; import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticType; -import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.ExpressionParseTreeRewriter; +import com.github._1c_syntax.bsl.languageserver.utils.Trees; +import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.BinaryOperationNode; +import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.BslExpression; +import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.BslOperator; +import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.ExpressionNodeType; +import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.UnaryOperationNode; import com.github._1c_syntax.bsl.parser.BSLParser; -import org.antlr.v4.runtime.tree.ParseTree; @DiagnosticMetadata( type = DiagnosticType.CODE_SMELL, @@ -17,22 +21,53 @@ DiagnosticTag.BADPRACTICE } ) -public class DoubleNegativesDiagnostic extends AbstractVisitorDiagnostic { +public class DoubleNegativesDiagnostic extends AbstractExpressionTreeDiagnostic { - private static final int MIN_EXPRESSION_SIZE = 3; + @Override + protected ExpressionVisitorDecision onExpressionEnter(BSLParser.ExpressionContext ctx) { + return super.onExpressionEnter(ctx); + } @Override - public ParseTree visitExpression(BSLParser.ExpressionContext ctx) { + protected void visitBinaryOperation(BinaryOperationNode node) { + + if (node.getOperator() != BslOperator.EQUAL && node.getOperator() != BslOperator.NOT_EQUAL) { + super.visitBinaryOperation(node); + return; + } + + var parent = node.getParent(); + + if (parent == null || !isNegationOperator(parent)) { + super.visitBinaryOperation(node); + return; + } - if (sufficientSize(ctx)) - return ctx; + if (node.getOperator() == BslOperator.NOT_EQUAL) { + addDiagnostic(node); + } else if (isBooleanLiteral(node.getLeft()) || isBooleanLiteral(node.getRight())) { + addDiagnostic(node); + } - var tree = ExpressionParseTreeRewriter.buildExpressionTree(ctx); + super.visitBinaryOperation(node); + } + + private boolean isBooleanLiteral(BslExpression node) { + if (node.getNodeType() != ExpressionNodeType.LITERAL) + return false; - return ctx; + var constant = (BSLParser.ConstValueContext) node.getRepresentingAst(); + return constant.TRUE() != null || constant.FALSE() != null; } - private static boolean sufficientSize(BSLParser.ExpressionContext ctx) { - return ctx.children.size() < MIN_EXPRESSION_SIZE; + private static boolean isNegationOperator(BslExpression parent) { + return parent.getNodeType() == ExpressionNodeType.UNARY_OP && parent.cast().getOperator() == BslOperator.NOT; + } + + private void addDiagnostic(BinaryOperationNode node) { + var startToken = Trees.getTokens(node.getParent().getRepresentingAst()).stream().findFirst().orElseThrow(); + var endToken = Trees.getTokens(node.getRight().getRepresentingAst()).stream().reduce((one, two) -> two).orElseThrow(); + + diagnosticStorage.addDiagnostic(startToken, endToken); } } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IdenticalExpressionsDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IdenticalExpressionsDiagnostic.java index 5b81dee5aa8..46d3bd114de 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IdenticalExpressionsDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IdenticalExpressionsDiagnostic.java @@ -34,7 +34,7 @@ import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.BslExpression; import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.BslOperator; import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.ExpressionNodeType; -import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.ExpressionParseTreeRewriter; +import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.ExpressionTreeBuildingVisitor; import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.NodeEqualityComparer; import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.TernaryOperatorNode; import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.TransitiveOperationsIgnoringComparer; @@ -62,7 +62,7 @@ } ) @RequiredArgsConstructor -public class IdenticalExpressionsDiagnostic extends AbstractVisitorDiagnostic { +public class IdenticalExpressionsDiagnostic extends AbstractExpressionTreeDiagnostic { private static final int MIN_EXPRESSION_SIZE = 3; private static final String POPULAR_DIVISORS_DEFAULT_VALUE = "60, 1024"; @@ -73,7 +73,10 @@ public class IdenticalExpressionsDiagnostic extends AbstractVisitorDiagnostic { ) private Set popularDivisors = parseCommaSeparatedSet(POPULAR_DIVISORS_DEFAULT_VALUE); private final FormatProvider formatProvider; - + + private final List binaryOperations = new ArrayList<>(); + private BSLParser.ExpressionContext expressionContext; + private static Set parseCommaSeparatedSet(String values) { if (values.trim().isEmpty()) { return Collections.emptySet(); @@ -95,28 +98,41 @@ public void configure(Map configuration) { } @Override - public ParseTree visitExpression(BSLParser.ExpressionContext ctx) { - - if (sufficientSize(ctx)) { - return ctx; - } - - var tree = ExpressionParseTreeRewriter.buildExpressionTree(ctx); + protected ExpressionVisitorDecision onExpressionEnter(BSLParser.ExpressionContext ctx) { + expressionContext = ctx; + return sufficientSize(ctx)? ExpressionVisitorDecision.SKIP : ExpressionVisitorDecision.ACCEPT; + } - var binariesList = flattenBinaryOperations(tree); - if (binariesList.isEmpty()) { - return ctx; - } + @Override + protected void visitTopLevelExpression(BslExpression node) { + binaryOperations.clear(); + super.visitTopLevelExpression(node); var comparer = new TransitiveOperationsIgnoringComparer(); comparer.logicalOperationsAsTransitive(true); - binariesList + binaryOperations .stream() .filter(x -> checkEquality(comparer, x)) - .forEach(x -> diagnosticStorage.addDiagnostic(ctx, + .forEach(x -> diagnosticStorage.addDiagnostic(expressionContext, info.getMessage(x.getRepresentingAst().getText(), getOperandText(x)))); + } + + @Override + protected void visitBinaryOperation(BinaryOperationNode node) { + var operator = node.getOperator(); + + // разыменования отбросим, хотя comparer их и не зачтет, но для производительности + // лучше выкинем их сразу + if (operator == BslOperator.DEREFERENCE || operator == BslOperator.INDEX_ACCESS) { + return; + } + + // одинаковые умножения и сложения - не считаем, см. тесты + if (operator != BslOperator.ADD && operator != BslOperator.MULTIPLY) { + binaryOperations.add(node); + } - return ctx; + super.visitBinaryOperation(node); } private boolean checkEquality(NodeEqualityComparer comparer, BinaryOperationNode node) { diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/BinaryOperationNode.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/BinaryOperationNode.java index acde5b6f19b..31549e9b98f 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/BinaryOperationNode.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/BinaryOperationNode.java @@ -22,16 +22,16 @@ package com.github._1c_syntax.bsl.languageserver.utils.expressiontree; import lombok.EqualsAndHashCode; +import lombok.Getter; import lombok.ToString; -import lombok.Value; import org.antlr.v4.runtime.tree.ParseTree; -@Value +@Getter @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BinaryOperationNode extends BslOperationNode { - BslExpression left; - BslExpression right; + private final BslExpression left; + private final BslExpression right; private BinaryOperationNode(BslOperator operator, BslExpression left, BslExpression right, ParseTree actualSourceCode) { super(ExpressionNodeType.BINARY_OP, operator, actualSourceCode); diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/BslExpression.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/BslExpression.java index 76bc9dc1da0..72a98f95e9e 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/BslExpression.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/BslExpression.java @@ -24,18 +24,22 @@ import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Data; -import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.ToString; import org.antlr.v4.runtime.tree.ParseTree; @Data @RequiredArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor(access = AccessLevel.PROTECTED) -@NoArgsConstructor(access = AccessLevel.PRIVATE, force = true) public abstract class BslExpression { private final ExpressionNodeType nodeType; private ParseTree representingAst; + @ToString.Exclude + @Setter(AccessLevel.PACKAGE) + private BslExpression parent; + /** * Синтаксический-помощник для более удобных downcast-ов * @param тип, к которому надо привести данный узел diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/BslOperationNode.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/BslOperationNode.java index 8afabd15956..fa065e25bae 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/BslOperationNode.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/BslOperationNode.java @@ -36,7 +36,7 @@ public abstract class BslOperationNode extends BslExpression { BslOperator operator; protected BslOperationNode(ExpressionNodeType type, BslOperator operator, ParseTree sourceCodeOperator) { - super(type, sourceCodeOperator); + super(type, sourceCodeOperator, null); this.operator = operator; } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionParseTreeRewriter.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionParseTreeRewriter.java deleted file mode 100644 index c580191eb8d..00000000000 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionParseTreeRewriter.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is a part of BSL Language Server. - * - * Copyright (c) 2018-2024 - * Alexey Sosnoviy , Nikita Fedkin and contributors - * - * SPDX-License-Identifier: LGPL-3.0-or-later - * - * BSL Language Server is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * BSL Language Server is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with BSL Language Server. - */ -package com.github._1c_syntax.bsl.languageserver.utils.expressiontree; - -import com.github._1c_syntax.bsl.parser.BSLParser; - - -/** - * Преобразователь выражения в дерево вычисления. - */ -public final class ExpressionParseTreeRewriter { - - private ExpressionParseTreeRewriter(){ - } - - /** - * @return результирующее выражение в виде дерева вычисления операций - */ - public static BslExpression buildExpressionTree(BSLParser.ExpressionContext expression) { - var visitor = new ExpressionTreeBuildingVisitor(); - visitor.visitExpression(expression); - return visitor.getExpressionTree(); - } - -} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java index 53c8019f6ba..8be9b8973ce 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java @@ -37,9 +37,9 @@ /** - * внутренний, неэкспортируемый класс. + * Посетитель AST, который находит выражения и преобразует их в Expression Tree */ -class ExpressionTreeBuildingVisitor extends BSLParserBaseVisitor { +public class ExpressionTreeBuildingVisitor extends BSLParserBaseVisitor { @Value private static class OperatorInCode { @@ -57,6 +57,17 @@ public int getPriority() { private BslExpression resultExpression; private int recursionLevel = -1; + /** + * Хелпер построения дерева выражения на основе готового AST выражения + * @param ctx AST выражения + * @return дерево вычисления выражения + */ + public static BslExpression buildExpressionTree(BSLParser.ExpressionContext ctx) { + var instance = new ExpressionTreeBuildingVisitor(); + instance.visitExpression(ctx); + return instance.getExpressionTree(); + } + /** * @return результирующее выражение в виде дерева вычисления операций */ @@ -358,7 +369,7 @@ public ParseTree visitTernaryOperator(BSLParser.TernaryOperatorContext ctx) { } private static BslExpression makeSubexpression(BSLParser.ExpressionContext ctx) { - return ExpressionParseTreeRewriter.buildExpressionTree(ctx); + return buildExpressionTree(ctx); } private static void addCallArguments(AbstractCallNode callNode, List args) { @@ -383,11 +394,16 @@ private void buildOperation() { var operand = operands.pop(); var operation = UnaryOperationNode.create(operator.getOperator(), operand, operator.getActualSourceCode()); + operand.setParent(operation); operands.push(operation); } else { var right = operands.pop(); var left = operands.pop(); var binaryOp = BinaryOperationNode.create(operator.getOperator(), left, right, operator.getActualSourceCode()); + + left.setParent(binaryOp); + right.setParent(binaryOp); + operands.push(binaryOp); } } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeVisitor.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeVisitor.java new file mode 100644 index 00000000000..868e29b163c --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeVisitor.java @@ -0,0 +1,53 @@ +package com.github._1c_syntax.bsl.languageserver.utils.expressiontree; + +/** + * Обходчик дерева выражений + */ +public class ExpressionTreeVisitor { + + private void visit(BslExpression node) { + switch (node.getNodeType()) { + case CALL: + visitAbstractCall((AbstractCallNode) node); + break; + case UNARY_OP: + visitUnaryOperation((UnaryOperationNode) node); + break; + case TERNARY_OP: + var ternary = (TernaryOperatorNode) node; + visitTernaryOperator(ternary); + break; + case BINARY_OP: + visitBinaryOperation((BinaryOperationNode)node); + break; + + default: + break; // для спокойствия сонара + } + } + + protected void visitTopLevelExpression(BslExpression node) { + visit(node); + } + + protected void visitAbstractCall(AbstractCallNode node) { + for (var expr : node.arguments()) { + visit(expr); + } + } + + protected void visitUnaryOperation(UnaryOperationNode node) { + visit(node.getOperand()); + } + + protected void visitBinaryOperation(BinaryOperationNode node) { + visit(node.getLeft()); + visit(node.getRight()); + } + + protected void visitTernaryOperator(TernaryOperatorNode node) { + visit(node.getCondition()); + visit(node.getTruePart()); + visit(node.getFalsePart()); + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/TerminalSymbolNode.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/TerminalSymbolNode.java index dae120ca7b3..e32ae01ee08 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/TerminalSymbolNode.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/TerminalSymbolNode.java @@ -30,7 +30,7 @@ */ public class TerminalSymbolNode extends BslExpression { private TerminalSymbolNode(ExpressionNodeType type, ParseTree representingAst) { - super(type, representingAst); + super(type, representingAst, null); } /** diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnosticTest.java index 9a571e52415..387f4d289c8 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnosticTest.java @@ -18,7 +18,15 @@ void test() { List diagnostics = getDiagnostics(); assertThat(diagnostics, true) - .hasRange(3, 6, 3, 74) + .hasRange(1, 5, 1, 73) + .hasRange(7, 4, 7, 19) + .hasRange(8, 4, 8, 20) + .hasRange(9, 4, 9, 20) + .hasRange(10, 4, 10, 21) + .hasRange(11, 4, 11, 42) + .hasRange(12, 4, 12, 42) + .hasRange(13, 4, 13, 25) + .hasRange(14, 4, 14, 25) ; } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ExpressionParseTreeRewriterTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ExpressionParseTreeRewriterTest.java index 028ede22c6c..e9b430abad2 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ExpressionParseTreeRewriterTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ExpressionParseTreeRewriterTest.java @@ -28,7 +28,7 @@ import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.BslOperator; import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.ConstructorCallNode; import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.ExpressionNodeType; -import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.ExpressionParseTreeRewriter; +import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.ExpressionTreeBuildingVisitor; import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.MethodCallNode; import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.SkippedCallArgumentNode; import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.UnaryOperationNode; @@ -146,6 +146,21 @@ void booleanPriority() { } + @Test + void booleanNotPriority() { + var code = "Рез = Не Б <> Неопределено И Ложь"; + var expressionTree = getExpressionTree(code); + var binary = (BinaryOperationNode) expressionTree; + + assertThat(binary.getOperator()).isEqualTo(BslOperator.AND); + + var negation = binary.getLeft().cast(); + assertThat(negation.getNodeType()).isEqualTo(ExpressionNodeType.UNARY_OP); + assertThat(negation.getOperator()).isEqualTo(BslOperator.NOT); + + assertThat((binary.getLeft()).getNodeType()).isEqualTo(ExpressionNodeType.LITERAL); + } + @Test void dereferenceOfProperty() { var code = "Рез = Структура.Свойство"; @@ -357,6 +372,6 @@ void notOperatorPriority_with_parenthesis() { BslExpression getExpressionTree(String code) { var expression = parse(code); - return ExpressionParseTreeRewriter.buildExpressionTree(expression); + return ExpressionTreeBuildingVisitor.buildExpressionTree(expression); } } \ No newline at end of file diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ExpressionTreeComparersTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ExpressionTreeComparersTest.java index 0a654d5fdb9..375ee3cb2f2 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ExpressionTreeComparersTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ExpressionTreeComparersTest.java @@ -26,7 +26,7 @@ import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.BslExpression; import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.BslOperator; import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.DefaultNodeEqualityComparer; -import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.ExpressionParseTreeRewriter; +import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.ExpressionTreeBuildingVisitor; import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.TransitiveOperationsIgnoringComparer; import com.github._1c_syntax.bsl.parser.BSLParser; import org.junit.jupiter.api.Test; @@ -72,7 +72,7 @@ BSLParser.ExpressionContext parse(String code) { BslExpression getExpressionTree(String code) { var expression = parse(code); - return ExpressionParseTreeRewriter.buildExpressionTree(expression); + return ExpressionTreeBuildingVisitor.buildExpressionTree(expression); } } From 1842f447a06f40638ebd02a7d40b8bf947481a73 Mon Sep 17 00:00:00 2001 From: Andrey Ovsyankin Date: Thu, 6 Jun 2024 15:24:03 +0300 Subject: [PATCH 04/13] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=BE=20=D0=BF=D0=BE=D1=81=D1=82=D1=80=D0=BE?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B4=D0=B5=D1=80=D0=B5=D0=B2=D0=B0?= =?UTF-8?q?=20=D0=B8=20=D1=81=D0=B4=D0=B5=D0=BB=D0=B0=D0=BD=20=D0=B7=D0=B5?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D1=8B=D0=B9=20=D1=82=D0=B5=D1=81=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DoubleNegativesDiagnostic.java | 22 +++++++++++++++++++ .../ExpressionTreeBuildingVisitor.java | 11 ++++++++-- .../DoubleNegativesDiagnosticTest.java | 7 +++++- .../ExpressionParseTreeRewriterTest.java | 2 +- .../diagnostics/DoubleNegativesDiagnostic.bsl | 5 +++-- 5 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java index 8a7d27e6f63..52ed915f451 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java @@ -52,6 +52,21 @@ protected void visitBinaryOperation(BinaryOperationNode node) { super.visitBinaryOperation(node); } + @Override + protected void visitUnaryOperation(UnaryOperationNode node) { + if (node.getOperator() == BslOperator.NOT && + node.getParent() != null && + node.getParent().getNodeType() == ExpressionNodeType.UNARY_OP) { + + var unaryParent = node.getParent().cast(); + if (unaryParent.getOperator() == BslOperator.NOT) { + addDiagnostic(node); + } + } + + super.visitUnaryOperation(node); + } + private boolean isBooleanLiteral(BslExpression node) { if (node.getNodeType() != ExpressionNodeType.LITERAL) return false; @@ -70,4 +85,11 @@ private void addDiagnostic(BinaryOperationNode node) { diagnosticStorage.addDiagnostic(startToken, endToken); } + + private void addDiagnostic(UnaryOperationNode node) { + var startToken = Trees.getTokens(node.getParent().getRepresentingAst()).stream().findFirst().orElseThrow(); + var endToken = Trees.getTokens(node.getOperand().getRepresentingAst()).stream().reduce((one, two) -> two).orElseThrow(); + + diagnosticStorage.addDiagnostic(startToken, endToken); + } } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java index 8be9b8973ce..250ae335c63 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java @@ -192,14 +192,21 @@ private void processOperation(OperatorInCode operator) { return; } - var lastSeenOperator = operatorsInFly.peek(); - if (lastSeenOperator.getPriority() > operator.getPriority()) { + while (hasHigherPriorityOperatorsInFly(operator)) { buildOperation(); } operatorsInFly.push(operator); } + private boolean hasHigherPriorityOperatorsInFly(OperatorInCode operator) { + var lastSeenOperator = operatorsInFly.peek(); + if (lastSeenOperator == null) + return false; + + return lastSeenOperator.getPriority() > operator.getPriority(); + } + private static BslOperator getOperator(BSLParser.OperationContext ctx) { if (ctx.PLUS() != null) { return BslOperator.ADD; diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnosticTest.java index 387f4d289c8..c6c5236c83e 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnosticTest.java @@ -26,7 +26,12 @@ void test() { .hasRange(11, 4, 11, 42) .hasRange(12, 4, 12, 42) .hasRange(13, 4, 13, 25) - .hasRange(14, 4, 14, 25) + .hasRange(14, 4, 14, 24) + .hasRange(19, 5, 19, 38) + .hasRange(23, 19, 23, 39) + .hasRange(32, 4, 32, 26) + .hasRange(33, 4, 33, 36) + .hasRange(39, 4, 39, 19) ; } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ExpressionParseTreeRewriterTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ExpressionParseTreeRewriterTest.java index e9b430abad2..c97ae2dd585 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ExpressionParseTreeRewriterTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ExpressionParseTreeRewriterTest.java @@ -158,7 +158,7 @@ void booleanNotPriority() { assertThat(negation.getNodeType()).isEqualTo(ExpressionNodeType.UNARY_OP); assertThat(negation.getOperator()).isEqualTo(BslOperator.NOT); - assertThat((binary.getLeft()).getNodeType()).isEqualTo(ExpressionNodeType.LITERAL); + assertThat((binary.getRight()).getNodeType()).isEqualTo(ExpressionNodeType.LITERAL); } @Test diff --git a/src/test/resources/diagnostics/DoubleNegativesDiagnostic.bsl b/src/test/resources/diagnostics/DoubleNegativesDiagnostic.bsl index 24799667ebd..f0493b0ec06 100644 --- a/src/test/resources/diagnostics/DoubleNegativesDiagnostic.bsl +++ b/src/test/resources/diagnostics/DoubleNegativesDiagnostic.bsl @@ -20,7 +20,7 @@ Пока Не Таблица.Данные <> Неопределено Цикл КонецЦикла; -Б = Не (Не А = 1 или Б <> Неопределено); // срабатывает на "Не А = 1" +Б = Не (Не А = 1 или Б <> Неопределено); // не срабатывает на "Не А = 1" Б = Не (А <> 1 или Не Б <> Неопределено); // срабатывает на "Не Б <> Неопределено" Б = Не (А <> 1 или Не Б = Неопределено); // не срабатывает на "Не Б <> Неопределено" т.к. сравнения вида Не Х = Неопределено популярны @@ -37,4 +37,5 @@ // Прямое двойное отрицание -Б = Не (Не Значение); \ No newline at end of file +Б = Не (Не Значение); +Б = Не (Не Значение И ДругоеЗначение); // не срабатывает \ No newline at end of file From 0e597d58ca12b81e88293a0e477850da0af5d8e4 Mon Sep 17 00:00:00 2001 From: Andrey Ovsyankin Date: Thu, 6 Jun 2024 15:35:32 +0300 Subject: [PATCH 05/13] =?UTF-8?q?=D0=9E=D0=BF=D0=B5=D1=87=D0=B0=D1=82?= =?UTF-8?q?=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../diagnostics/DoubleNegativesDiagnostic_en.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic_en.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic_en.properties index 5349a4b9fcc..b40f038bd92 100644 --- a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic_en.properties +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic_en.properties @@ -1,2 +1,2 @@ -diagnosticMessage=Using double negatives complicates understandong of code +diagnosticMessage=Using double negatives complicates understanding of code diagnosticName=Double negatives From 7ad97669963ef0d689dedae7f972fdbf3ee724fd Mon Sep 17 00:00:00 2001 From: Andrey Ovsyankin Date: Thu, 6 Jun 2024 15:39:07 +0300 Subject: [PATCH 06/13] gradlew precommit --- docs/diagnostics/DoubleNegatives.md | 2 +- docs/en/diagnostics/DoubleNegatives.md | 2 +- .../AbstractExpressionTreeDiagnostic.java | 21 +++++++++++++++++++ .../DoubleNegativesDiagnostic.java | 21 +++++++++++++++++++ .../expressiontree/ExpressionTreeVisitor.java | 21 +++++++++++++++++++ .../configuration/parameters-schema.json | 10 +++++++++ .../languageserver/configuration/schema.json | 3 +++ .../DoubleNegativesDiagnosticTest.java | 21 +++++++++++++++++++ 8 files changed, 99 insertions(+), 2 deletions(-) diff --git a/docs/diagnostics/DoubleNegatives.md b/docs/diagnostics/DoubleNegatives.md index dfc19134c94..fda21235024 100644 --- a/docs/diagnostics/DoubleNegatives.md +++ b/docs/diagnostics/DoubleNegatives.md @@ -27,4 +27,4 @@ ## Источники -* Источник: [Remove double negative](https://www.refactoring.com/catalog/removeDoubleNegative.html) \ No newline at end of file +* Источник: [Remove double negative](https://www.refactoring.com/catalog/removeDoubleNegative.html) diff --git a/docs/en/diagnostics/DoubleNegatives.md b/docs/en/diagnostics/DoubleNegatives.md index 5a960bb659c..3a6b3059d40 100644 --- a/docs/en/diagnostics/DoubleNegatives.md +++ b/docs/en/diagnostics/DoubleNegatives.md @@ -25,4 +25,4 @@ EndIf; ## Sources -* Источник: [Remove double negative](https://www.refactoring.com/catalog/removeDoubleNegative.html) \ No newline at end of file +* Источник: [Remove double negative](https://www.refactoring.com/catalog/removeDoubleNegative.html) diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractExpressionTreeDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractExpressionTreeDiagnostic.java index d6d13c383af..6481916867f 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractExpressionTreeDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractExpressionTreeDiagnostic.java @@ -1,3 +1,24 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright (c) 2018-2024 + * Alexey Sosnoviy , Nikita Fedkin and contributors + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * BSL Language Server is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * BSL Language Server is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with BSL Language Server. + */ package com.github._1c_syntax.bsl.languageserver.diagnostics; import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java index 52ed915f451..1c416d31ce5 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java @@ -1,3 +1,24 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright (c) 2018-2024 + * Alexey Sosnoviy , Nikita Fedkin and contributors + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * BSL Language Server is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * BSL Language Server is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with BSL Language Server. + */ package com.github._1c_syntax.bsl.languageserver.diagnostics; import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticMetadata; diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeVisitor.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeVisitor.java index 868e29b163c..951ac2b76d9 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeVisitor.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeVisitor.java @@ -1,3 +1,24 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright (c) 2018-2024 + * Alexey Sosnoviy , Nikita Fedkin and contributors + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * BSL Language Server is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * BSL Language Server is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with BSL Language Server. + */ package com.github._1c_syntax.bsl.languageserver.utils.expressiontree; /** diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/configuration/parameters-schema.json b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/configuration/parameters-schema.json index 749df4a1160..917a458b09c 100644 --- a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/configuration/parameters-schema.json +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/configuration/parameters-schema.json @@ -526,6 +526,16 @@ "title": "Disable safe mode", "$id": "#/definitions/DisableSafeMode" }, + "DoubleNegatives": { + "description": "Double negatives", + "default": true, + "type": [ + "boolean", + "object" + ], + "title": "Double negatives", + "$id": "#/definitions/DoubleNegatives" + }, "DuplicateRegion": { "description": "Duplicate regions", "default": true, diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/configuration/schema.json b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/configuration/schema.json index 96fdadfbdff..e22c02dd4b2 100644 --- a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/configuration/schema.json +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/configuration/schema.json @@ -149,6 +149,9 @@ "DisableSafeMode": { "$ref": "parameters-schema.json#/definitions/DisableSafeMode" }, + "DoubleNegatives": { + "$ref": "parameters-schema.json#/definitions/DoubleNegatives" + }, "DuplicateRegion": { "$ref": "parameters-schema.json#/definitions/DuplicateRegion" }, diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnosticTest.java index c6c5236c83e..1880469c2c1 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnosticTest.java @@ -1,3 +1,24 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright (c) 2018-2024 + * Alexey Sosnoviy , Nikita Fedkin and contributors + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * BSL Language Server is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * BSL Language Server is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with BSL Language Server. + */ package com.github._1c_syntax.bsl.languageserver.diagnostics; import org.eclipse.lsp4j.Diagnostic; From 656b264c02ef6aafa5d80d9e07b77a700faf2c03 Mon Sep 17 00:00:00 2001 From: Andrey Ovsyankin Date: Thu, 13 Jun 2024 12:41:59 +0300 Subject: [PATCH 07/13] =?UTF-8?q?=D0=97=D0=B0=D0=BC=D0=B5=D1=87=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D1=81=D0=BE=D0=BD=D0=B0=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AbstractExpressionTreeDiagnostic.java | 26 +++++----- .../DoubleNegativesDiagnostic.java | 43 +++++++++------- .../IdenticalExpressionsDiagnostic.java | 50 ------------------- .../ExpressionTreeBuildingVisitor.java | 4 +- 4 files changed, 43 insertions(+), 80 deletions(-) diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractExpressionTreeDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractExpressionTreeDiagnostic.java index 6481916867f..d3e23cf5107 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractExpressionTreeDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractExpressionTreeDiagnostic.java @@ -58,11 +58,11 @@ public final List getDiagnostics(DocumentContext documentContext) { * При входе в выражение вызывается данный метод. * Переопределяя его можно оценить - имеет ли смысл строить дерево выражения, или данное выражение не подходит. * Позволяет сократить время на построение дерева, если это не требуется для данного AST. + * * @param ctx - выражение, которое в данный момент посещается. - * @return - * - если надо прекратить обход в глубину и построить Expression Tree на данном выражении - надо вернуть ACCEPT - * - если надо пройти дальше и посетить дочерние выражения, не затрагивая данное - надо вернуть VISIT_CHILDREN - * - если надо пропустить выражение, не ходить глубже и не строить Expression Tree - надо вернуть SKIP + * @return - если надо прекратить обход в глубину и построить Expression Tree на данном выражении - надо вернуть ACCEPT + * - если надо пройти дальше и посетить дочерние выражения, не затрагивая данное - надо вернуть VISIT_CHILDREN + * - если надо пропустить выражение, не ходить глубже и не строить Expression Tree - надо вернуть SKIP */ protected ExpressionVisitorDecision onExpressionEnter(BSLParser.ExpressionContext ctx) { return ExpressionVisitorDecision.ACCEPT; @@ -96,17 +96,19 @@ public ParseTree visitExpression(BSLParser.ExpressionContext ctx) { var result = onExpressionEnter(ctx); return switch (result) { case SKIP -> ctx; - case ACCEPT -> { - super.visitExpression(ctx); - var expressionTree = getExpressionTree(); - if (expressionTree != null) // нашлись выражения в предложенном файле - visitTopLevelExpression(expressionTree); - - yield ctx; - } + case ACCEPT -> processExpression(ctx); case VISIT_CHILDREN -> super.visitChildren(ctx); }; } + + private BSLParser.ExpressionContext processExpression(BSLParser.ExpressionContext ctx) { + super.visitExpression(ctx); + var expressionTree = getExpressionTree(); + if (expressionTree != null) // нашлись выражения в предложенном файле + visitTopLevelExpression(expressionTree); + + return ctx; + } } } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java index 1c416d31ce5..1a3cd45fcd1 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java @@ -44,11 +44,6 @@ ) public class DoubleNegativesDiagnostic extends AbstractExpressionTreeDiagnostic { - @Override - protected ExpressionVisitorDecision onExpressionEnter(BSLParser.ExpressionContext ctx) { - return super.onExpressionEnter(ctx); - } - @Override protected void visitBinaryOperation(BinaryOperationNode node) { @@ -64,9 +59,7 @@ protected void visitBinaryOperation(BinaryOperationNode node) { return; } - if (node.getOperator() == BslOperator.NOT_EQUAL) { - addDiagnostic(node); - } else if (isBooleanLiteral(node.getLeft()) || isBooleanLiteral(node.getRight())) { + if (node.getOperator() == BslOperator.NOT_EQUAL || isBooleanLiteral(node.getLeft()) || isBooleanLiteral(node.getRight())) { addDiagnostic(node); } @@ -76,8 +69,8 @@ protected void visitBinaryOperation(BinaryOperationNode node) { @Override protected void visitUnaryOperation(UnaryOperationNode node) { if (node.getOperator() == BslOperator.NOT && - node.getParent() != null && - node.getParent().getNodeType() == ExpressionNodeType.UNARY_OP) { + node.getParent() != null && + node.getParent().getNodeType() == ExpressionNodeType.UNARY_OP) { var unaryParent = node.getParent().cast(); if (unaryParent.getOperator() == BslOperator.NOT) { @@ -88,28 +81,44 @@ protected void visitUnaryOperation(UnaryOperationNode node) { super.visitUnaryOperation(node); } - private boolean isBooleanLiteral(BslExpression node) { - if (node.getNodeType() != ExpressionNodeType.LITERAL) + private static boolean isBooleanLiteral(BslExpression node) { + if (node.getNodeType() != ExpressionNodeType.LITERAL) { return false; + } var constant = (BSLParser.ConstValueContext) node.getRepresentingAst(); return constant.TRUE() != null || constant.FALSE() != null; } private static boolean isNegationOperator(BslExpression parent) { - return parent.getNodeType() == ExpressionNodeType.UNARY_OP && parent.cast().getOperator() == BslOperator.NOT; + return parent.getNodeType() == ExpressionNodeType.UNARY_OP + && parent.cast().getOperator() == BslOperator.NOT; } private void addDiagnostic(BinaryOperationNode node) { - var startToken = Trees.getTokens(node.getParent().getRepresentingAst()).stream().findFirst().orElseThrow(); - var endToken = Trees.getTokens(node.getRight().getRepresentingAst()).stream().reduce((one, two) -> two).orElseThrow(); + var startToken = Trees.getTokens(node.getParent().getRepresentingAst()) + .stream() + .findFirst() + .orElseThrow(); + + var endToken = Trees.getTokens(node.getRight().getRepresentingAst()) + .stream() + .reduce((one, two) -> two) + .orElseThrow(); diagnosticStorage.addDiagnostic(startToken, endToken); } private void addDiagnostic(UnaryOperationNode node) { - var startToken = Trees.getTokens(node.getParent().getRepresentingAst()).stream().findFirst().orElseThrow(); - var endToken = Trees.getTokens(node.getOperand().getRepresentingAst()).stream().reduce((one, two) -> two).orElseThrow(); + var startToken = Trees.getTokens(node.getParent().getRepresentingAst()) + .stream() + .findFirst() + .orElseThrow(); + + var endToken = Trees.getTokens(node.getOperand().getRepresentingAst()) + .stream() + .reduce((one, two) -> two) + .orElseThrow(); diagnosticStorage.addDiagnostic(startToken, endToken); } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IdenticalExpressionsDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IdenticalExpressionsDiagnostic.java index 46d3bd114de..6a9a19338f2 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IdenticalExpressionsDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IdenticalExpressionsDiagnostic.java @@ -29,20 +29,16 @@ import com.github._1c_syntax.bsl.languageserver.providers.FormatProvider; import com.github._1c_syntax.bsl.languageserver.utils.Ranges; import com.github._1c_syntax.bsl.languageserver.utils.Trees; -import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.AbstractCallNode; import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.BinaryOperationNode; import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.BslExpression; import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.BslOperator; import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.ExpressionNodeType; -import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.ExpressionTreeBuildingVisitor; import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.NodeEqualityComparer; -import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.TernaryOperatorNode; import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.TransitiveOperationsIgnoringComparer; import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.UnaryOperationNode; import com.github._1c_syntax.bsl.parser.BSLParser; import lombok.RequiredArgsConstructor; import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.tree.ParseTree; import org.eclipse.lsp4j.FormattingOptions; import java.util.ArrayList; @@ -228,52 +224,6 @@ private static void fillTokens(BslExpression node, List collection) { } } - private static List flattenBinaryOperations(BslExpression tree) { - var list = new ArrayList(); - gatherBinaryOperations(list, tree); - return list; - } - - private static void gatherBinaryOperations(List list, BslExpression tree) { - switch (tree.getNodeType()) { - case CALL: - for (var expr : tree.cast().arguments()) { - gatherBinaryOperations(list, expr); - } - break; - case UNARY_OP: - gatherBinaryOperations(list, tree.cast().getOperand()); - break; - case TERNARY_OP: - var ternary = (TernaryOperatorNode) tree; - gatherBinaryOperations(list, ternary.getCondition()); - gatherBinaryOperations(list, ternary.getTruePart()); - gatherBinaryOperations(list, ternary.getFalsePart()); - break; - case BINARY_OP: - var binary = (BinaryOperationNode) tree; - var operator = binary.getOperator(); - - // разыменования отбросим, хотя comparer их и не зачтет, но для производительности - // лучше выкинем их сразу - if (operator == BslOperator.DEREFERENCE || operator == BslOperator.INDEX_ACCESS) { - return; - } - - // одинаковые умножения и сложения - не считаем, см. тесты - if (operator != BslOperator.ADD && operator != BslOperator.MULTIPLY) { - list.add(binary); - } - - gatherBinaryOperations(list, binary.getLeft()); - gatherBinaryOperations(list, binary.getRight()); - break; - - default: - break; // для спокойствия сонара - } - } - private static boolean isComplementary(BinaryOperationNode binary) { var operator = binary.getOperator(); if ((operator == BslOperator.OR || operator == BslOperator.AND) diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java index 250ae335c63..53e60bc6fda 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java @@ -59,6 +59,7 @@ public int getPriority() { /** * Хелпер построения дерева выражения на основе готового AST выражения + * * @param ctx AST выражения * @return дерево вычисления выражения */ @@ -201,8 +202,9 @@ private void processOperation(OperatorInCode operator) { private boolean hasHigherPriorityOperatorsInFly(OperatorInCode operator) { var lastSeenOperator = operatorsInFly.peek(); - if (lastSeenOperator == null) + if (lastSeenOperator == null) { return false; + } return lastSeenOperator.getPriority() > operator.getPriority(); } From 7e2945b0abe09b3e04bd7a4a61a58eb4eeb06444 Mon Sep 17 00:00:00 2001 From: Alexey Sosnoviy Date: Fri, 21 Jun 2024 15:51:52 +0300 Subject: [PATCH 08/13] =?UTF-8?q?=D0=9F=D0=BE=D0=BB=D0=BE=D0=BC=D0=B0?= =?UTF-8?q?=D0=BB=20=D1=82=D0=B5=D1=81=D1=82=20=D1=81=20NoSuchElementExcep?= =?UTF-8?q?tion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/diagnostics/DoubleNegativesDiagnostic.bsl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/test/resources/diagnostics/DoubleNegativesDiagnostic.bsl b/src/test/resources/diagnostics/DoubleNegativesDiagnostic.bsl index f0493b0ec06..2890d3154b3 100644 --- a/src/test/resources/diagnostics/DoubleNegativesDiagnostic.bsl +++ b/src/test/resources/diagnostics/DoubleNegativesDiagnostic.bsl @@ -38,4 +38,8 @@ // Прямое двойное отрицание Б = Не (Не Значение); -Б = Не (Не Значение И ДругоеЗначение); // не срабатывает \ No newline at end of file +Б = Не (Не Значение И ДругоеЗначение); // не срабатывает + +// NoSuchElementException +Запись = РегистрыСведений.ЗаданияКПересчетуСтатуса.СоздатьМенеджерЗаписи(); +Запись.Записать(Истина); From 5ef9a5d144435d3171f608850390cace2169260a Mon Sep 17 00:00:00 2001 From: EvilBeaver Date: Tue, 9 Jul 2024 11:32:52 +0300 Subject: [PATCH 09/13] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=BE=20=D0=BF=D0=BE=D1=81=D1=82=D1=80=D0=BE?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B2=D1=8B=D1=80=D0=B0=D0=B6=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AbstractExpressionTreeDiagnostic.java | 27 ++++++++++++------- .../DoubleNegativesDiagnostic.java | 4 ++- .../ExpressionTreeBuildingVisitor.java | 5 ++-- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractExpressionTreeDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractExpressionTreeDiagnostic.java index d3e23cf5107..dbbcc1c9c50 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractExpressionTreeDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractExpressionTreeDiagnostic.java @@ -26,6 +26,7 @@ import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.ExpressionTreeBuildingVisitor; import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.ExpressionTreeVisitor; import com.github._1c_syntax.bsl.parser.BSLParser; +import com.github._1c_syntax.bsl.parser.BSLParserBaseVisitor; import lombok.Getter; import lombok.Setter; import org.antlr.v4.runtime.tree.ParseTree; @@ -60,7 +61,8 @@ public final List getDiagnostics(DocumentContext documentContext) { * Позволяет сократить время на построение дерева, если это не требуется для данного AST. * * @param ctx - выражение, которое в данный момент посещается. - * @return - если надо прекратить обход в глубину и построить Expression Tree на данном выражении - надо вернуть ACCEPT + * @return - флаг дальнейшего поведения. + * - если надо прекратить обход в глубину и построить Expression Tree на данном выражении - надо вернуть ACCEPT * - если надо пройти дальше и посетить дочерние выражения, не затрагивая данное - надо вернуть VISIT_CHILDREN * - если надо пропустить выражение, не ходить глубже и не строить Expression Tree - надо вернуть SKIP */ @@ -86,26 +88,33 @@ protected enum ExpressionVisitorDecision { /** * Пропустить данное выражение и обойти вложенные в него выражения */ - VISIT_CHILDREN; + VISIT_CHILDREN } - private class ExpressionTreeBuilder extends ExpressionTreeBuildingVisitor { + private class ExpressionTreeBuilder extends BSLParserBaseVisitor { + @Override public ParseTree visitExpression(BSLParser.ExpressionContext ctx) { + var treeBuildingVisitor = new ExpressionTreeBuildingVisitor(); + var result = onExpressionEnter(ctx); return switch (result) { case SKIP -> ctx; - case ACCEPT -> processExpression(ctx); - case VISIT_CHILDREN -> super.visitChildren(ctx); + case ACCEPT -> processExpression(treeBuildingVisitor, ctx); + case VISIT_CHILDREN -> treeBuildingVisitor.visitChildren(ctx); }; } - private BSLParser.ExpressionContext processExpression(BSLParser.ExpressionContext ctx) { - super.visitExpression(ctx); - var expressionTree = getExpressionTree(); - if (expressionTree != null) // нашлись выражения в предложенном файле + private BSLParser.ExpressionContext processExpression( + ExpressionTreeBuildingVisitor treeBuildingVisitor, + BSLParser.ExpressionContext ctx + ) { + treeBuildingVisitor.visitExpression(ctx); + var expressionTree = treeBuildingVisitor.getExpressionTree(); + if (expressionTree != null) { // нашлись выражения в предложенном файле visitTopLevelExpression(expressionTree); + } return ctx; } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java index 1a3cd45fcd1..35594f1abe5 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java @@ -59,7 +59,9 @@ protected void visitBinaryOperation(BinaryOperationNode node) { return; } - if (node.getOperator() == BslOperator.NOT_EQUAL || isBooleanLiteral(node.getLeft()) || isBooleanLiteral(node.getRight())) { + if (node.getOperator() == BslOperator.NOT_EQUAL + || isBooleanLiteral(node.getLeft()) + || isBooleanLiteral(node.getRight())) { addDiagnostic(node); } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java index 53e60bc6fda..cf39d3ed566 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java @@ -33,13 +33,12 @@ import java.util.Deque; import java.util.List; import java.util.Objects; -import java.util.stream.Collectors; /** * Посетитель AST, который находит выражения и преобразует их в Expression Tree */ -public class ExpressionTreeBuildingVisitor extends BSLParserBaseVisitor { +public final class ExpressionTreeBuildingVisitor extends BSLParserBaseVisitor { @Value private static class OperatorInCode { @@ -317,7 +316,7 @@ public ParseTree visitNewExpression(BSLParser.NewExpressionContext ctx) { if (typeName == null) { // function style var typeNameArg = args.get(0); - args = args.stream().skip(1).collect(Collectors.toList()); + args = args.stream().skip(1).toList(); callNode = ConstructorCallNode.createDynamic(makeSubexpression(typeNameArg.expression())); } else { // static style From 2dff72e31b6b8984d126c0984c852418512ed7ca Mon Sep 17 00:00:00 2001 From: EvilBeaver Date: Tue, 9 Jul 2024 22:16:07 +0300 Subject: [PATCH 10/13] =?UTF-8?q?=D0=A3=D0=B1=D1=80=D0=B0=D0=BB=20=D0=BF?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D1=83=20=D1=81=20=D0=BE?= =?UTF-8?q?=D1=82=D1=80=D0=B8=D1=86=D0=B0=D0=BD=D0=B8=D0=B5=D0=BC=20=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=B5=D0=BD=D1=81=D1=82=D0=B2=D0=B0=20=D0=B1=D1=83?= =?UTF-8?q?=D0=BB=D0=B5=D0=B2=D0=B0=20=D0=BB=D0=B8=D1=82=D0=B5=D1=80=D0=B0?= =?UTF-8?q?=D0=BB=D0=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DoubleNegativesDiagnostic.java | 14 +---------- .../DoubleNegativesDiagnosticTest.java | 24 +++++++++---------- .../diagnostics/DoubleNegativesDiagnostic.bsl | 4 ---- 3 files changed, 12 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java index 35594f1abe5..9e895698adc 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnostic.java @@ -31,7 +31,6 @@ import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.BslOperator; import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.ExpressionNodeType; import com.github._1c_syntax.bsl.languageserver.utils.expressiontree.UnaryOperationNode; -import com.github._1c_syntax.bsl.parser.BSLParser; @DiagnosticMetadata( type = DiagnosticType.CODE_SMELL, @@ -59,9 +58,7 @@ protected void visitBinaryOperation(BinaryOperationNode node) { return; } - if (node.getOperator() == BslOperator.NOT_EQUAL - || isBooleanLiteral(node.getLeft()) - || isBooleanLiteral(node.getRight())) { + if (node.getOperator() == BslOperator.NOT_EQUAL) { addDiagnostic(node); } @@ -83,15 +80,6 @@ protected void visitUnaryOperation(UnaryOperationNode node) { super.visitUnaryOperation(node); } - private static boolean isBooleanLiteral(BslExpression node) { - if (node.getNodeType() != ExpressionNodeType.LITERAL) { - return false; - } - - var constant = (BSLParser.ConstValueContext) node.getRepresentingAst(); - return constant.TRUE() != null || constant.FALSE() != null; - } - private static boolean isNegationOperator(BslExpression parent) { return parent.getNodeType() == ExpressionNodeType.UNARY_OP && parent.cast().getOperator() == BslOperator.NOT; diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnosticTest.java index 1880469c2c1..00311548343 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DoubleNegativesDiagnosticTest.java @@ -40,19 +40,17 @@ void test() { assertThat(diagnostics, true) .hasRange(1, 5, 1, 73) - .hasRange(7, 4, 7, 19) - .hasRange(8, 4, 8, 20) - .hasRange(9, 4, 9, 20) - .hasRange(10, 4, 10, 21) - .hasRange(11, 4, 11, 42) - .hasRange(12, 4, 12, 42) - .hasRange(13, 4, 13, 25) - .hasRange(14, 4, 14, 24) - .hasRange(19, 5, 19, 38) - .hasRange(23, 19, 23, 39) - .hasRange(32, 4, 32, 26) - .hasRange(33, 4, 33, 36) - .hasRange(39, 4, 39, 19) + .hasRange(5, 4, 5, 20) + .hasRange(6, 4, 6, 21) + .hasRange(7, 4, 7, 42) + .hasRange(8, 4, 8, 42) + .hasRange(9, 4, 9, 25) + .hasRange(10, 4, 10, 24) + .hasRange(15, 5, 15, 38) + .hasRange(19, 19, 19, 39) + .hasRange(28, 4, 28, 26) + .hasRange(29, 4, 29, 36) + .hasRange(35, 4, 35, 19) ; } diff --git a/src/test/resources/diagnostics/DoubleNegativesDiagnostic.bsl b/src/test/resources/diagnostics/DoubleNegativesDiagnostic.bsl index 2890d3154b3..b28fe9f6ca5 100644 --- a/src/test/resources/diagnostics/DoubleNegativesDiagnostic.bsl +++ b/src/test/resources/diagnostics/DoubleNegativesDiagnostic.bsl @@ -3,10 +3,6 @@ // Сделать действие КонецЕсли; -// Отрицание с проверкой на литерал - -А = Не Отказ = Ложь; -А = Не (Отказ = Ложь); А = Не Отказ <> Ложь; А = Не (Отказ <> Ложь); А = Не НекотороеЗначение() <> Неопределено; From 2f5258c1b88ce1aefd13c33e5facf7ad55419e91 Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Tue, 20 Aug 2024 06:49:37 +0000 Subject: [PATCH 11/13] Translate DoubleNegatives.md in en 100% translated source file: 'DoubleNegatives.md' on 'en'. --- docs/en/diagnostics/DoubleNegatives.md | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/docs/en/diagnostics/DoubleNegatives.md b/docs/en/diagnostics/DoubleNegatives.md index 3a6b3059d40..65eea5b15f4 100644 --- a/docs/en/diagnostics/DoubleNegatives.md +++ b/docs/en/diagnostics/DoubleNegatives.md @@ -1,28 +1,5 @@ # Double negatives (DoubleNegatives) -## Description -Using double negatives complicates the understanding of the code and can lead to errors when instead of truth the developer "in his mind" calculated False, or vice versa. It is recommended to replace double negatives with conditions that directly express the author's intentions. - -## Examples - -### Wrong - -```bsl -If Not ValueTable.Find(ValueToSearch, "Column") <> Undefined Тогда - // Act -EndIf; -``` - -### Correct - -```bsl -If ValueTable.Find(ValueToSearch, "Column") = Undefined Тогда - // Act -EndIf; -``` - -## Sources - -* Источник: [Remove double negative](https://www.refactoring.com/catalog/removeDoubleNegative.html) +* Description From 2bba5fff1445275322e088fe0916a92d0b2d7f5e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Aug 2024 09:04:56 +0000 Subject: [PATCH 12/13] build(deps): bump the freefair group with 5 updates Bumps the freefair group with 5 updates: | Package | From | To | | --- | --- | --- | | [io.freefair.lombok](https://github.com/freefair/gradle-plugins) | `8.7.1` | `8.10` | | [io.freefair.javadoc-links](https://github.com/freefair/gradle-plugins) | `8.7.1` | `8.10` | | [io.freefair.javadoc-utf-8](https://github.com/freefair/gradle-plugins) | `8.7.1` | `8.10` | | [io.freefair.aspectj.post-compile-weaving](https://github.com/freefair/gradle-plugins) | `8.7.1` | `8.10` | | [io.freefair.maven-central.validate-poms](https://github.com/freefair/gradle-plugins) | `8.7.1` | `8.10` | Updates `io.freefair.lombok` from 8.7.1 to 8.10 - [Release notes](https://github.com/freefair/gradle-plugins/releases) - [Commits](https://github.com/freefair/gradle-plugins/compare/8.7.1...8.10) Updates `io.freefair.javadoc-links` from 8.7.1 to 8.10 - [Release notes](https://github.com/freefair/gradle-plugins/releases) - [Commits](https://github.com/freefair/gradle-plugins/compare/8.7.1...8.10) Updates `io.freefair.javadoc-utf-8` from 8.7.1 to 8.10 - [Release notes](https://github.com/freefair/gradle-plugins/releases) - [Commits](https://github.com/freefair/gradle-plugins/compare/8.7.1...8.10) Updates `io.freefair.aspectj.post-compile-weaving` from 8.7.1 to 8.10 - [Release notes](https://github.com/freefair/gradle-plugins/releases) - [Commits](https://github.com/freefair/gradle-plugins/compare/8.7.1...8.10) Updates `io.freefair.maven-central.validate-poms` from 8.7.1 to 8.10 - [Release notes](https://github.com/freefair/gradle-plugins/releases) - [Commits](https://github.com/freefair/gradle-plugins/compare/8.7.1...8.10) --- updated-dependencies: - dependency-name: io.freefair.lombok dependency-type: direct:production update-type: version-update:semver-minor dependency-group: freefair - dependency-name: io.freefair.javadoc-links dependency-type: direct:production update-type: version-update:semver-minor dependency-group: freefair - dependency-name: io.freefair.javadoc-utf-8 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: freefair - dependency-name: io.freefair.aspectj.post-compile-weaving dependency-type: direct:production update-type: version-update:semver-minor dependency-group: freefair - dependency-name: io.freefair.maven-central.validate-poms dependency-type: direct:production update-type: version-update:semver-minor dependency-group: freefair ... Signed-off-by: dependabot[bot] --- build.gradle.kts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 6f64a88e434..4d82eaf66b3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,11 +11,11 @@ plugins { signing id("org.cadixdev.licenser") version "0.6.1" id("org.sonarqube") version "5.1.0.4882" - id("io.freefair.lombok") version "8.7.1" - id("io.freefair.javadoc-links") version "8.7.1" - id("io.freefair.javadoc-utf-8") version "8.7.1" - id("io.freefair.aspectj.post-compile-weaving") version "8.7.1" - id("io.freefair.maven-central.validate-poms") version "8.7.1" + id("io.freefair.lombok") version "8.10" + id("io.freefair.javadoc-links") version "8.10" + id("io.freefair.javadoc-utf-8") version "8.10" + id("io.freefair.aspectj.post-compile-weaving") version "8.10" + id("io.freefair.maven-central.validate-poms") version "8.10" id("me.qoomon.git-versioning") version "6.4.3" id("com.github.ben-manes.versions") version "0.51.0" id("org.springframework.boot") version "3.2.5" From 2f6bcd10cdc1139bcb97136dfd5199931c4c2d56 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Aug 2024 07:04:22 +0000 Subject: [PATCH 13/13] build(deps): bump me.qoomon.git-versioning from 6.4.3 to 6.4.4 Bumps me.qoomon.git-versioning from 6.4.3 to 6.4.4. --- updated-dependencies: - dependency-name: me.qoomon.git-versioning dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 4d82eaf66b3..d9056fbc834 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -16,7 +16,7 @@ plugins { id("io.freefair.javadoc-utf-8") version "8.10" id("io.freefair.aspectj.post-compile-weaving") version "8.10" id("io.freefair.maven-central.validate-poms") version "8.10" - id("me.qoomon.git-versioning") version "6.4.3" + id("me.qoomon.git-versioning") version "6.4.4" id("com.github.ben-manes.versions") version "0.51.0" id("org.springframework.boot") version "3.2.5" id("io.spring.dependency-management") version "1.1.6"