From 09032f79c434e07cf6d6f338c4382a62ad9835cc Mon Sep 17 00:00:00 2001 From: theshadowco Date: Mon, 4 Oct 2021 18:13:17 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=BE=D0=B2=D0=B0=D1=8F=20=D0=B4=D0=B8?= =?UTF-8?q?=D0=B0=D0=B3=D0=BD=D0=BE=D1=81=D1=82=D0=B8=D0=BA=D0=B0=20-=20?= =?UTF-8?q?=D0=BA=D1=80=D0=B8=D0=B2=D0=BE=D0=B9=20=D0=B7=D0=B0=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/diagnostics/BrokenQuery.md | 66 +++++++++++++++++++ docs/diagnostics/index.md | 5 +- docs/en/diagnostics/BrokenQuery.md | 36 ++++++++++ docs/en/diagnostics/index.md | 5 +- .../context/computer/QueryComputer.java | 14 ++-- .../diagnostics/BrokenQueryDiagnostic.java | 54 +++++++++++++++ .../configuration/parameters-schema.json | 10 +++ .../BrokenQueryDiagnostic_en.properties | 2 + .../BrokenQueryDiagnostic_ru.properties | 2 + .../BrokenQueryDiagnosticTest.java | 49 ++++++++++++++ .../diagnostics/BrokenQueryDiagnostic.bsl | 30 +++++++++ 11 files changed, 262 insertions(+), 11 deletions(-) create mode 100644 docs/diagnostics/BrokenQuery.md create mode 100644 docs/en/diagnostics/BrokenQuery.md create mode 100644 src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/BrokenQueryDiagnostic.java create mode 100644 src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/BrokenQueryDiagnostic_en.properties create mode 100644 src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/BrokenQueryDiagnostic_ru.properties create mode 100644 src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/BrokenQueryDiagnosticTest.java create mode 100644 src/test/resources/diagnostics/BrokenQueryDiagnostic.bsl diff --git a/docs/diagnostics/BrokenQuery.md b/docs/diagnostics/BrokenQuery.md new file mode 100644 index 00000000000..f195f57f9a1 --- /dev/null +++ b/docs/diagnostics/BrokenQuery.md @@ -0,0 +1,66 @@ +# Ошибка разбора текста запроса (BrokenQuery) + +| Тип | Поддерживаются
языки | Важность | Включена
по умолчанию | Время на
исправление (мин) | Теги | +|:-------------:|:-----------------------------:|:--------:|:------------------------------:|:-----------------------------------:|:------------------------------------------------:| +| `Дефект кода` | `BSL` | `Важный` | `Да` | `5` | `standard`
`sql`
`badpractice` | + + +## Описание диагностики + + +При написании текста запроса необходимо следовать следующему правилу: текст запроса должен быть написан таким образом, что бы он мог быть открыт конструктором запросов. + +Следование этому правилу позволяет осуществлять быструю проверку корректности синтаксиса запроса, а также доработку и сопровождение. + +## Примеры + + +Неправильно + +```bsl +ТекстЗапроса = "ВЫБРАТЬ +| Номенклатура.Наименование КАК Наименование , +| Номенклатура. " + ИмяПоляКод + " КАК КодАртикул +|ИЗ +| Справочник.Номенклатура КАК Номенклатура"; +``` + +Правильно + +```bsl +ТекстЗапроса = "ВЫБРАТЬ +| Номенклатура.Наименование КАК Наименование , +| &ИмяПоляЗапроса КАК КодАртикул +|ИЗ +| Справочник.Номенклатура КАК Номенклатура"; + +ТекстЗапроса = СтрЗаменить(ТекстЗапроса, + "&ИмяПоляКод", + "Номенклатура." + ИмяПоляКод); +``` + +## Источники + + + +* [Стандарт: Работа с запросами. Оформление текстов запросов](https://its.1c.ru/db/v8std#content:437:hdoc) + +## Сниппеты + + +### Экранирование кода + +```bsl +// BSLLS:BrokenQuery-off +// BSLLS:BrokenQuery-on +``` + +### Параметр конфигурационного файла + +```json +"BrokenQuery": false +``` diff --git a/docs/diagnostics/index.md b/docs/diagnostics/index.md index 1b41768f33c..3b575afe0fa 100644 --- a/docs/diagnostics/index.md +++ b/docs/diagnostics/index.md @@ -8,12 +8,12 @@ ## Список реализованных диагностик -Общее количество: **145** +Общее количество: **146** * Потенциальная уязвимость: **4** * Уязвимость: **4** * Ошибка: **44** -* Дефект кода: **93** +* Дефект кода: **94** | Ключ | Название | Включена по умолчанию | Важность | Тип | Тэги | @@ -21,6 +21,7 @@ [AllFunctionPathMustHaveReturn](AllFunctionPathMustHaveReturn.md) | Все возможные пути выполнения функции должны содержать оператор Возврат | Да | Важный | Дефект кода | `unpredictable`
`badpractice`
`suspicious` [AssignAliasFieldsInQuery](AssignAliasFieldsInQuery.md) | Назначение псевдонимов выбранным полям в запросе | Да | Важный | Дефект кода | `standard`
`sql`
`badpractice` [BeginTransactionBeforeTryCatch](BeginTransactionBeforeTryCatch.md) | Нарушение правил работы с транзакциями для метода 'НачатьТранзакцию' | Да | Важный | Ошибка | `standard` + [BrokenQuery](BrokenQuery.md) | Ошибка разбора текста запроса | Да | Важный | Дефект кода | `standard`
`sql`
`badpractice` [CachedPublic](CachedPublic.md) | Кеширование программного интерфейса | Да | Важный | Дефект кода | `standard`
`design` [CanonicalSpellingKeywords](CanonicalSpellingKeywords.md) | Каноническое написание ключевых слов | Да | Информационный | Дефект кода | `standard` [CodeAfterAsyncCall](CodeAfterAsyncCall.md) | После вызова асинхронного метода есть строки кода | Нет | Важный | Дефект кода | `suspicious` diff --git a/docs/en/diagnostics/BrokenQuery.md b/docs/en/diagnostics/BrokenQuery.md new file mode 100644 index 00000000000..00b20c7b97d --- /dev/null +++ b/docs/en/diagnostics/BrokenQuery.md @@ -0,0 +1,36 @@ +# Query text parsing error (BrokenQuery) + +| Type | Scope | Severity | Activated
by default | Minutes
to fix | Tags | +|:------------:|:-----:|:--------:|:-----------------------------:|:-----------------------:|:------------------------------------------------:| +| `Code smell` | `BSL` | `Major` | `Yes` | `5` | `standard`
`sql`
`badpractice` | + + +## Description + + +## Examples + + +## Sources + + + +## Snippets + + +### Diagnostic ignorance in code + +```bsl +// BSLLS:BrokenQuery-off +// BSLLS:BrokenQuery-on +``` + +### Parameter for config + +```json +"BrokenQuery": false +``` diff --git a/docs/en/diagnostics/index.md b/docs/en/diagnostics/index.md index 4427c56ec4f..ac3272fc965 100644 --- a/docs/en/diagnostics/index.md +++ b/docs/en/diagnostics/index.md @@ -8,12 +8,12 @@ To escape individual sections of code or files from triggering diagnostics, you ## Implemented diagnostics -Total: **145** +Total: **146** * Security Hotspot: **4** * Vulnerability: **4** * Error: **44** -* Code smell: **93** +* Code smell: **94** | Key | Name| Enabled by default | Severity | Type | Tags | @@ -21,6 +21,7 @@ Total: **145** [AllFunctionPathMustHaveReturn](AllFunctionPathMustHaveReturn.md) | All execution paths of a function must have a Return statement | Yes | Major | Code smell | `unpredictable`
`badpractice`
`suspicious` [AssignAliasFieldsInQuery](AssignAliasFieldsInQuery.md) | Assigning aliases to selected fields in a query | Yes | Major | Code smell | `standard`
`sql`
`badpractice` [BeginTransactionBeforeTryCatch](BeginTransactionBeforeTryCatch.md) | Violating transaction rules for the 'BeginTransaction' method | Yes | Major | Error | `standard` + [BrokenQuery](BrokenQuery.md) | Query text parsing error | Yes | Major | Code smell | `standard`
`sql`
`badpractice` [CachedPublic](CachedPublic.md) | Cached public methods | Yes | Major | Code smell | `standard`
`design` [CanonicalSpellingKeywords](CanonicalSpellingKeywords.md) | Canonical keyword writing | Yes | Info | Code smell | `standard` [CodeAfterAsyncCall](CodeAfterAsyncCall.md) | Lines of code after the asynchronous method call | No | Major | Code smell | `suspicious` diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/computer/QueryComputer.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/computer/QueryComputer.java index 1e3d05ef46a..cf7d0fbe985 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/computer/QueryComputer.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/computer/QueryComputer.java @@ -37,9 +37,6 @@ public class QueryComputer extends BSLParserBaseVisitor implements Computer> { - private final DocumentContext documentContext; - private final List queries = new ArrayList<>(); - /** * Ключевые слова для поиска потенциально запросных строк */ @@ -66,6 +63,9 @@ public class QueryComputer extends BSLParserBaseVisitor implements Co private static final Pattern FIRST_QUOTE_PATTERN = CaseInsensitivePattern.compile( "^\\s*(\")"); + private final DocumentContext documentContext; + private final List queries = new ArrayList<>(); + public QueryComputer(DocumentContext documentContext) { this.documentContext = documentContext; } @@ -85,18 +85,18 @@ public ParseTree visitString(BSLParser.StringContext ctx) { return ctx; } - int startLine = 0; + var startLine = 0; var startEmptyLines = ""; if (!ctx.getTokens().isEmpty()) { startLine = ctx.getTokens().get(0).getLine(); startEmptyLines = "\n".repeat(startLine - 1); } - boolean isQuery = false; + var isQuery = false; // конкатенация строк в одну int prevTokenLine = -1; - String partString = ""; + var partString = ""; var strings = new StringJoiner("\n"); for (Token token : ctx.getTokens()) { @@ -109,7 +109,7 @@ public ParseTree visitString(BSLParser.StringContext ctx) { // если новый токен строки находится на той же строке файла, что и предыдущий, то добавляем его к ней if (token.getLine() == prevTokenLine && prevTokenLine != -1) { - String newString = getString(startLine, token); + var newString = getString(startLine, token); partString = newString.substring(partString.length()); } else { partString = getString(startLine, token); diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/BrokenQueryDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/BrokenQueryDiagnostic.java new file mode 100644 index 00000000000..57cd43f4c07 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/BrokenQueryDiagnostic.java @@ -0,0 +1,54 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright (c) 2018-2021 + * Alexey Sosnoviy , Nikita Gryzlov 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; +import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticScope; +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.Trees; +import com.github._1c_syntax.bsl.parser.SDBLParser; +import org.antlr.v4.runtime.tree.ParseTree; + +@DiagnosticMetadata( + type = DiagnosticType.CODE_SMELL, + severity = DiagnosticSeverity.MAJOR, + minutesToFix = 5, + tags = { + DiagnosticTag.STANDARD, + DiagnosticTag.SQL, + DiagnosticTag.BADPRACTICE + }, + scope = DiagnosticScope.BSL +) +public class BrokenQueryDiagnostic extends AbstractSDBLVisitorDiagnostic { + + @Override + // анализируем каждый запрос пакета + public ParseTree visitQueries(SDBLParser.QueriesContext ctx) { + if (Trees.treeContainsErrors(ctx)) { + diagnosticStorage.addDiagnostic(ctx); + } + return ctx; + } +} 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 3a70a1e0d3e..b04d251d4ba 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 @@ -48,6 +48,16 @@ "title": "Violating transaction rules for the 'BeginTransaction' method", "$id": "#/definitions/BeginTransactionBeforeTryCatch" }, + "BrokenQuery": { + "description": "Query text parsing error", + "default": true, + "type": [ + "boolean", + "object" + ], + "title": "Query text parsing error", + "$id": "#/definitions/BrokenQuery" + }, "CachedPublic": { "description": "Cached public methods", "default": true, diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/BrokenQueryDiagnostic_en.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/BrokenQueryDiagnostic_en.properties new file mode 100644 index 00000000000..de7e8d70596 --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/BrokenQueryDiagnostic_en.properties @@ -0,0 +1,2 @@ +diagnosticMessage=Query text must be correct +diagnosticName=Query text parsing error diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/BrokenQueryDiagnostic_ru.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/BrokenQueryDiagnostic_ru.properties new file mode 100644 index 00000000000..ee09a8e0430 --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/BrokenQueryDiagnostic_ru.properties @@ -0,0 +1,2 @@ +diagnosticMessage=Текст запроса должен быть корректным и открываться конструктором запросов +diagnosticName=Ошибка разбора текста запроса diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/BrokenQueryDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/BrokenQueryDiagnosticTest.java new file mode 100644 index 00000000000..4058d6ab095 --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/BrokenQueryDiagnosticTest.java @@ -0,0 +1,49 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright (c) 2018-2021 + * Alexey Sosnoviy , Nikita Gryzlov 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; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static com.github._1c_syntax.bsl.languageserver.util.Assertions.assertThat; + +class BrokenQueryDiagnosticTest extends AbstractDiagnosticTest { + BrokenQueryDiagnosticTest() { + super(BrokenQueryDiagnostic.class); + } + + @Test + void test() { + + List diagnostics = getDiagnostics(); + + assertThat(diagnostics).hasSize(4); + assertThat(diagnostics, true) + .hasRange(5, 1, 6, 26) + .hasRange(9, 1, 10, 59) + .hasRange(14, 1, 19, 11) + .hasRange(27, 1, 28, 3) + ; + } +} diff --git a/src/test/resources/diagnostics/BrokenQueryDiagnostic.bsl b/src/test/resources/diagnostics/BrokenQueryDiagnostic.bsl new file mode 100644 index 00000000000..af7f4f919d0 --- /dev/null +++ b/src/test/resources/diagnostics/BrokenQueryDiagnostic.bsl @@ -0,0 +1,30 @@ +ТекстЗапроса = +"ВЫБРАТЬ ССЫЛКА +|ИЗ Справочник.Контрагенты"; + +ТекстЗапросаОшибка1 = +"ВЫБРАТЬ +|ИЗ Справочник.Контрагенты"; + +ТекстЗапросаОшибка2 = +"ВЫБРАТЬ Поле +|ИЗ Справочник.Контрагенты КАК Контрагенты ЛЕВОЕ СОЕДИНЕНИЕ " ++ "Документ.Накладная ПО Контрагенты.Ссылка = Покупатель"; + +ТекстЗапросаОшибка3 = +"ВЫБРАТЬ Поле +|ИЗ Справочник.Контрагенты КАК Контрагенты +|ЛЕВОЕ СОЕДИНЕНИЕ +|Документ.Накладная ПО Контрагенты.Ссылка = Покупатель +|ГДЕ +| Условие >"; + +ТекстЗапросаОшибка4 = +"ВЫБРАТЬ Поле +|ИЗ Справочник.Контрагенты КАК Контрагенты +|ЛЕВОЕ СОЕДИНЕНИЕ +|Документ.Накладная ПО Контрагенты.Ссылка = Покупатель +|; +|ВЫБРАТЬ Поле +|ИЗ +|";