diff --git a/.github/ISSUE_TEMPLATE/Bug.md b/.github/ISSUE_TEMPLATE/Bug.md index e376f03462d..e072b2709c1 100644 --- a/.github/ISSUE_TEMPLATE/Bug.md +++ b/.github/ISSUE_TEMPLATE/Bug.md @@ -11,7 +11,7 @@ assignees: '' > Версия BSLLS либо плагина, который использует BSLLS **Описание ошибки диагностики** -> Описание ошибки, замечачания +> Описание ошибки, замечания **Пример кода** > Пример кода (в блоке code или прикрепленный файл), на котором ошибка воспроизводится diff --git a/.github/ISSUE_TEMPLATE/BugDiagnostic.md b/.github/ISSUE_TEMPLATE/BugDiagnostic.md index 96aaa619206..b9a1f15012a 100644 --- a/.github/ISSUE_TEMPLATE/BugDiagnostic.md +++ b/.github/ISSUE_TEMPLATE/BugDiagnostic.md @@ -14,7 +14,7 @@ assignees: '' ## Описание ошибки диагностики - + ## Пример кода diff --git a/.github/ISSUE_TEMPLATE/NewDiagnostic.md b/.github/ISSUE_TEMPLATE/NewDiagnostic.md index dc6189c3c14..fdad78fe1e1 100644 --- a/.github/ISSUE_TEMPLATE/NewDiagnostic.md +++ b/.github/ISSUE_TEMPLATE/NewDiagnostic.md @@ -8,7 +8,7 @@ assignees: '' --- ## Описание проблемы, ошибки, которую надо диагностировать - + ## Ссылка на источник, подтверждающее нарушение либо обоснование наличия проблемы diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index f3c207da999..cff8f04f58f 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -28,10 +28,10 @@ jobs: - name: Checkout project uses: actions/checkout@v2 - - name: Setup JDK 11 + - name: Setup JDK 15 uses: actions/setup-java@v1 with: - java-version: 11 + java-version: 15 - name: Build with Gradle run: ./gradlew bootJar diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 33af458ae93..54e8043c0e5 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -22,7 +22,7 @@ jobs: - name: Setup JDK uses: actions/setup-java@v1 with: - java-version: 14 + java-version: 15 - name: Build javadoc run: ./gradlew --no-daemon javadoc diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 1a739d31b8a..a6b35bb4de5 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -8,7 +8,7 @@ jobs: strategy: fail-fast: false matrix: - java_version: ['11', '14'] + java_version: ['11', '15'] os: [ubuntu-latest, windows-latest, macOS-latest] steps: - uses: actions/checkout@v1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0fdfc38d45f..5525a278ec8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,7 +32,7 @@ jobs: - name: Set up JDK uses: actions/setup-java@v1 with: - java-version: 14 + java-version: 15 - name: Build bootJar with Gradle run: ./gradlew check bootJar - name: Build jpackage app-image diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 04b7d78ae1a..3ce68ab3333 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -6,14 +6,12 @@ - + + - - - - + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index ba393bfe0ef..050aaa4cdd6 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,9 @@ - + + + + \ No newline at end of file diff --git a/README.md b/README.md index 1955ad13dc6..801f0fb0203 100644 --- a/README.md +++ b/README.md @@ -101,15 +101,15 @@ Usage: bsl-language-server format [-hq] [-s=] Format files in source directory -h, --help Show this help message and exit -q, --silent Silent mode - -s, --srcDir= Source directory + -s, --src= Source directory or file ``` -Для указания каталога расположения форматируемых исходников используется параметр `--srcDir` (сокращенно `-s`), за которым следует путь (относительный или абсолютный) к каталогу исходников. +Для указания каталога расположения форматируемых исходников (или файла) используется параметр `--src` (сокращенно `-s`), за которым следует путь (относительный или абсолютный) к каталогу исходников (или файлу). Пример строки запуска форматирования: ```sh -java -jar bsl-language-server.jar --format --srcDir ./src/cf +java -jar bsl-language-server.jar --format --src ./src/cf ``` ## Благодарности @@ -130,7 +130,7 @@ java -jar bsl-language-server.jar --format --srcDir ./src/cf --- -[![JetBrains](docs/assets/images/jetbrains-variant-4.png)](https://www.jetbrains.com) +[![JetBrains](docs/assets/images/jetbrains-variant-4.png)](https://www.jetbrains.com?from=bsl-language-server) Создатель профессиональных инструментов разработки программного обеспечения, инновационных и мощных, [JetBrains](https://www.jetbrains.com) поддержал наш проект, предоставив лицензии на свои продукты, в том числе на `IntelliJ IDEA Ultimate`. diff --git a/build.gradle.kts b/build.gradle.kts index 5a4103f7698..49325bf69dd 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,4 @@ +import groovy.util.Node import me.qoomon.gradle.gitversioning.GitVersioningPluginConfig import me.qoomon.gradle.gitversioning.GitVersioningPluginConfig.CommitVersionDescription import me.qoomon.gradle.gitversioning.GitVersioningPluginConfig.VersionDescription @@ -6,17 +7,16 @@ import java.util.* plugins { `java-library` - maven `maven-publish` jacoco - id("com.github.hierynomus.license") version "0.15.0" + id("net.kyori.indra.license-header") version "1.0.2" id("org.sonarqube") version "3.0" id("io.franzbecker.gradle-lombok") version "4.0.0" id("me.qoomon.git-versioning") version "3.0.0" - id("com.github.ben-manes.versions") version "0.31.0" + id("com.github.ben-manes.versions") version "0.33.0" id("io.freefair.javadoc-links") version "5.2.1" - id("org.springframework.boot") version "2.3.3.RELEASE" - id("com.github.1c-syntax.bslls-dev-tools") version "0.3.0" + id("org.springframework.boot") version "2.3.5.RELEASE" + id("com.github.1c-syntax.bslls-dev-tools") version "0.3.3" } apply(plugin = "io.spring.dependency-management") @@ -45,7 +45,7 @@ gitVersioning.apply(closureOf { val jacksonVersion = "2.11.2" val junitVersion = "5.6.1" -val languageToolVersion = "5.0" +val languageToolVersion = "5.1" dependencies { @@ -53,13 +53,13 @@ dependencies { // spring api("org.springframework.boot:spring-boot-starter") - api("info.picocli:picocli-spring-boot-starter:4.5.1") + api("info.picocli:picocli-spring-boot-starter:4.5.2") // lsp4j core api("org.eclipse.lsp4j", "org.eclipse.lsp4j", "0.9.0") // 1c-syntax - api("com.github.1c-syntax", "bsl-parser", "0.16.0") { + api("com.github.1c-syntax", "bsl-parser", "2cfed6c4f59b3ea2e24e0badfd4f1ff21df7215a") { exclude("com.tunnelvisionlabs", "antlr4-annotations") exclude("com.ibm.icu", "*") exclude("org.antlr", "ST4") @@ -68,10 +68,10 @@ dependencies { exclude("org.glassfish", "javax.json") } api("com.github.1c-syntax", "utils", "0.3.1") - api("com.github.1c-syntax", "mdclasses", "0.6.1") + api("com.github.1c-syntax", "mdclasses", "0.7.0") // JLanguageTool - implementation("org.languagetool", "languagetool-core", "5.0.2") + implementation("org.languagetool", "languagetool-core", languageToolVersion) implementation("org.languagetool", "language-en", languageToolVersion) implementation("org.languagetool", "language-ru", languageToolVersion) @@ -79,9 +79,10 @@ dependencies { implementation("commons-io", "commons-io", "2.8.0") implementation("org.apache.commons", "commons-lang3", "3.11") implementation("commons-beanutils", "commons-beanutils", "1.9.4") + implementation("org.apache.commons", "commons-collections4", "4.4") // progress bar - implementation("me.tongfei", "progressbar", "0.8.1") + implementation("me.tongfei", "progressbar", "0.9.0") // (de)serialization implementation("com.fasterxml.jackson.core", "jackson-databind", jacksonVersion) @@ -94,6 +95,7 @@ dependencies { // COMPILE compileOnly("org.projectlombok", "lombok", lombok.version) + annotationProcessor("org.projectlombok", "lombok", lombok.version) // TEST @@ -106,8 +108,8 @@ dependencies { testImplementation("org.springframework.boot:spring-boot-starter-test") // test utils - testImplementation("org.assertj", "assertj-core", "3.17.2") - testImplementation("org.mockito", "mockito-core", "3.5.10") + testImplementation("org.assertj", "assertj-core", "3.18.0") + testImplementation("org.mockito", "mockito-core", "3.6.0") testImplementation("com.ginsberg", "junit5-system-exit", "1.0.0") testImplementation("org.awaitility", "awaitility", "4.0.3") } @@ -148,7 +150,7 @@ tasks.test { useJUnitPlatform() testLogging { - events("passed", "skipped", "failed") + events("passed", "skipped", "failed", "standard_error") } reports { @@ -183,18 +185,24 @@ tasks.processResources { } } +jacoco { + toolVersion = "0.8.6" +} + license { header = rootProject.file("license/HEADER.txt") ext["year"] = "2018-" + Calendar.getInstance().get(Calendar.YEAR) ext["name"] = "Alexey Sosnoviy , Nikita Gryzlov " ext["project"] = "BSL Language Server" - strictCheck = true - mapping("java", "SLASHSTAR_STYLE") exclude("**/*.properties") exclude("**/*.xml") exclude("**/*.json") exclude("**/*.bsl") exclude("**/*.os") + exclude("**/*.txt") + exclude("**/*.java.orig") + exclude("**/*.impl") + exclude("**/*.mockito.plugins.MockMaker") } sonarqube { @@ -210,8 +218,8 @@ sonarqube { } lombok { - version = "1.18.12" - sha256 = "49381508ecb02b3c173368436ef71b24c0d4418ad260e6cc98becbcf4b345406" + version = "1.18.16" + sha256 = "7206cbbfd6efd5e85bceff29545633645650be58d58910a23b0d4835fbd15ed7" } tasks { @@ -244,6 +252,7 @@ tasks { } artifacts { + archives(tasks["jar"]) archives(tasks["sourcesJar"]) archives(tasks["bootJar"]) archives(tasks["javadocJar"]) @@ -252,22 +261,26 @@ artifacts { publishing { publications { create("maven") { + artifact(tasks["jar"]) artifact(tasks["sourcesJar"]) artifact(tasks["bootJar"]) artifact(tasks["javadocJar"]) pom.withXml { val dependenciesNode = asNode().appendNode("dependencies") - configurations.implementation.get().dependencies.forEach { dependency -> - if (dependency !is SelfResolvingDependency) { - val dependencyNode = dependenciesNode.appendNode("dependency") - dependencyNode.appendNode("groupId", dependency.group) - dependencyNode.appendNode("artifactId", dependency.name) - dependencyNode.appendNode("version", dependency.version) - dependencyNode.appendNode("scope", "runtime") - } - } + configurations.implementation.get().dependencies.forEach(addDependency(dependenciesNode, "runtime")) + configurations.api.get().dependencies.forEach(addDependency(dependenciesNode, "compile")) } } } } + +fun addDependency(dependenciesNode: Node, scope: String) = { dependency: Dependency -> + if (dependency !is SelfResolvingDependency) { + val dependencyNode = dependenciesNode.appendNode("dependency") + dependencyNode.appendNode("groupId", dependency.group) + dependencyNode.appendNode("artifactId", dependency.name) + dependencyNode.appendNode("version", dependency.version) + dependencyNode.appendNode("scope", scope) + } +} diff --git a/docs/diagnostics/CodeOutOfRegion.md b/docs/diagnostics/CodeOutOfRegion.md index b0b0c272543..abd895bd657 100644 --- a/docs/diagnostics/CodeOutOfRegion.md +++ b/docs/diagnostics/CodeOutOfRegion.md @@ -4,6 +4,12 @@ :-: | :-: | :-: | :-: | :-: | :-: `Дефект кода` | `BSL` | `Информационный` | `Да` | `1` | `standard` +## Параметры + + Имя | Тип | Описание | Значение по умолчанию + :-: | :-: | :-- | :-: + `checkUnknownModuleType` | `Булево` | ```Проверять неизвестные типы модулей``` | ```false``` + ## Описание диагностики @@ -65,5 +71,7 @@ ### Параметр конфигурационного файла ```json -"CodeOutOfRegion": false +"CodeOutOfRegion": { + "checkUnknownModuleType": false +} ``` diff --git a/docs/diagnostics/CommandModuleExportMethods.md b/docs/diagnostics/CommandModuleExportMethods.md new file mode 100644 index 00000000000..bc869a7b7c2 --- /dev/null +++ b/docs/diagnostics/CommandModuleExportMethods.md @@ -0,0 +1,31 @@ +# Экспортные методы в модулях команд и общих команд (CommandModuleExportMethods) + + Тип | Поддерживаются
языки | Важность | Включена
по умолчанию | Время на
исправление (мин) | Тэги + :-: | :-: | :-: | :-: | :-: | :-: + `Дефект кода` | `BSL` | `Информационный` | `Да` | `1` | `standard`
`clumsy` + + +## Описание диагностики + +Не следует размещать экспортные методы в модулях команд и общих команд. К этим модулям нет возможности +обращаться из внешнего по отношению к ним кода, поэтому экспортные методы в этих модулях не имеют смысла. + +## Источники + +* [Источник](https://its.1c.ru/db/v8std/content/544/hdoc) + +## Сниппеты + + +### Экранирование кода + +```bsl +// BSLLS:CommandModuleExportMethods-off +// BSLLS:CommandModuleExportMethods-on +``` + +### Параметр конфигурационного файла + +```json +"CommandModuleExportMethods": false +``` diff --git a/docs/diagnostics/DeprecatedMethodCall.md b/docs/diagnostics/DeprecatedMethodCall.md index 206c6b5926e..042989f0a3e 100644 --- a/docs/diagnostics/DeprecatedMethodCall.md +++ b/docs/diagnostics/DeprecatedMethodCall.md @@ -7,6 +7,8 @@ ## Описание диагностики +В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово "Устарела." (англ. "Deprecated."). + Следует избегать использования или расширения устаревших методов. Пометка метода как устаревшего - это предупреждение о том, что метод будет удален в будущих версиях и оставлен для временной обратной совместимости. Исключение: допустимо вызывать устаревшие методы из устаревших методов. diff --git a/docs/diagnostics/FunctionOutParameter.md b/docs/diagnostics/FunctionOutParameter.md new file mode 100644 index 00000000000..4139ca3a9e7 --- /dev/null +++ b/docs/diagnostics/FunctionOutParameter.md @@ -0,0 +1,54 @@ +# Исходящий параметр функции (FunctionOutParameter) + + Тип | Поддерживаются
языки | Важность | Включена
по умолчанию | Время на
исправление (мин) | Тэги + :-: | :-: | :-: | :-: | :-: | :-: + `Дефект кода` | `BSL`
`OS` | `Важный` | `Нет` | `10` | `design` + + +## Описание диагностики + + +Функция не должна иметь выходных параметров. Весь вывод должен быть в возвращаемом значении. Если нужно возвращать несколько значений следует использовать такие типы как Структура, Массив и т.д. + +## Примеры + + +```bsl +// Не правильно: +URLСервиса = ""; +ИмяПользователя = ""; +ПарольПользователя = ""; + +ЗаполнитьПараметрыПодключения(URLСервиса, ИмяПользователя, Пароль); + +// Правильно: +ПараметрыПодключения = НовыеПараметрыПодключения(); +// Возвращаемое значение - Структура: +// URLСервиса - Строка +// ИмяПользователя - Строка +// ПарольПользователя - Строка +``` + +## Источники + + + +## Сниппеты + + +### Экранирование кода + +```bsl +// BSLLS:FunctionOutParameter-off +// BSLLS:FunctionOutParameter-on +``` + +### Параметр конфигурационного файла + +```json +"FunctionOutParameter": false +``` diff --git a/docs/diagnostics/GlobalContextMethodCollision8312.md b/docs/diagnostics/GlobalContextMethodCollision8312.md new file mode 100644 index 00000000000..b11e023ba9c --- /dev/null +++ b/docs/diagnostics/GlobalContextMethodCollision8312.md @@ -0,0 +1,55 @@ +# Конфликт имен методов с методами глобального контекста (GlobalContextMethodCollision8312) + + Тип | Поддерживаются
языки | Важность | Включена
по умолчанию | Время на
исправление (мин) | Тэги + :-: | :-: | :-: | :-: | :-: | :-: + `Ошибка` | `BSL`
`OS` | `Блокирующий` | `Да` | `10` | `error`
`unpredictable` + + +## Описание диагностики + + +Начиная с версии платформы `8.3.12`, реализованы новые методы глобального контекста, которые могут совпаcть по имени с существующими функциями в коде конфигурации прикладного решений. + +Метод|Английский вариант +:-: | :-: +ПроверитьБит|CheckBit +ПроверитьПоБитовойМаске|CheckByBitMask +УстановитьБит|SetBit +ПобитовоеИ|BitwiseAnd +ПобитовоеИли|BitwiseOr +ПобитовоеНе|BitwiseNot +ПобитовоеИНе|BitwiseAndNot +ПобитовоеИсключительноеИли|BitwiseXor +ПобитовыйСдвигВлево|BitwiseShiftLeft +ПобитовыйСдвигВправо|BitwiseShiftRight + +Необходимо существующие функции конфигурации прикладного решения необходимо либо переименовать, либо удалить, заменив обращение к ним на методы глобального контекста. + +## Примеры + + +## Источники + + + +* Источник: [Перевод конфигураций на платформу "1С:Предприятие 8.3" без режима совместимости с версией 8.2](https://its.1c.ru/db/metod8dev#content:5293:hdoc:pereimenovaniya_metodov_i_svojstv) + +## Сниппеты + + +### Экранирование кода + +```bsl +// BSLLS:GlobalContextMethodCollision8312-off +// BSLLS:GlobalContextMethodCollision8312-on +``` + +### Параметр конфигурационного файла + +```json +"GlobalContextMethodCollision8312": false +``` diff --git a/docs/diagnostics/LatinAndCyrillicSymbolInWord.md b/docs/diagnostics/LatinAndCyrillicSymbolInWord.md new file mode 100644 index 00000000000..29876aa2e5c --- /dev/null +++ b/docs/diagnostics/LatinAndCyrillicSymbolInWord.md @@ -0,0 +1,47 @@ +# Смешивание латинских и кириллических символов в одном идентификаторе (LatinAndCyrillicSymbolInWord) + + Тип | Поддерживаются
языки | Важность | Включена
по умолчанию | Время на
исправление (мин) | Тэги + :-: | :-: | :-: | :-: | :-: | :-: + `Дефект кода` | `BSL`
`OS` | `Незначительный` | `Да` | `5` | `brainoverload`
`suspicious` + +## Параметры + + Имя | Тип | Описание | Значение по умолчанию + :-: | :-: | :-- | :-: + `excludeWords` | `Строка` | ```Список слов-исключений, задается строкой через запятую``` | ```ЧтениеXML, ЧтениеJSON, ЗаписьXML, ЗаписьJSON, ComОбъект, ФабрикаXDTO, ОбъектXDTO, СоединениеFTP, HTTPСоединение, HTTPЗапрос, HTTPСервисОтвет, SMSСообщение, WSПрокси``` + + +## Описание диагностики + + +При разработке не стоит использовать идентификаторы, состоящие из символов разных языков, т.к. это усложняет их дальнейшее использование, заставляя переключать раскладку. +Диагностика обнаруживает и ошибочное использование символов из другого языка, когда он был использован не преднамеренно, например использование символов с одинаковым начертанием `o`, `c`, `B`, `p` и т.д. + +## Примеры + + +## Источники + + + +## Сниппеты + + +### Экранирование кода + +```bsl +// BSLLS:LatinAndCyrillicSymbolInWord-off +// BSLLS:LatinAndCyrillicSymbolInWord-on +``` + +### Параметр конфигурационного файла + +```json +"LatinAndCyrillicSymbolInWord": { + "excludeWords": "ЧтениеXML, ЧтениеJSON, ЗаписьXML, ЗаписьJSON, ComОбъект, ФабрикаXDTO, ОбъектXDTO, СоединениеFTP, HTTPСоединение, HTTPЗапрос, HTTPСервисОтвет, SMSСообщение, WSПрокси" +} +``` diff --git a/docs/diagnostics/MagicDate.md b/docs/diagnostics/MagicDate.md new file mode 100644 index 00000000000..8126100e4a9 --- /dev/null +++ b/docs/diagnostics/MagicDate.md @@ -0,0 +1,52 @@ +# Магические даты (MagicDate) + + Тип | Поддерживаются
языки | Важность | Включена
по умолчанию | Время на
исправление (мин) | Тэги + :-: | :-: | :-: | :-: | :-: | :-: + `Дефект кода` | `BSL`
`OS` | `Незначительный` | `Да` | `5` | `badpractice`
`brainoverload` + +## Параметры + + Имя | Тип | Описание | Значение по умолчанию + :-: | :-: | :-- | :-: + `authorizedDates` | `Строка` | ```Разрешенные даты, через запятую. Например: 00010101,00010101000000,000101010000``` | ```00010101,00010101000000,000101010000``` + + +## Описание диагностики +Магическая дата - это любая дата в вашем коде, которая не очевидна без погружения в контекст. + +## Примеры + +Плохо + +```bsl +Если текДата < '20151021' Тогда + ХоверБордБудетИзобретен = Неопределено; +КонецЕсли; +``` + +Хорошо + +```bsl +ПредсказаннаяДата = '20151021'; +Если текДата < ПредсказаннаяДата Тогда + ХоверБордБудетИзобретен = Неопределено; +КонецЕсли; +``` + +## Сниппеты + + +### Экранирование кода + +```bsl +// BSLLS:MagicDate-off +// BSLLS:MagicDate-on +``` + +### Параметр конфигурационного файла + +```json +"MagicDate": { + "authorizedDates": "00010101,00010101000000,000101010000" +} +``` diff --git a/docs/diagnostics/MissingEventSubscriptionHandler.md b/docs/diagnostics/MissingEventSubscriptionHandler.md new file mode 100644 index 00000000000..577319fd611 --- /dev/null +++ b/docs/diagnostics/MissingEventSubscriptionHandler.md @@ -0,0 +1,40 @@ +# Отсутствует обработчик подписки на событие (MissingEventSubscriptionHandler) + + Тип | Поддерживаются
языки | Важность | Включена
по умолчанию | Время на
исправление (мин) | Тэги + :-: | :-: | :-: | :-: | :-: | :-: + `Ошибка` | `BSL` | `Блокирующий` | `Да` | `5` | `error` + + +## Описание диагностики + + +Если у подписки на событие не указан обработчик либо обработчик не существует, то возникнет ошибка при работе приложения. + +**Внимание: Диагностика прикрепляет замечания на модуль сеанса.** + +## Примеры + + +## Источники + + + +## Сниппеты + + +### Экранирование кода + +```bsl +// BSLLS:MissingEventSubscriptionHandler-off +// BSLLS:MissingEventSubscriptionHandler-on +``` + +### Параметр конфигурационного файла + +```json +"MissingEventSubscriptionHandler": false +``` diff --git a/docs/diagnostics/MissingParameterDescription.md b/docs/diagnostics/MissingParameterDescription.md new file mode 100644 index 00000000000..5031a3b1156 --- /dev/null +++ b/docs/diagnostics/MissingParameterDescription.md @@ -0,0 +1,49 @@ +# Отсутствует описание параметров метода (MissingParameterDescription) + + Тип | Поддерживаются
языки | Важность | Включена
по умолчанию | Время на
исправление (мин) | Тэги + :-: | :-: | :-: | :-: | :-: | :-: + `Дефект кода` | `BSL`
`OS` | `Важный` | `Да` | `5` | `standard`
`badpractice` + + +## Описание диагностики + + +Описание метода (процедуры или функции) должно оформляться корректно, помогая программистам правильно использовать функциональность. + +Если метод содержит параметры, то в его описании, в одноименном блоке, должны быть приведены описания для всех параметров в том же порядке, что и в сигнатуре метода. + +Диагностика обнаруживает типовые ошибки: + +- Отсутствие описания всех параметров +- Отсутствие описания части параметров, с указанием, для какого параметра описание не обнаружено +- Присутствие в описании параметров, отсутстсвующих в сигнатуре метода (которые могли остаться от рефакторинга) +- Некачественное описание параметра: когда имя параметра присутствует в описании метода, но не указаны тип параметра и описание типа + +## Примеры + + +## Источники + + + +* Источник: [Стандарт: Описание процедур и функций](https://its.1c.ru/db/v8std#content:453:hdoc) + +## Сниппеты + + +### Экранирование кода + +```bsl +// BSLLS:MissingParameterDescription-off +// BSLLS:MissingParameterDescription-on +``` + +### Параметр конфигурационного файла + +```json +"MissingParameterDescription": false +``` diff --git a/docs/diagnostics/MissingReturnedValueDescription.md b/docs/diagnostics/MissingReturnedValueDescription.md new file mode 100644 index 00000000000..d5c694549d3 --- /dev/null +++ b/docs/diagnostics/MissingReturnedValueDescription.md @@ -0,0 +1,48 @@ +# Отсутствует описание возвращаемого значения функции (MissingReturnedValueDescription) + + Тип | Поддерживаются
языки | Важность | Включена
по умолчанию | Время на
исправление (мин) | Тэги + :-: | :-: | :-: | :-: | :-: | :-: + `Дефект кода` | `BSL`
`OS` | `Важный` | `Да` | `5` | `standard`
`badpractice` + + +## Описание диагностики + + +Описание метода (процедуры или функции) должно оформляться корректно, помогая программистам правильно использовать функциональность. + +Описание функции должно содержать описание возвращаемого значения в одноименном блоке. Необходимо привести описание для всех возможных типов возвращаемого значения. + +Диагностика обнаруживает типовые ошибки: + +- Отсутствие описания возвращаемого значения +- Наличие описания возвращаемого значения у процедуры +- Некачественное описание возвращаемого значения: когда имя типа присутствует в описании, но не указано его описание + +## Примеры + + +## Источники + + + +* Источник: [Стандарт: Описание процедур и функций](https://its.1c.ru/db/v8std#content:453:hdoc) + +## Сниппеты + + +### Экранирование кода + +```bsl +// BSLLS:MissingReturnedValueDescription-off +// BSLLS:MissingReturnedValueDescription-on +``` + +### Параметр конфигурационного файла + +```json +"MissingReturnedValueDescription": false +``` diff --git a/docs/diagnostics/MissingSpace.md b/docs/diagnostics/MissingSpace.md index 39e2cce44dd..4c60d263485 100644 --- a/docs/diagnostics/MissingSpace.md +++ b/docs/diagnostics/MissingSpace.md @@ -1,4 +1,4 @@ -# Пропущены пробелы слева или справа от операторов `+ - * / = % < > <> <= >=`, а так же справа от `,` и `;` (MissingSpace) +# Пропущены пробелы слева или справа от операторов `+ - * / = % < > <> <= >=`, от ключевых слов, а так же справа от `,` и `;` (MissingSpace) Тип | Поддерживаются
языки | Важность | Включена
по умолчанию | Время на
исправление (мин) | Тэги :-: | :-: | :-: | :-: | :-: | :-: @@ -8,9 +8,9 @@ Имя | Тип | Описание | Значение по умолчанию :-: | :-: | :-- | :-: - `listForCheckLeft` | `Строка` | ```Список символов для проверки слева (разделенные пробелом). Например: ) =``` | `````` - `listForCheckRight` | `Строка` | ```Список символов для проверки справа (разделенные пробелом). Например: ( =``` | ```, ;``` - `listForCheckLeftAndRight` | `Строка` | ```Список символов для проверки с обоих сторон (разделенные пробелом). Например: + - * / = % < >``` | ```+ - * / = % < > <> <= >=``` + `listForCheckLeft` | `Строка` | ```Список для проверки слева (разделенные пробелом). Например: ) =``` | `````` + `listForCheckRight` | `Строка` | ```Список для проверки справа (разделенные пробелом). Например: ( =``` | ```, ;``` + `listForCheckLeftAndRight` | `Строка` | ```Список для проверки с обоих сторон (разделенные пробелом). Например: + - * / = % < >``` | ```+ - * / = % < > <> <= >=``` `checkSpaceToRightOfUnary` | `Булево` | ```Проверять наличие пробела справа от унарных знаков (+ -)``` | ```false``` `allowMultipleCommas` | `Булево` | ```Разрешать несколько запятых подряд``` | ```false``` diff --git a/docs/diagnostics/NestedFunctionInParameters.md b/docs/diagnostics/NestedFunctionInParameters.md index 8dcc70769c2..ff81d7f9d4b 100644 --- a/docs/diagnostics/NestedFunctionInParameters.md +++ b/docs/diagnostics/NestedFunctionInParameters.md @@ -2,7 +2,7 @@ Тип | Поддерживаются
языки | Важность | Включена
по умолчанию | Время на
исправление (мин) | Тэги :-: | :-: | :-: | :-: | :-: | :-: - `Дефект кода` | `BSL`
`OS` | `Незначительный` | `Да` | `5` | `standard`
`brainoverload`
`badpractice` + `Дефект кода` | `BSL`
`OS` | `Незначительный` | `Да` | `2` | `standard`
`brainoverload`
`badpractice` ## Описание диагностики diff --git a/docs/diagnostics/OrdinaryAppSupport.md b/docs/diagnostics/OrdinaryAppSupport.md new file mode 100644 index 00000000000..bc0a486accd --- /dev/null +++ b/docs/diagnostics/OrdinaryAppSupport.md @@ -0,0 +1,48 @@ +# Поддержка обычного приложения (OrdinaryAppSupport) + + Тип | Поддерживаются
языки | Важность | Включена
по умолчанию | Время на
исправление (мин) | Тэги + :-: | :-: | :-: | :-: | :-: | :-: + `Дефект кода` | `BSL` | `Важный` | `Да` | `1` | `standard`
`unpredictable` + + +## Описание диагностики + +Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, +разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск +в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). + +Для этого рекомендуется: + +* Свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина. +* Свойство «Использовать обычные формы в управляемом режиме» установить в Ложь. +* придерживаться общей схемы установки признаков общих модулей, а саму разработку в Конфигураторе вести в режиме +редактирования для обоих режимов запуска – управляемое и обычное приложение (меню Сервис – Параметры – закладка Общие). + +При разработке в EDT свойства устанавливаются через Конфигуратор. + +Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен +только в отдельных, обоснованных случаях. + +## Примеры + + +## Источники + + +* Источник: [Стандарт: Общие требования к конфигурации](https://its.1c.ru/db/v8std#content:467:hdoc) + +## Сниппеты + + +### Экранирование кода + +```bsl +// BSLLS:OrdinaryAppSupport-off +// BSLLS:OrdinaryAppSupport-on +``` + +### Параметр конфигурационного файла + +```json +"OrdinaryAppSupport": false +``` diff --git a/docs/diagnostics/RedundantAccessToObject.md b/docs/diagnostics/RedundantAccessToObject.md new file mode 100644 index 00000000000..6c9ec87b04b --- /dev/null +++ b/docs/diagnostics/RedundantAccessToObject.md @@ -0,0 +1,58 @@ +# Избыточное обращение к объекту (RedundantAccessToObject) + + Тип | Поддерживаются
языки | Важность | Включена
по умолчанию | Время на
исправление (мин) | Тэги + :-: | :-: | :-: | :-: | :-: | :-: + `Дефект кода` | `BSL` | `Информационный` | `Да` | `1` | `standard`
`clumsy` + +## Параметры + + Имя | Тип | Описание | Значение по умолчанию + :-: | :-: | :-- | :-: + `checkObjectModule` | `Булево` | ```Проверять модули объектов``` | ```true``` + `checkFormModule` | `Булево` | ```Проверять модули форм``` | ```true``` + `checkRecordSetModule` | `Булево` | ```Проверять модули наборов записей``` | ```true``` + + +## Описание диагностики +В формах и модулях объектов избыточно обращаться к реквизитам через ЭтотОбъект. В общих модулях избыточно обращаться к методам через свое имя, кроме модулей с ПовтИсп. + +## Примеры +В модуле объекта документа с реквизитом `Контрагент` неправильно писать +```bsl +ЭтотОбъект.Контрагент = ПолучитьКонтрагента(); +``` + +правильно будет обратиться к реквизиту напрямую +```bsl +Контрагент = ПолучитьКонтрагента(); +``` + +В общем модуле `ОбщегоНазначения` неправильным будет такой вызов метода +```bsl +ОбщегоНазначения.СообщитьПользователю("ru = 'Привет мир!'"); +``` + +а правильным +```bsl +СообщитьПользователю("ru = 'Привет мир!'"); +``` + +## Сниппеты + + +### Экранирование кода + +```bsl +// BSLLS:RedundantAccessToObject-off +// BSLLS:RedundantAccessToObject-on +``` + +### Параметр конфигурационного файла + +```json +"RedundantAccessToObject": { + "checkObjectModule": true, + "checkFormModule": true, + "checkRecordSetModule": true +} +``` diff --git a/docs/diagnostics/RefOveruse.md b/docs/diagnostics/RefOveruse.md new file mode 100644 index 00000000000..75211cc8586 --- /dev/null +++ b/docs/diagnostics/RefOveruse.md @@ -0,0 +1,43 @@ +# Избыточное использование "Ссылка" в запросе (RefOveruse) + + Тип | Поддерживаются
языки | Важность | Включена
по умолчанию | Время на
исправление (мин) | Тэги + :-: | :-: | :-: | :-: | :-: | :-: + `Дефект кода` | `BSL` | `Важный` | `Да` | `5` | `sql`
`performance` + + +## Описание диагностики + +Использование ".Ссылка" к полю ссылочного типа приведет к неявному левому соединению с таблицей-источником данного поля, +при этом не несет никакой ценности, а только генерирует избыточную нагрузку на СУБД. +## Примеры + +``` +Запрос.Текст = "ВЫБРАТЬ Файлы.Файл.Ссылка, // ошибка + | Файлы.Файл + | ИЗ + | СлужебныеФайлы КАК Файлы"; +``` +## Источники + + +* Полезная информация: [Разыменование ссылочных полей составного типа в языке запросов](https://its.1c.ru/db/v8std/content/654/hdoc) + +## Сниппеты + + +### Экранирование кода + +```bsl +// BSLLS:RefOveruse-off +// BSLLS:RefOveruse-on +``` + +### Параметр конфигурационного файла + +```json +"RefOveruse": false +``` diff --git a/docs/diagnostics/Typo.md b/docs/diagnostics/Typo.md index 88112c344eb..524bbd39bbf 100644 --- a/docs/diagnostics/Typo.md +++ b/docs/diagnostics/Typo.md @@ -9,7 +9,7 @@ Имя | Тип | Описание | Значение по умолчанию :-: | :-: | :-- | :-: `minWordLength` | `Целое` | ```Минимальная длина проверяемых слов``` | ```3``` - `userWordsToIgnore` | `Строка` | ```Пользовательский словарь исключений (через запятую, без пробелов)``` | `````` + `userWordsToIgnore` | `Строка` | ```Пользовательский словарь исключений (через запятую)``` | `````` ## Описание диагностики diff --git a/docs/diagnostics/UnusedLocalMethod.md b/docs/diagnostics/UnusedLocalMethod.md index 377dea4cad5..706e6551315 100644 --- a/docs/diagnostics/UnusedLocalMethod.md +++ b/docs/diagnostics/UnusedLocalMethod.md @@ -2,7 +2,7 @@ Тип | Поддерживаются
языки | Важность | Включена
по умолчанию | Время на
исправление (мин) | Тэги :-: | :-: | :-: | :-: | :-: | :-: - `Дефект кода` | `BSL`
`OS` | `Важный` | `Да` | `1` | `standard`
`suspicious` + `Дефект кода` | `BSL`
`OS` | `Важный` | `Да` | `1` | `standard`
`suspicious`
`unused` ## Описание диагностики diff --git a/docs/diagnostics/UnusedParameters.md b/docs/diagnostics/UnusedParameters.md index 9eb997249e1..5108ce1a39a 100644 --- a/docs/diagnostics/UnusedParameters.md +++ b/docs/diagnostics/UnusedParameters.md @@ -2,7 +2,7 @@ Тип | Поддерживаются
языки | Важность | Включена
по умолчанию | Время на
исправление (мин) | Тэги :-: | :-: | :-: | :-: | :-: | :-: - `Дефект кода` | `OS` | `Важный` | `Да` | `5` | `design` + `Дефект кода` | `OS` | `Важный` | `Да` | `5` | `design`
`unused` ## Описание диагностики diff --git a/docs/diagnostics/UsingModalWindows.md b/docs/diagnostics/UsingModalWindows.md index ad690bc6e44..a3b79db7311 100644 --- a/docs/diagnostics/UsingModalWindows.md +++ b/docs/diagnostics/UsingModalWindows.md @@ -4,6 +4,12 @@ :-: | :-: | :-: | :-: | :-: | :-: `Дефект кода` | `BSL` | `Важный` | `Да` | `15` | `standard` +## Параметры + + Имя | Тип | Описание | Значение по умолчанию + :-: | :-: | :-- | :-: + `forceModalityMode` | `Булево` | ```Игнорировать использование модальности конфигурации``` | ```false``` + ## Описание диагностики @@ -58,5 +64,7 @@ ### Параметр конфигурационного файла ```json -"UsingModalWindows": false +"UsingModalWindows": { + "forceModalityMode": false +} ``` diff --git a/docs/diagnostics/index.md b/docs/diagnostics/index.md index e5066976d5e..2032d5b13e7 100644 --- a/docs/diagnostics/index.md +++ b/docs/diagnostics/index.md @@ -8,12 +8,13 @@ ## Список реализованных диагностик -Общее количество: **117** +Общее количество: **128** -* Дефект кода: **74** -* Уязвимость: **3** -* Ошибка: **36** * Потенциальная уязвимость: **4** +* Уязвимость: **3** +* Ошибка: **38** +* Дефект кода: **83** + | Ключ | Название | Включена по умолчанию | Важность | Тип | Тэги | | --- | --- | :-: | --- | --- | --- | @@ -23,6 +24,7 @@ [CodeBlockBeforeSub](CodeBlockBeforeSub.md) | Определения методов должны размещаться перед операторами тела модуля | Да | Блокирующий | Ошибка | `error` [CodeOutOfRegion](CodeOutOfRegion.md) | Код расположен вне области | Да | Информационный | Дефект кода | `standard` [CognitiveComplexity](CognitiveComplexity.md) | Когнитивная сложность | Да | Критичный | Дефект кода | `brainoverload` + [CommandModuleExportMethods](CommandModuleExportMethods.md) | Экспортные методы в модулях команд и общих команд | Да | Информационный | Дефект кода | `standard`
`clumsy` [CommentedCode](CommentedCode.md) | Закомментированный фрагмент кода | Да | Незначительный | Дефект кода | `standard`
`badpractice` [CommitTransactionOutsideTryCatch](CommitTransactionOutsideTryCatch.md) | Нарушение правил работы с транзакциями для метода 'ЗафиксироватьТранзакцию' | Да | Важный | Ошибка | `standard` [CommonModuleAssign](CommonModuleAssign.md) | Присвоение общему модулю | Да | Блокирующий | Ошибка | `error` @@ -61,9 +63,11 @@ [ExtraCommas](ExtraCommas.md) | Запятые без указания параметра в конце вызова метода | Да | Важный | Дефект кода | `standard`
`badpractice` [FormDataToValue](FormDataToValue.md) | Использование метода ДанныеФормыВЗначение | Да | Информационный | Дефект кода | `badpractice` [FunctionNameStartsWithGet](FunctionNameStartsWithGet.md) | Имя функции не должно начинаться с "Получить" | Нет | Информационный | Дефект кода | `standard` + [FunctionOutParameter](FunctionOutParameter.md) | Исходящий параметр функции | Нет | Важный | Дефект кода | `design` [FunctionReturnsSamePrimitive](FunctionReturnsSamePrimitive.md) | Функция всегда возвращает одно и то же примитивное значение | Да | Важный | Ошибка | `design`
`badpractice` [FunctionShouldHaveReturn](FunctionShouldHaveReturn.md) | Функция должна содержать возврат | Да | Важный | Ошибка | `suspicious`
`unpredictable` [GetFormMethod](GetFormMethod.md) | Использование метода ПолучитьФорму | Да | Важный | Ошибка | `error` + [GlobalContextMethodCollision8312](GlobalContextMethodCollision8312.md) | Конфликт имен методов с методами глобального контекста | Да | Блокирующий | Ошибка | `error`
`unpredictable` [IdenticalExpressions](IdenticalExpressions.md) | Одинаковые выражения слева и справа от "foo" оператора | Да | Важный | Ошибка | `suspicious` [IfConditionComplexity](IfConditionComplexity.md) | Использование сложных выражений в условии оператора "Если" | Да | Незначительный | Дефект кода | `brainoverload` [IfElseDuplicatedCodeBlock](IfElseDuplicatedCodeBlock.md) | Повторяющиеся блоки кода в синтаксической конструкции Если...Тогда...ИначеЕсли... | Да | Незначительный | Дефект кода | `suspicious` @@ -73,12 +77,17 @@ [IsInRoleMethod](IsInRoleMethod.md) | Использование метода РольДоступна | Да | Важный | Дефект кода | `error` [JoinWithSubQuery](JoinWithSubQuery.md) | Соединение с вложенными запросами | Да | Важный | Дефект кода | `sql`
`standard`
`performance` [JoinWithVirtualTable](JoinWithVirtualTable.md) | Соединение с виртуальными таблицами | Да | Важный | Дефект кода | `sql`
`standard`
`performance` + [LatinAndCyrillicSymbolInWord](LatinAndCyrillicSymbolInWord.md) | Смешивание латинских и кириллических символов в одном идентификаторе | Да | Незначительный | Дефект кода | `brainoverload`
`suspicious` [LineLength](LineLength.md) | Ограничение на длину строки | Да | Незначительный | Дефект кода | `standard`
`badpractice` + [MagicDate](MagicDate.md) | Магические даты | Да | Незначительный | Дефект кода | `badpractice`
`brainoverload` [MagicNumber](MagicNumber.md) | Магические числа | Да | Незначительный | Дефект кода | `badpractice` [MetadataObjectNameLength](MetadataObjectNameLength.md) | Имена объектов метаданных не должны превышать допустимой длины наименования | Да | Важный | Ошибка | `standard` [MethodSize](MethodSize.md) | Ограничение на размер метода | Да | Важный | Дефект кода | `badpractice` [MissingCodeTryCatchEx](MissingCodeTryCatchEx.md) | Конструкция "Попытка...Исключение...КонецПопытки" не содержит кода в исключении | Да | Важный | Ошибка | `standard`
`badpractice` - [MissingSpace](MissingSpace.md) | Пропущены пробелы слева или справа от операторов `+ - * / = % < > <> <= >=`, а так же справа от `,` и `;` | Да | Информационный | Дефект кода | `badpractice` + [MissingEventSubscriptionHandler](MissingEventSubscriptionHandler.md) | Отсутствует обработчик подписки на событие | Да | Блокирующий | Ошибка | `error` + [MissingParameterDescription](MissingParameterDescription.md) | Отсутствует описание параметров метода | Да | Важный | Дефект кода | `standard`
`badpractice` + [MissingReturnedValueDescription](MissingReturnedValueDescription.md) | Отсутствует описание возвращаемого значения функции | Да | Важный | Дефект кода | `standard`
`badpractice` + [MissingSpace](MissingSpace.md) | Пропущены пробелы слева или справа от операторов `+ - * / = % < > <> <= >=`, от ключевых слов, а так же справа от `,` и `;` | Да | Информационный | Дефект кода | `badpractice` [MissingTemporaryFileDeletion](MissingTemporaryFileDeletion.md) | Отсутствует удаление временного файла после использования | Да | Важный | Ошибка | `badpractice`
`standard` [MissingVariablesDescription](MissingVariablesDescription.md) | Все объявления переменных должны иметь описание | Да | Незначительный | Дефект кода | `standard` [MultilingualStringHasAllDeclaredLanguages](MultilingualStringHasAllDeclaredLanguages.md) | Есть локализованный текст для всех заявленных в конфигурации языков | Да | Незначительный | Ошибка | `error`
`localize` @@ -95,10 +104,13 @@ [OSUsersMethod](OSUsersMethod.md) | Использование метода ПользователиОС | Да | Критичный | Потенциальная уязвимость | `suspicious` [OneStatementPerLine](OneStatementPerLine.md) | Одно выражение в одной строке | Да | Незначительный | Дефект кода | `standard`
`design` [OrderOfParams](OrderOfParams.md) | Порядок параметров метода | Да | Важный | Дефект кода | `standard`
`design` + [OrdinaryAppSupport](OrdinaryAppSupport.md) | Поддержка обычного приложения | Да | Важный | Дефект кода | `standard`
`unpredictable` [PairingBrokenTransaction](PairingBrokenTransaction.md) | Нарушение парности использования методов "НачатьТранзакцию()" и "ЗафиксироватьТранзакцию()" / "ОтменитьТранзакцию()" | Да | Важный | Ошибка | `standard` [ParseError](ParseError.md) | Ошибка разбора исходного кода | Да | Критичный | Ошибка | `error` [ProcedureReturnsValue](ProcedureReturnsValue.md) | Процедура не должна возвращать значение | Да | Блокирующий | Ошибка | `error` [PublicMethodsDescription](PublicMethodsDescription.md) | Все методы программного интерфейса должны иметь описание | Да | Информационный | Дефект кода | `standard`
`brainoverload`
`badpractice` + [RedundantAccessToObject](RedundantAccessToObject.md) | Избыточное обращение к объекту | Да | Информационный | Дефект кода | `standard`
`clumsy` + [RefOveruse](RefOveruse.md) | Избыточное использование "Ссылка" в запросе | Да | Важный | Дефект кода | `sql`
`performance` [SelfAssign](SelfAssign.md) | Присвоение переменной самой себе | Да | Важный | Ошибка | `suspicious` [SelfInsertion](SelfInsertion.md) | Вставка коллекции в саму себя | Да | Важный | Ошибка | `standard`
`unpredictable`
`performance` [SemicolonPresence](SemicolonPresence.md) | Выражение должно заканчиваться символом ";" | Да | Незначительный | Дефект кода | `standard`
`badpractice` @@ -117,8 +129,8 @@ [UnknownPreprocessorSymbol](UnknownPreprocessorSymbol.md) | Неизвестный символ препроцессора | Да | Критичный | Ошибка | `standard`
`error` [UnreachableCode](UnreachableCode.md) | Недостижимый код | Да | Незначительный | Ошибка | `design`
`suspicious` [UnsafeSafeModeMethodCall](UnsafeSafeModeMethodCall.md) | Небезопасное использование функции БезопасныйРежим() | Да | Блокирующий | Ошибка | `deprecated`
`error` - [UnusedLocalMethod](UnusedLocalMethod.md) | Неиспользуемый локальный метод | Да | Важный | Дефект кода | `standard`
`suspicious` - [UnusedParameters](UnusedParameters.md) | Неиспользуемый параметр | Да | Важный | Дефект кода | `design` + [UnusedLocalMethod](UnusedLocalMethod.md) | Неиспользуемый локальный метод | Да | Важный | Дефект кода | `standard`
`suspicious`
`unused` + [UnusedParameters](UnusedParameters.md) | Неиспользуемый параметр | Да | Важный | Дефект кода | `design`
`unused` [UseLessForEach](UseLessForEach.md) | Бесполезный перебор коллекции | Да | Критичный | Ошибка | `clumsy` [UsingCancelParameter](UsingCancelParameter.md) | Работа с параметром "Отказ" | Да | Важный | Дефект кода | `standard`
`badpractice` [UsingExternalCodeTools](UsingExternalCodeTools.md) | Использование возможностей выполнения внешнего кода | Да | Критичный | Потенциальная уязвимость | `standard`
`design` diff --git a/docs/en/diagnostics/CodeBlockBeforeSub.md b/docs/en/diagnostics/CodeBlockBeforeSub.md index 8710886751c..ed60fd10fad 100644 --- a/docs/en/diagnostics/CodeBlockBeforeSub.md +++ b/docs/en/diagnostics/CodeBlockBeforeSub.md @@ -24,7 +24,12 @@ Based on the structure described above, the location of the program code before Wrong ```bsl -Method(); Message("Before methods"); Procedure Method() // Method body EndProcedure +SomeMethod(); +Message("Before methods definition"); + +Procedure SomeMethod() +// Method body +EndProcedure ``` ## Sources diff --git a/docs/en/diagnostics/CodeOutOfRegion.md b/docs/en/diagnostics/CodeOutOfRegion.md index f1614eb2339..672c94e4521 100644 --- a/docs/en/diagnostics/CodeOutOfRegion.md +++ b/docs/en/diagnostics/CodeOutOfRegion.md @@ -4,6 +4,12 @@ :-: | :-: | :-: | :-: | :-: | :-: `Code smell` | `BSL` | `Info` | `Yes` | `1` | `standard` +## Parameters + + Name | Type | Description | Default value + :-: | :-: | :-- | :-: + `checkUnknownModuleType` | `Boolean` | ```Check unknown module type``` | ```false``` + ## Description @@ -69,5 +75,7 @@ RU | EN ### Parameter for config ```json -"CodeOutOfRegion": false +"CodeOutOfRegion": { + "checkUnknownModuleType": false +} ``` diff --git a/docs/en/diagnostics/CognitiveComplexity.md b/docs/en/diagnostics/CognitiveComplexity.md index 2d5c5055d7d..bbcec93b328 100644 --- a/docs/en/diagnostics/CognitiveComplexity.md +++ b/docs/en/diagnostics/CognitiveComplexity.md @@ -14,9 +14,7 @@ ## Description -Cognitive complexity shows how difficult it is to perceive the written code. - High cognitive complexity clearly indicates the need for refactoring to make future support easier. - The most effective way to reduce cognitive complexity is to decompose the code, split the methods into simpler ones, and also optimize logical expressions. +Cognitive complexity shows how difficult it is to perceive the written code. High cognitive complexity clearly indicates the need for refactoring to make future support easier. The most effective way to reduce cognitive complexity is to decompose the code, split the methods into simpler ones, and also optimize logical expressions. ### Cognitive Complexity calculation @@ -26,91 +24,89 @@ Bellow are given code analysis rules, conditions increase cognitive complexity. ```bsl -// Loop For Each -For Each Element In Collection Do // +1 +// Loop `For each` +For Each Element in Collection Do // +1 EndDo; -// Loop For -For It = Start To End Do // +1 +// Loop `For` +For i = StartValue To EndValue Do // +1 EndDo; -// Loop While +// Loop `While` While Condition Do // +1 EndDo; // Condition -If Condition Then // +1 +If Condition1 Then // +1 // Alternative condition branch ElseIf Condition2 Then // +1 -// Default branch +// default branch Else EndIf; -// Ternary operator +// ternary operator Value = ?(Condition, ValueTrue, ValueFalse); // +1 Try -// Except processing +// Exception handling Except // +1 EndTry; -// Goto label -Goto ~Label; // +1 +// Go to label +Goto ~Label; // +1 -// Binary logical operators +// Binary logical operations -While Condition OR Condition2 Do // +2 +While Condition1 Or Condition2 Do // +2 EndDo; -If Condition OR Condition2 Then // +2 +If Condition1 And Condition2 Then // +2 ElseIf Condition2 // +1 - Or Condition3 AND Condition4 Then // +2 + Or Condition3 And Condition4 Then // +2 EndIf; -Value = ?(Condition OR Condition2 OR NOT Condition3, // +3 +Value = ?(Condition1 Or Condition2 Or Not Condition3,// +3 ValueTrue, ValueFalse); -Value = First OR Second; // +1 +Value = First Or Second; // +1 Value = A <> B; // +1 - ``` #### For each nesting level, next blocks get additional 1 to complexity ```bsl -// Loop For Each -For Each Element In Collection Do +// Loop `For each` +For Each Element in Collection Do EndDo; -/// Loop For -For It = Start To End Do +// Loop `For` +For i = StartValue To EndValue Do +EndDo; -// Loop While +// Loop `While` While Condition Do EndDo; - // Condition -If Condition Then +If Condition1 Then EndIf; -// Ternary operator +// ternary operator Value = ?(Condition, ValueTrue, ValueFalse); Try -// Except processing +// Exception handling Except EndTry; ~Label: - ``` #### Alternative branches, binary operations, and go to label do not increase cognitive complexity when nested. diff --git a/docs/en/diagnostics/CommandModuleExportMethods.md b/docs/en/diagnostics/CommandModuleExportMethods.md new file mode 100644 index 00000000000..0238f6cadd2 --- /dev/null +++ b/docs/en/diagnostics/CommandModuleExportMethods.md @@ -0,0 +1,30 @@ +# Export methods in command and general command modules (CommandModuleExportMethods) + + Type | Scope | Severity | Activated
by default | Minutes
to fix | Tags + :-: | :-: | :-: | :-: | :-: | :-: + `Code smell` | `BSL` | `Info` | `Yes` | `1` | `standard`
`clumsy` + + +## Description + +You should not place export methods in command and General command modules. You can't access these modules from code external to them, so export methods in these modules do not make sense. + +## Sources + +- [Source(RU)](https://its.1c.ru/db/v8std/content/544/hdoc) + +## Snippets + + +### Diagnostic ignorance in code + +```bsl +// BSLLS:CommandModuleExportMethods-off +// BSLLS:CommandModuleExportMethods-on +``` + +### Parameter for config + +```json +"CommandModuleExportMethods": false +``` diff --git a/docs/en/diagnostics/CommonModuleAssign.md b/docs/en/diagnostics/CommonModuleAssign.md index 705e6d06ac9..af2d57ffd13 100644 --- a/docs/en/diagnostics/CommonModuleAssign.md +++ b/docs/en/diagnostics/CommonModuleAssign.md @@ -9,7 +9,7 @@ -When assigning a value to a common module, an exception will be thrown. Such a situation is possible when a common module with a name that is already used for a variable is added to the configuration. +Setting a value to a common module throws exception.
Such situation is possible when a common module is added to the configuration with a name that has already been used for the variable. ## Examples diff --git a/docs/en/diagnostics/CommonModuleNameCached.md b/docs/en/diagnostics/CommonModuleNameCached.md index 926110d41a9..3021e3fadf2 100644 --- a/docs/en/diagnostics/CommonModuleNameCached.md +++ b/docs/en/diagnostics/CommonModuleNameCached.md @@ -9,7 +9,7 @@ -Modules intended for implementing functions on the server or client with cached of the returned values (for the time of the call or for the session) are named with the postfix "Cached" and "ClientCached" respectively. +Use the "Cached" and "ClientCached" postfixes for the modules that implement functions with repeated use of return values (upon the call or session time) on the server and on the client respectively. ## Examples diff --git a/docs/en/diagnostics/CommonModuleNameServerCall.md b/docs/en/diagnostics/CommonModuleNameServerCall.md index 707547ca21d..5794cc99d10 100644 --- a/docs/en/diagnostics/CommonModuleNameServerCall.md +++ b/docs/en/diagnostics/CommonModuleNameServerCall.md @@ -9,11 +9,11 @@ -Server common modules for calling from the client code contain server methods available for use from client code. It forms the application server client interface. Such methods are placed in common modules with the attribute: +Common server modules for calling from the client contain server procedures and functions available from the client code. They constitute the client interface of the application server.
Such procedures and functions are placed in common modules with the following property: - Server (ServerCall is enabled) -Server common modules for calling from the client must be named with the postfix "ServerCall" +Name common server modules to be called from the client according to general rules of naming metadata objects. Make sure they include the "ServerCall" postfix ## Examples diff --git a/docs/en/diagnostics/CreateQueryInCycle.md b/docs/en/diagnostics/CreateQueryInCycle.md index 08b99439691..5db70ffcb05 100644 --- a/docs/en/diagnostics/CreateQueryInCycle.md +++ b/docs/en/diagnostics/CreateQueryInCycle.md @@ -14,58 +14,43 @@ Execution query in cycle Bad ```Bsl - -СписокДокументов = Новый Массив; -СуммаДокументов = 0; -Для индекс = 0 По СписокДокументов.ВГраница() Цикл - Запрос = Новый Запрос; - Запрос.Текст = - "ВЫБРАТЬ - | ПоступлениеТоваровУслуг.СуммаДокумента - |ИЗ - | Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг - |ГДЕ - | ПоступлениеТоваровУслуг.Ссылка = &Ссылка"; - - Запрос.УстановитьПараметр("Ссылка", СписокДокументов[индекс]); - - РезультатЗапроса = Запрос.Выполнить(); - - ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать(); - - Пока ВыборкаДетальныеЗаписи.Следующий() Цикл - СуммаДокументов = СуммаДокументов + ВыборкаДетальныеЗаписи.СуммаДокумента; - КонецЦикла; -КонецЦикла; - - +// BanksToProcessing - contains an array of banks + +InidividualQuery = New Query(" + |SELECT + | BankAccounts.Ref AS Account + |FROM + | Catalog.BankAccounts AS BankAccounts + |WHERE + | BankAccounts.Bank = &Bank"); + +For Each Bank From BanksToProcess Do + InidividualQuery .SetParameter("Bank", Bank); + AccountsSelection = InidividualQuery .Execute().Select(); + While AccountsSelection.Next() Do + ProcessBankAccounts(AccountsSelection.Account); + EndDo; +EndDo; ``` Good ```Bsl -СписокДокументов = Новый Массив; -СуммаДокументов = 0; - -Запрос = Новый Запрос; -Запрос.Текст = - "ВЫБРАТЬ - | СУММА(ПоступлениеТоваровУслуг.СуммаДокумента) КАК СуммаДокумента - |ИЗ - | Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг - |ГДЕ - | ПоступлениеТоваровУслуг.Ссылка В(&СписокДокументов)"; - -Запрос.УстановитьПараметр("Ссылка", СписокДокументов); - -РезультатЗапроса = Запрос.Выполнить(); - -ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать(); - -Пока ВыборкаДетальныеЗаписи.Следующий() Цикл - СуммаДокументов = ВыборкаДетальныеЗаписи.СуммаДокумента; -КонецЦикла; - +// BanksToProcess - contains an array of banks + +MergedQuery = New Query(" + |SELECT + | BankAccounts.Ref AS Account + |FROM + | Catalog.BankAccounts AS BankAccounts + |WHERE + | BankAccounts.Bank In(&BanksToProcess)"); + +MergedQuery.SetParameter("BanksToProcess", BanksToProcess); +AccountsSelection = MergedQuery.Execute().Select(); +While AccountsSelection.Next() Do + ProcessBankAccounts(AccountsSelection.Account); +EndDo; ``` ## Snippets diff --git a/docs/en/diagnostics/CyclomaticComplexity.md b/docs/en/diagnostics/CyclomaticComplexity.md index 54cbe4c8821..9338c5d0c5b 100644 --- a/docs/en/diagnostics/CyclomaticComplexity.md +++ b/docs/en/diagnostics/CyclomaticComplexity.md @@ -37,7 +37,41 @@ Cyclomatic complexity increases by 1 for each of following constructions: ```bsl -Функция СерверныйМодульМенеджера(Имя) // 1 ОбъектНайден = Ложь; // 0 // 0 ЧастиИмени = СтрРазделить(Имя, "."); // 0 Если ЧастиИмени.Количество() = 2 Тогда // 1 // 0 ИмяВида = ВРег(ЧастиИмени[0]); // 0 ИмяОбъекта = ЧастиИмени[1]; // 0 // 0 Если ИмяВида = ВРег("Константы") Тогда // 1 Если Метаданные.Константы.Найти(ИмяОбъекта) <> Неопределено Тогда // 1 ОбъектНайден = Истина; // 0 КонецЕсли; // 0 ИначеЕсли ИмяВида = ВРег("РегистрыСведений") Тогда // 1 Если Метаданные.РегистрыСведений.Найти(ИмяОбъекта) <> Неопределено Тогда // 1 ОбъектНайден = Истина; // 0 КонецЕсли; // 0 Иначе // 1 ОбъектНайден = Ложь; // 0 КонецЕсли; // 0 КонецЕсли; // 0 // 0 Если Не ОбъектНайден Тогда // 1 ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( // 0 НСтр("ru = 'Объект метаданных ""%1"" не найден, // 0 |либо для него не поддерживается получение модуля менеджера.'"), // 0 Имя); // 0 КонецЕсли; // 0 УстановитьБезопасныйРежим(Истина); // 0 Модуль = Вычислить(Имя); // 0 F = ?(Условие, ИСТИНА, НЕОПРЕДЕЛЕНО); // 1 А = ?(Условие, ИСТИНА, ?(Условие2, ЛОЖЬ, НЕОПРЕДЕЛЕНО)); // 2 M = ИСТИНА ИЛИ 7; // 1 Возврат Модуль; // 0 КонецФункции // итог 12 +Function ServerModuleManager(Name) // 1 + ObjectFounded = False; // 0 + // 0 + NameParts = StrSplit(Name, "."); // 0 + If NameParts.Count() = 2 Then // 1 + // 0 + TypeName = Upper(NameParts[0]); // 0 + ObjectName = NameParts[1]; // 0 + // 0 + If TypeName = Upper("Constants") Then // 1 + If Metadata.Constants.Find(ObjectName) <> Undefined Then // 1 + ObjectFounded = True; // 0 + EndIf; // 0 + ElsIf TypeName = Upper("InformationRegisters") Then // 1 + If Metadata.InformationRegisters.Find(ObjectName) <> Undefined Then // 1 + ObjectFounded = True; // 0 + EndIf; // 0 + Else // 1 + ObjectFounded = False; // 0 + EndIf; // 0 + EndIf; // 0 + // 0 + If Not ObjectFounded Then // 1 + Raise СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( // 0 + НСтр("ru = 'Объект метаданных ""%1"" не найден, // 0 + |либо для него не поддерживается получение модуля менеджера.'"), // 0 + Name); // 0 + EndIf; // 0 + SetSafeMode(True); // 0 + Module = Eval(Name); // 0 + F = ?(SomeCondition1, True, Undefined); // 1 + А = ?(SomeCondition1, True, ?(SomeCondition2, False, Undefined)); // 2 + M = True Or 7; // 1 + Return Module; // 0 +EndFunction // Total 12 ``` ## Sources diff --git a/docs/en/diagnostics/DeprecatedAttributes8312.md b/docs/en/diagnostics/DeprecatedAttributes8312.md index fc2661e47cf..7889f5c0600 100644 --- a/docs/en/diagnostics/DeprecatedAttributes8312.md +++ b/docs/en/diagnostics/DeprecatedAttributes8312.md @@ -11,7 +11,7 @@ The following items are deprecated and their use is not recommended since platform version 8.3.12: -- Implemented the new AlwaysHorizontal value of the ChildFormItemsGroup system enum. The Horizontal value of the ChildFormItemsGroup system enum is deprecated; +- Implemented the new AlwaysHorizontal value of the ChildFormItemsGroup system enum.
The Horizontal value of the ChildFormItemsGroup system enum is deprecated - ChartLabelsOrientation system enum is no longer available. Actual variant is ChartLabelsOrientation; @@ -43,7 +43,7 @@ The following items are deprecated and their use is not recommended since platfo - Property ShowTitle of Chart, GanttChart, PivotChart objects are obsolete and not recomended for use. -- The global context method ClearEventLog() is applicable only to a event log in SQLite format, is obsolete and its use is not recommended. +- Global context method ClearEventLog() is deprecated and only applicable to logs that have SQLite format. It is recommended that you do not use this method. ## Sources diff --git a/docs/en/diagnostics/DeprecatedFind.md b/docs/en/diagnostics/DeprecatedFind.md index 1672d5064d7..f750c3b039e 100644 --- a/docs/en/diagnostics/DeprecatedFind.md +++ b/docs/en/diagnostics/DeprecatedFind.md @@ -14,16 +14,18 @@ Method "Find" is deprecated. Use "StrFind" instead. Incorrect: ```bsl -If Find(Collaborator.Name, "Boris") > 0 Then - + +If Find(Employee.Name, "Boris") > 0 Then + EndIf; ``` Correct: ```bsl -If StrFind(Collaborator.Name, "Boris") > 0 Then - + +If StrFind(Employee.Name, "Boris") > 0 Then + EndIf; ``` diff --git a/docs/en/diagnostics/DeprecatedMethodCall.md b/docs/en/diagnostics/DeprecatedMethodCall.md index 5e222930a55..ce35463a072 100644 --- a/docs/en/diagnostics/DeprecatedMethodCall.md +++ b/docs/en/diagnostics/DeprecatedMethodCall.md @@ -7,6 +7,8 @@ ## Description +If you need to mark a procedure or function as deprecated, start its description with "Deprecated" at the top. + Use or extension of deprecated methods should be avoided. Marking method as deprecated is a warning that means the method will be removed in future versions and left for temporary backward compatibility. Exception: It is possible to call deprecated methods from deprecated methods. @@ -16,7 +18,7 @@ Exception: It is possible to call deprecated methods from deprecated methods. ```bsl -// Deprecated. Need to use DontDeprecatedProcedure. +// Deprecated. Need to use NotDeprecatedProcedure. Procedure DeprecatedProcedure() EndProcedure diff --git a/docs/en/diagnostics/DeprecatedMethods8310.md b/docs/en/diagnostics/DeprecatedMethods8310.md index 3762a8dcb5f..5971bd01ac6 100644 --- a/docs/en/diagnostics/DeprecatedMethods8310.md +++ b/docs/en/diagnostics/DeprecatedMethods8310.md @@ -6,18 +6,22 @@ ## Description + -The following global context methods are deprecated and are not recommended -since platform version 8.3.10: + +The following global context methods are deprecated and are not recommended since platform version 8.3.10: + ``` SetShortApplicationCaption(); GetShortApplicationCaption(); SetClientApplicationCaption(); GetClientApplicationCaption(); ClientApplicationBaseFontCurrentVariant(); -ClientApplicationInterfaceCurrentVariant(). +ClientApplicationInterfaceCurrentVariant(); ``` + ## Sources + Source: [Version 8.3.10 changelog](https://dl03.1c.ru/content/Platform/8_3_10_2699/1cv8upd.htm) diff --git a/docs/en/diagnostics/ExecuteExternalCode.md b/docs/en/diagnostics/ExecuteExternalCode.md index 42e76ea6ce4..69e521326b7 100644 --- a/docs/en/diagnostics/ExecuteExternalCode.md +++ b/docs/en/diagnostics/ExecuteExternalCode.md @@ -9,10 +9,9 @@ -It is dangerous to use not only direct execution of code written in the Enterprise mode, but also algorithms where `Execute` or `Eval` code executes the code in server methods. -It is forbidden to use the methods `Execute ` and `Eval` in server methods of modules: forms, commands, objects, etc. +When you develop applications, note that not only execution of a code written in the Enterprise mode is unsafe, but also places, where the `Execute` or `Eval` methods are used to execute the code created based on parameters passed to server functions and procedures. -**The restriction does not apply to code executed on the client.** +**This restriction is not applicable to the code being executed on the client** ## Examples diff --git a/docs/en/diagnostics/ExecuteExternalCodeInCommonModule.md b/docs/en/diagnostics/ExecuteExternalCodeInCommonModule.md index 5eba045a3cd..ba220f844de 100644 --- a/docs/en/diagnostics/ExecuteExternalCodeInCommonModule.md +++ b/docs/en/diagnostics/ExecuteExternalCodeInCommonModule.md @@ -9,10 +9,9 @@ -It is dangerous to use not only direct execution of code written in the Enterprise mode, but also algorithms where `Execute` or `Eval` code executes the code in server methods. -If it is necessary to execute external code, then it must be located in a common module and pass an audit in advance. +When you develop applications, note that not only execution of a code written in the Enterprise mode is unsafe, but also places, where the `Execute` or `Eval` methods are used to execute the code created based on parameters passed to server functions and procedures.
If the execution of arbitrary code Is necessary then it has to be preliminarily checked -**The restriction does not apply to code executed on the client.** +**This restriction is not applicable to the code being executed on the client.** ## Examples diff --git a/docs/en/diagnostics/FormDataToValue.md b/docs/en/diagnostics/FormDataToValue.md index a876e76adad..7411bcff8fb 100644 --- a/docs/en/diagnostics/FormDataToValue.md +++ b/docs/en/diagnostics/FormDataToValue.md @@ -6,21 +6,29 @@ ## Description + + In most cases, you should use the FormAttributeToValue method, instead of the FormDataToValue. The recommendation is due to considerations of unification of the application code and the fact that the syntax of the FormAttributeToValue is simpler than FormDataToValue. + ## Examples + + ``` -Procedure Test2() - FormDataToValue(Object, Type("ValueTable")); +Procedure Test() + Form=Doc.GetForm("DocumentForm"); + FD = Form.FormDataToValue(Object, Type("ValueTable")); EndProcedure ``` + ## Sources + -Source: [Using of FormAttributeToValue method](https://its.1c.ru/db/v8std#content:409:hdoc) +Source: [Using of FormAttributeToValue and FormDataToValue methods](https://its.1c.ru/db/v8std#content:409:hdoc) ## Snippets diff --git a/docs/en/diagnostics/FunctionOutParameter.md b/docs/en/diagnostics/FunctionOutParameter.md new file mode 100644 index 00000000000..f2ccee293e1 --- /dev/null +++ b/docs/en/diagnostics/FunctionOutParameter.md @@ -0,0 +1,58 @@ +# Out function parameter (FunctionOutParameter) + + Type | Scope | Severity | Activated
by default | Minutes
to fix | Tags + :-: | :-: | :-: | :-: | :-: | :-: + `Code smell` | `BSL`
`OS` | `Major` | `No` | `10` | `design` + + +## Description + + + +The function must have no output parameters. All output must be in the return value. If you need to return multiple values, you should use such types as Structure, Array, etc. + +## Examples + + + +```bsl +// Wrong: +ServiceURL = ""; +UserName = ""; +UserPassword = ""; + +FillConnectionParameters(ServiceURL, UserName, UserPassword); + +// Correctly: +ConnectionParameters = NewConnectionParameters(); +// Returned value - Structure: +// Service URL - String +// UserName - String +// UserPassword - String +``` + +## Sources + + + + + +## Snippets + + +### Diagnostic ignorance in code + +```bsl +// BSLLS:FunctionOutParameter-off +// BSLLS:FunctionOutParameter-on +``` + +### Parameter for config + +```json +"FunctionOutParameter": false +``` diff --git a/docs/en/diagnostics/GetFormMethod.md b/docs/en/diagnostics/GetFormMethod.md index 8d65d3e0f23..3cb2c5d2825 100644 --- a/docs/en/diagnostics/GetFormMethod.md +++ b/docs/en/diagnostics/GetFormMethod.md @@ -6,23 +6,30 @@ ## Description + -To open forms, use the OpenForm global context method (when using the 1C: Enterprise 8.2 platform version and earlier versions, also use OpenFormModal). -An alternative method, using the GetForm method, is not recommended. + +To open forms, use the OpenForm global context method (when using the 1C: Enterprise 8.2 platform version and earlier versions, also use OpenFormModal). An alternative method, using the GetForm method, is not recommended. + ## Examples + + ``` Procedure Test() Doc = Documents.PlanOperation.CreateDocument(); Form = Doc.GetForm("DocumentForm"); // here EndProcedure ``` + ``` Procedure Test2() - Form = GetForm("Document.PlanOperation.Form"); // here + Form = GetForm("CommonForms.MyForm"); EndProcedure ``` + ## Sources + Source: [Standard](https://its.1c.ru/db/v8std/content/404/hdoc) diff --git a/docs/en/diagnostics/GlobalContextMethodCollision8312.md b/docs/en/diagnostics/GlobalContextMethodCollision8312.md new file mode 100644 index 00000000000..ded72b3ff6b --- /dev/null +++ b/docs/en/diagnostics/GlobalContextMethodCollision8312.md @@ -0,0 +1,36 @@ +# Global context method names collision (GlobalContextMethodCollision8312) + + Type | Scope | Severity | Activated
by default | Minutes
to fix | Tags + :-: | :-: | :-: | :-: | :-: | :-: + `Error` | `BSL`
`OS` | `Blocker` | `Yes` | `10` | `error`
`unpredictable` + + +## Description + + +## Examples + + +## Sources + + + +## Snippets + + +### Diagnostic ignorance in code + +```bsl +// BSLLS:GlobalContextMethodCollision8312-off +// BSLLS:GlobalContextMethodCollision8312-on +``` + +### Parameter for config + +```json +"GlobalContextMethodCollision8312": false +``` diff --git a/docs/en/diagnostics/LatinAndCyrillicSymbolInWord.md b/docs/en/diagnostics/LatinAndCyrillicSymbolInWord.md new file mode 100644 index 00000000000..9b006e549e7 --- /dev/null +++ b/docs/en/diagnostics/LatinAndCyrillicSymbolInWord.md @@ -0,0 +1,50 @@ +# Mixing Latin and Cyrillic characters in one identifier (LatinAndCyrillicSymbolInWord) + + Type | Scope | Severity | Activated
by default | Minutes
to fix | Tags + :-: | :-: | :-: | :-: | :-: | :-: + `Code smell` | `BSL`
`OS` | `Minor` | `Yes` | `5` | `brainoverload`
`suspicious` + +## Parameters + + Name | Type | Description | Default value + :-: | :-: | :-- | :-: + `excludeWords` | `String` | ```A list of exclusion words, specified as a comma-separated string``` | ```ЧтениеXML, ЧтениеJSON, ЗаписьXML, ЗаписьJSON, ComОбъект, ФабрикаXDTO, ОбъектXDTO, СоединениеFTP, HTTPСоединение, HTTPЗапрос, HTTPСервисОтвет, SMSСообщение, WSПрокси``` + + +## Description + + + +Do not use identifiers consisting of characters from different languages, вecause it makes it difficult to use them further, forcing to switch the layout.
Also, the diagnostics detects the erroneous use of characters from another language, when it was used unintentionally. For exaple: `o`, `c`, `B`, `p` and etc. + +## Examples + + + +## Sources + + + + + +## Snippets + + +### Diagnostic ignorance in code + +```bsl +// BSLLS:LatinAndCyrillicSymbolInWord-off +// BSLLS:LatinAndCyrillicSymbolInWord-on +``` + +### Parameter for config + +```json +"LatinAndCyrillicSymbolInWord": { + "excludeWords": "ЧтениеXML, ЧтениеJSON, ЗаписьXML, ЗаписьJSON, ComОбъект, ФабрикаXDTO, ОбъектXDTO, СоединениеFTP, HTTPСоединение, HTTPЗапрос, HTTPСервисОтвет, SMSСообщение, WSПрокси" +} +``` diff --git a/docs/en/diagnostics/MagicDate.md b/docs/en/diagnostics/MagicDate.md new file mode 100644 index 00000000000..fc93a5d9b59 --- /dev/null +++ b/docs/en/diagnostics/MagicDate.md @@ -0,0 +1,52 @@ +# Magic dates (MagicDate) + + Type | Scope | Severity | Activated
by default | Minutes
to fix | Tags + :-: | :-: | :-: | :-: | :-: | :-: + `Code smell` | `BSL`
`OS` | `Minor` | `Yes` | `5` | `badpractice`
`brainoverload` + +## Parameters + + Name | Type | Description | Default value + :-: | :-: | :-- | :-: + `authorizedDates` | `String` | ```Allowed dates, comma separated. Example: 00010101,00010101000000,000101010000``` | ```00010101,00010101000000,000101010000``` + + +## Description +Magic date is any date in your code that does not immediately become apparent without being immersed in context. + +## Examples + +Bad + +```bsl +If now < '20151021' Then + HoverBoardIsReal = Undefined; +EndIf; +``` + +Good + +```bsl +PredictedDate = '20151021'; +If now < PredictedDate Then + HoverBoardIsReal = Undefined; +EndIf; +``` + +## Snippets + + +### Diagnostic ignorance in code + +```bsl +// BSLLS:MagicDate-off +// BSLLS:MagicDate-on +``` + +### Parameter for config + +```json +"MagicDate": { + "authorizedDates": "00010101,00010101000000,000101010000" +} +``` diff --git a/docs/en/diagnostics/MissingEventSubscriptionHandler.md b/docs/en/diagnostics/MissingEventSubscriptionHandler.md new file mode 100644 index 00000000000..9fc0534b374 --- /dev/null +++ b/docs/en/diagnostics/MissingEventSubscriptionHandler.md @@ -0,0 +1,44 @@ +# Event subscription handler missing (MissingEventSubscriptionHandler) + + Type | Scope | Severity | Activated
by default | Minutes
to fix | Tags + :-: | :-: | :-: | :-: | :-: | :-: + `Error` | `BSL` | `Blocker` | `Yes` | `5` | `error` + + +## Description + + + +If the handler for the "event subscription" is not filled or does not exist, then an error will occur in the application. + +**Note: Diagnostics attaches notes to the "session module".** + +## Examples + + + +## Sources + + + + + +## Snippets + + +### Diagnostic ignorance in code + +```bsl +// BSLLS:MissingEventSubscriptionHandler-off +// BSLLS:MissingEventSubscriptionHandler-on +``` + +### Parameter for config + +```json +"MissingEventSubscriptionHandler": false +``` diff --git a/docs/en/diagnostics/MissingParameterDescription.md b/docs/en/diagnostics/MissingParameterDescription.md new file mode 100644 index 00000000000..8216cd3c405 --- /dev/null +++ b/docs/en/diagnostics/MissingParameterDescription.md @@ -0,0 +1,53 @@ +# Method parameters description are missing (MissingParameterDescription) + + Type | Scope | Severity | Activated
by default | Minutes
to fix | Tags + :-: | :-: | :-: | :-: | :-: | :-: + `Code smell` | `BSL`
`OS` | `Major` | `Yes` | `5` | `standard`
`badpractice` + + +## Description + + + +The description of a method (procedure or function) should be formatted correctly to help programmers use the functionality correctly. + +If a method contains parameters, then in its description, in the block of the same name, descriptions for all parameters must be given in the same order as in the method signature. + +Diagnostic detects typical errors: + +- Lack of description of all parameters +- Absence of a description of some of the parameters, indicating for which parameter the description was not found +- The presence in the description of parameters that are absent in the method signature (which could remain from refactoring) +- Poor parameter description: when the parameter name is present in the method description, but the parameter type and type description are not specified + +## Examples + + + +## Sources + + + + + +- [Standart: Procedures and functions description](https://its.1c.ru/db/v8std#content:453:hdoc) + +## Snippets + + +### Diagnostic ignorance in code + +```bsl +// BSLLS:MissingParameterDescription-off +// BSLLS:MissingParameterDescription-on +``` + +### Parameter for config + +```json +"MissingParameterDescription": false +``` diff --git a/docs/en/diagnostics/MissingReturnedValueDescription.md b/docs/en/diagnostics/MissingReturnedValueDescription.md new file mode 100644 index 00000000000..9dae7e3ac06 --- /dev/null +++ b/docs/en/diagnostics/MissingReturnedValueDescription.md @@ -0,0 +1,52 @@ +# Function returned values description is missing (MissingReturnedValueDescription) + + Type | Scope | Severity | Activated
by default | Minutes
to fix | Tags + :-: | :-: | :-: | :-: | :-: | :-: + `Code smell` | `BSL`
`OS` | `Major` | `Yes` | `5` | `standard`
`badpractice` + + +## Description + + + +The description of a method (procedure or function) should be formatted correctly to help programmers use the functionality correctly. + +The function description must contain a description of the return value in the block of the same name. You must provide a description for all possible return types. + +Diagnostics detects typical errors: + +- No return value description +- Return value description for procedure +- Poor description of the return value: when the type name is present in the description, but its description is not specified + +## Examples + + + +## Sources + + + + + +- [Standart: Procedures and functions description](https://its.1c.ru/db/v8std#content:453:hdoc) + +## Snippets + + +### Diagnostic ignorance in code + +```bsl +// BSLLS:MissingReturnedValueDescription-off +// BSLLS:MissingReturnedValueDescription-on +``` + +### Parameter for config + +```json +"MissingReturnedValueDescription": false +``` diff --git a/docs/en/diagnostics/MissingSpace.md b/docs/en/diagnostics/MissingSpace.md index 4e991530fcc..485a40802fe 100644 --- a/docs/en/diagnostics/MissingSpace.md +++ b/docs/en/diagnostics/MissingSpace.md @@ -1,4 +1,4 @@ -# Missing spaces to the left or right of operators + - * / = % < > <> <= >=, and also to the right of , and ; (MissingSpace) +# Missing spaces to the left or right of operators + - * / = % < > <> <= >=, keywords, and also to the right of , and ; (MissingSpace) Type | Scope | Severity | Activated
by default | Minutes
to fix | Tags :-: | :-: | :-: | :-: | :-: | :-: @@ -8,9 +8,9 @@ Name | Type | Description | Default value :-: | :-: | :-- | :-: - `listForCheckLeft` | `String` | ```List of symbols to check for the space to the left of (separated by space)``` | `````` - `listForCheckRight` | `String` | ```List of symbols to check for the space to the right of (separated by space)``` | ```, ;``` - `listForCheckLeftAndRight` | `String` | ```List of symbols to check for the space from both sides of (separated by space)``` | ```+ - * / = % < > <> <= >=``` + `listForCheckLeft` | `String` | ```List to check for the space to the left of (separated by space)``` | `````` + `listForCheckRight` | `String` | ```List to check for the space to the right of (separated by space)``` | ```, ;``` + `listForCheckLeftAndRight` | `String` | ```List to check for the space from both sides of (separated by space)``` | ```+ - * / = % < > <> <= >=``` `checkSpaceToRightOfUnary` | `Boolean` | ```Check for space to the right of unary signs (+ -)``` | ```false``` `allowMultipleCommas` | `Boolean` | ```Allow several commas in a row``` | ```false``` @@ -66,8 +66,8 @@ The parameter has sense only if `,` is listed in one of three base parameters If set to `false` ```bsl -CommonModuleClientServer.MessageToUser(MessageText,,,, Cancel); // Incorrect -CommonModuleClientServer.MessageToUser(MessageText, , , , Cancel); // Correct + CommonModuleClientServer.MessageToUser(MessageText,,,, Cancel); // Bad + CommonModuleClientServer.MessageToUser(MessageText, , , , Cancel); // Correct ``` If set to `true` diff --git a/docs/en/diagnostics/NestedFunctionInParameters.md b/docs/en/diagnostics/NestedFunctionInParameters.md index 649b32b165e..c7fa5c272bc 100644 --- a/docs/en/diagnostics/NestedFunctionInParameters.md +++ b/docs/en/diagnostics/NestedFunctionInParameters.md @@ -2,7 +2,7 @@ Type | Scope | Severity | Activated
by default | Minutes
to fix | Tags :-: | :-: | :-: | :-: | :-: | :-: - `Code smell` | `BSL`
`OS` | `Minor` | `Yes` | `5` | `standard`
`brainoverload`
`badpractice` + `Code smell` | `BSL`
`OS` | `Minor` | `Yes` | `2` | `standard`
`brainoverload`
`badpractice` ## Description diff --git a/docs/en/diagnostics/NestedStatements.md b/docs/en/diagnostics/NestedStatements.md index d08070f2d9b..2be225e5ef1 100644 --- a/docs/en/diagnostics/NestedStatements.md +++ b/docs/en/diagnostics/NestedStatements.md @@ -13,7 +13,7 @@ ## Description -Nested operators "If", "For", "ForEach", "While" and "Try" are key ingredients for so called "spaghetti-code". +Nested "If, "For", "For Each", "While" and "Try" operators are the key ingredients for creating so-called "spaghetti code" Such code is hard for reading, refactoring and support. diff --git a/docs/en/diagnostics/NumberOfOptionalParams.md b/docs/en/diagnostics/NumberOfOptionalParams.md index d1350a25ef5..e0f5687d9bf 100644 --- a/docs/en/diagnostics/NumberOfOptionalParams.md +++ b/docs/en/diagnostics/NumberOfOptionalParams.md @@ -38,7 +38,7 @@ EndProcedure ## Sources -- [](https://its.1c.ru/db/v8std#content:640:hdoc)[Стандарт: Параметры процедур и функций](https://its.1c.ru/db/v8std#content:640:hdoc) +- [Стандарт: Параметры процедур и функций](https://its.1c.ru/db/v8std#content:640:hdoc) ## Snippets diff --git a/docs/en/diagnostics/OrdinaryAppSupport.md b/docs/en/diagnostics/OrdinaryAppSupport.md new file mode 100644 index 00000000000..c32a191a8ca --- /dev/null +++ b/docs/en/diagnostics/OrdinaryAppSupport.md @@ -0,0 +1,48 @@ +# Ordinary application support (OrdinaryAppSupport) + + Type | Scope | Severity | Activated
by default | Minutes
to fix | Tags + :-: | :-: | :-: | :-: | :-: | :-: + `Code smell` | `BSL` | `Major` | `Yes` | `1` | `standard`
`unpredictable` + + +## Description + + + +To maintain backward compatibility with various proprietary and third-party solutions, external processes and reports developed on previous versions of the 1C: Enterprise platform 8.0 and 8.1, the configuration should also support launching in regular application (thick client) and external connection modes for administrators (users with full rights). + +For this it is recommended: + +- The configuration property "Use managed forms in a ordinary application" is set to True. +- Set the property "Use ordinary forms in managed mode" to False. +- adhere to the general scheme for setting the attributes of common modules, and conduct the development itself in the Designer in edit mode for both launch modes - managed and ordinary applications (Service menu - Options - General tab). + +When developing in EDT, properties are set through the Designer. + +The refusal to support the launch of configuration in the ordinary application and external connection modes for administrators is possible only in certain justified cases. + +## Examples + + + +## Sources + + + +- Source: [Standard: General Configuration Requirements](https://its.1c.ru/db/v8std#content:467:hdoc) + +## Snippets + + +### Diagnostic ignorance in code + +```bsl +// BSLLS:OrdinaryAppSupport-off +// BSLLS:OrdinaryAppSupport-on +``` + +### Parameter for config + +```json +"OrdinaryAppSupport": false +``` diff --git a/docs/en/diagnostics/RedundantAccessToObject.md b/docs/en/diagnostics/RedundantAccessToObject.md new file mode 100644 index 00000000000..27209010e1c --- /dev/null +++ b/docs/en/diagnostics/RedundantAccessToObject.md @@ -0,0 +1,48 @@ +# Redundant access to an object (RedundantAccessToObject) + + Type | Scope | Severity | Activated
by default | Minutes
to fix | Tags + :-: | :-: | :-: | :-: | :-: | :-: + `Code smell` | `BSL` | `Info` | `Yes` | `1` | `standard`
`clumsy` + +## Parameters + + Name | Type | Description | Default value + :-: | :-: | :-- | :-: + `checkObjectModule` | `Boolean` | ```Check object modules``` | ```true``` + `checkFormModule` | `Boolean` | ```Check form modules``` | ```true``` + `checkRecordSetModule` | `Boolean` | ```Check record set modules``` | ```true``` + + +## Description + + +## Examples + + +## Sources + + + +## Snippets + + +### Diagnostic ignorance in code + +```bsl +// BSLLS:RedundantAccessToObject-off +// BSLLS:RedundantAccessToObject-on +``` + +### Parameter for config + +```json +"RedundantAccessToObject": { + "checkObjectModule": true, + "checkFormModule": true, + "checkRecordSetModule": true +} +``` diff --git a/docs/en/diagnostics/RefOveruse.md b/docs/en/diagnostics/RefOveruse.md new file mode 100644 index 00000000000..100ff13910d --- /dev/null +++ b/docs/en/diagnostics/RefOveruse.md @@ -0,0 +1,51 @@ +# Overuse "Reference" in a query (RefOveruse) + + Type | Scope | Severity | Activated
by default | Minutes
to fix | Tags + :-: | :-: | :-: | :-: | :-: | :-: + `Code smell` | `BSL` | `Major` | `Yes` | `5` | `sql`
`performance` + + +## Description + + + +Using ".Ref" to a field of a reference type will result in an implicit left join with the source table of this field, and it has no value, but only generates excessive load on the DBMS. + +## Examples + + + +``` +Query.Text = "Select Files.File.Ref, // error + | Files.File + | From + | InternalFiles AS Files"; +``` + +## Sources + + + + + +- Useful Information: [Dereferencing Complex Type Reference Fields in Query Language](https://its.1c.ru/db/v8std/content/654/hdoc) + +## Snippets + + +### Diagnostic ignorance in code + +```bsl +// BSLLS:RefOveruse-off +// BSLLS:RefOveruse-on +``` + +### Parameter for config + +```json +"RefOveruse": false +``` diff --git a/docs/en/diagnostics/StyleElementConstructors.md b/docs/en/diagnostics/StyleElementConstructors.md index 740a210c26a..e56f6dc5605 100644 --- a/docs/en/diagnostics/StyleElementConstructors.md +++ b/docs/en/diagnostics/StyleElementConstructors.md @@ -6,18 +6,24 @@ ## Description - + +You should use style elements to change the appearance, rather than setting specific values directly in the controls. This is required in order for similar controls to look the same in all forms where they occur. + +Types of style elements: + +- Color (set to RGB value) +- Font (type, size and style are set) +- Frame (set the type and width of the borders) ## Examples + ## Sources - - +System of standards + +- Source: [Standard: Style Elements](https://its.1c.ru/db/v8std#content:667:hdoc) ## Snippets diff --git a/docs/en/diagnostics/ThisObjectAssign.md b/docs/en/diagnostics/ThisObjectAssign.md index 05b82feb742..8a8853d5156 100644 --- a/docs/en/diagnostics/ThisObjectAssign.md +++ b/docs/en/diagnostics/ThisObjectAssign.md @@ -13,9 +13,10 @@ Often this error appears when updating the platform version: the "ThisObject" pr ## Examples -Wrong: +Incorrect: ```bsl + ThisObject = FormAttributeToValue("Object"); ``` diff --git a/docs/en/diagnostics/TimeoutsInExternalResources.md b/docs/en/diagnostics/TimeoutsInExternalResources.md index 0341abbd029..c5709b98a4e 100644 --- a/docs/en/diagnostics/TimeoutsInExternalResources.md +++ b/docs/en/diagnostics/TimeoutsInExternalResources.md @@ -52,8 +52,8 @@ HTTPConnection.Timeout = 1; ## Reference -- [](https://its.1c.ru/db/v8std#content:748:hdoc)[Timeouts when working with external resources](https://its.1c.ru/db/v8std#content:748:hdoc) -- [](https://its.1c.ru/db/metod8dev/content/2358/hdoc)[InternetMail Profilehas a default timeout](https://its.1c.ru/db/metod8dev/content/2358/hdoc) +- [Timeouts when working with external resources](https://its.1c.ru/db/v8std#content:748:hdoc) +- [InternetMail Profilehas a default timeout](https://its.1c.ru/db/metod8dev/content/2358/hdoc) ## Snippets diff --git a/docs/en/diagnostics/TooManyReturns.md b/docs/en/diagnostics/TooManyReturns.md index 4ba76111bd4..f8e1a956e4e 100644 --- a/docs/en/diagnostics/TooManyReturns.md +++ b/docs/en/diagnostics/TooManyReturns.md @@ -24,7 +24,21 @@ A large number of returns in a method (procedure or function) increases its comp Bad method example ```bsl -Function Example(Condition) If Condition = 1 Then Return "Check passed"; ElsIf Condition = 2 Then ExecuteSomething(); Return "Check not passed"; ElsIf Condition > 7 Then Если Validate(Contidtion) Then Return "Check passed"; Else Return "Check not passed"; EndIf; EndIf; Return ""; EndFunction +Function Example(Condition) + If Condition = 1 Then + Return "Check passed"; + ElsIf Condition = 2 Then + ExecuteSomething(); + Return "Check not passed"; + ElsIf Condition > 7 Then + Если Validate(Contidtion) Then + Return "Check passed"; + Else + Return "Check not passed"; + EndIf; + EndIf; + Return ""; +EndFunction ``` ## Sources diff --git a/docs/en/diagnostics/Typo.md b/docs/en/diagnostics/Typo.md index e1ab947d9fa..a3d3a25d2eb 100644 --- a/docs/en/diagnostics/Typo.md +++ b/docs/en/diagnostics/Typo.md @@ -9,7 +9,7 @@ Name | Type | Description | Default value :-: | :-: | :-- | :-: `minWordLength` | `Integer` | ```Minimum length for checked words``` | ```3``` - `userWordsToIgnore` | `String` | ```Dictionary for excluding words (comma separated, without spaces)``` | `````` + `userWordsToIgnore` | `String` | ```Dictionary for excluding words (comma separated)``` | `````` ## Description diff --git a/docs/en/diagnostics/UnionAll.md b/docs/en/diagnostics/UnionAll.md index 520849b394d..425897d43de 100644 --- a/docs/en/diagnostics/UnionAll.md +++ b/docs/en/diagnostics/UnionAll.md @@ -6,18 +6,48 @@ ## Description - + +In most cases, when you need to combine the results of two or more queries into a single result set, employ UNION ALL clause instead of UNION. The recommendation is based on the algorithm of the UNION clause, which searches for and removes duplicates from the united result even when duplicates are impossible by the query design. + +Employ UNION only when removing duplicates from the result is required. ## Examples - + +Incorrect: + +```bsl +SELECT +GoodsReceipt.Ref +FROM +Document.GoodsReceipt AS GoodsReceipt + +UNION + +SELECT +GoodsSale.Ref +FROM +Document.GoodsSale AS GoodsSale +``` + +Correct: + +```bsl +SELECT +GoodsReceipt.Ref +FROM +Document.GoodsReceipt AS GoodsReceipt + +UNION ALL + +SELECT +GoodsSale.Ref +FROM +Document.GoodsSale AS GoodsSale +``` ## Sources - - +- Link: [Development Standart: Using UNION and UNION ALL words in queries](https://its.1c.ru/db/v8std#content:434:hdoc) ## Snippets diff --git a/docs/en/diagnostics/UnsafeSafeModeMethodCall.md b/docs/en/diagnostics/UnsafeSafeModeMethodCall.md index b71a496f1a3..fd352602878 100644 --- a/docs/en/diagnostics/UnsafeSafeModeMethodCall.md +++ b/docs/en/diagnostics/UnsafeSafeModeMethodCall.md @@ -20,14 +20,20 @@ Using the Safe Mode () method, in which the result is implicitly converted to a Wrong: ``` -If SafeMode() Then // some code EndIf; +If SafeMode() Then + // some logic in safe mode... +EndIf; + +If No SafeMode() Then + // some logic in unsafe mode... +EndIf; ``` Correct: ``` If SafeMode() <> False Then -// some code + // some code EndIf; ``` diff --git a/docs/en/diagnostics/UnusedLocalMethod.md b/docs/en/diagnostics/UnusedLocalMethod.md index 7f7a41c148d..763263ef3ba 100644 --- a/docs/en/diagnostics/UnusedLocalMethod.md +++ b/docs/en/diagnostics/UnusedLocalMethod.md @@ -2,7 +2,7 @@ Type | Scope | Severity | Activated
by default | Minutes
to fix | Tags :-: | :-: | :-: | :-: | :-: | :-: - `Code smell` | `BSL`
`OS` | `Major` | `Yes` | `1` | `standard`
`suspicious` + `Code smell` | `BSL`
`OS` | `Major` | `Yes` | `1` | `standard`
`suspicious`
`unused` ## Description diff --git a/docs/en/diagnostics/UnusedParameters.md b/docs/en/diagnostics/UnusedParameters.md index 10d06a66aab..320f8eee42c 100644 --- a/docs/en/diagnostics/UnusedParameters.md +++ b/docs/en/diagnostics/UnusedParameters.md @@ -2,7 +2,7 @@ Type | Scope | Severity | Activated
by default | Minutes
to fix | Tags :-: | :-: | :-: | :-: | :-: | :-: - `Code smell` | `OS` | `Major` | `Yes` | `5` | `design` + `Code smell` | `OS` | `Major` | `Yes` | `5` | `design`
`unused` ## Description diff --git a/docs/en/diagnostics/UseLessForEach.md b/docs/en/diagnostics/UseLessForEach.md index 62f6e328872..4bc92ef7510 100644 --- a/docs/en/diagnostics/UseLessForEach.md +++ b/docs/en/diagnostics/UseLessForEach.md @@ -7,7 +7,7 @@ ## Description -Absence of iterator in the loop body indicates to useless collection iteration or to the error in the loop body. +The absence of an iterator in the loop body indicates either a useless iteration of the collection or an error in the loop body. ## Examples diff --git a/docs/en/diagnostics/UsingGoto.md b/docs/en/diagnostics/UsingGoto.md index 36077376874..46d5acac169 100644 --- a/docs/en/diagnostics/UsingGoto.md +++ b/docs/en/diagnostics/UsingGoto.md @@ -7,8 +7,7 @@ ## Description -`goto` is an unstructured control flow statement. It makes code less readable and maintainable. - Structured control flow statements such as `if`, `for`, `while`, `continue` or `break` should be used instead. +`goto` is an unstructured control flow statement. It makes code less readable and maintainable. Structured control flow statements such as `if`, `for`, `while`, `continue` or `break` should be used instead. ## Examples @@ -29,17 +28,18 @@ i = 0; Good ```bsl -For i = 0 to 10 Do - - Message("i = " + i); - +For Counter = 0 To 10 Do + + Message(StrTemplate("Counter = %1", Counter)) + EndDo; ``` ## Sources + -* Source: [Standard: Using goto (RU)](https://its.1c.ru/db/v8std/content/547/hdoc/_top/) +- Source: [Standard: Using goto (RU)](https://its.1c.ru/db/v8std/content/547/hdoc/_top/) ## Snippets diff --git a/docs/en/diagnostics/UsingModalWindows.md b/docs/en/diagnostics/UsingModalWindows.md index d43e3c9b0a8..40a7201c7fd 100644 --- a/docs/en/diagnostics/UsingModalWindows.md +++ b/docs/en/diagnostics/UsingModalWindows.md @@ -4,6 +4,12 @@ :-: | :-: | :-: | :-: | :-: | :-: `Code smell` | `BSL` | `Major` | `Yes` | `15` | `standard` +## Parameters + + Name | Type | Description | Default value + :-: | :-: | :-- | :-: + `forceModalityMode` | `Boolean` | ```Ignore configurations modality mode``` | ```false``` + ## Description @@ -33,11 +39,11 @@ Russian variant | English variant ## Examples ```bsl -// Example "Incorrect" -warning(NStr("ru = 'Выберите документ!'; en = 'Select a document!'"), 10); +// Incorrect +DoMessageBox(NStr("ru = 'Выберите документ!'; en = 'Select a document!'"), 10); -// Example "Correct" -ShowWarning(, NStr("ru = 'Выберите документ!'; en = 'Select a document!'"), 10); +// Correct +ShowMessageBox(, NStr("ru = 'Выберите документ!'; en = 'Select a document!'"), 10); ``` ## Sources @@ -58,5 +64,7 @@ ShowWarning(, NStr("ru = 'Выберите документ!'; en = 'Select a do ### Parameter for config ```json -"UsingModalWindows": false +"UsingModalWindows": { + "forceModalityMode": false +} ``` diff --git a/docs/en/diagnostics/index.md b/docs/en/diagnostics/index.md index 5c8b3e97ff9..9ce0092db7b 100644 --- a/docs/en/diagnostics/index.md +++ b/docs/en/diagnostics/index.md @@ -8,12 +8,13 @@ To escape individual sections of code or files from triggering diagnostics, you ## Implemented diagnostics -Total: **117** +Total: **128** -* Error: **36** -* Code smell: **74** -* Vulnerability: **3** * Security Hotspot: **4** +* Vulnerability: **3** +* Error: **38** +* Code smell: **83** + | Key | Name| Enabled by default | Severity | Type | Tags | | --- | --- | :-: | --- | --- | --- | @@ -23,6 +24,7 @@ Total: **117** [CodeBlockBeforeSub](CodeBlockBeforeSub.md) | Method definitions must be placed before the module body operators | Yes | Blocker | Error | `error` [CodeOutOfRegion](CodeOutOfRegion.md) | Code out of region | Yes | Info | Code smell | `standard` [CognitiveComplexity](CognitiveComplexity.md) | Cognitive complexity | Yes | Critical | Code smell | `brainoverload` + [CommandModuleExportMethods](CommandModuleExportMethods.md) | Export methods in command and general command modules | Yes | Info | Code smell | `standard`
`clumsy` [CommentedCode](CommentedCode.md) | Commented out code | Yes | Minor | Code smell | `standard`
`badpractice` [CommitTransactionOutsideTryCatch](CommitTransactionOutsideTryCatch.md) | Violating transaction rules for the 'CommitTransaction' method | Yes | Major | Error | `standard` [CommonModuleAssign](CommonModuleAssign.md) | CommonModuleAssign | Yes | Blocker | Error | `error` @@ -61,9 +63,11 @@ Total: **117** [ExtraCommas](ExtraCommas.md) | Commas without a parameter at the end of a method call | Yes | Major | Code smell | `standard`
`badpractice` [FormDataToValue](FormDataToValue.md) | FormDataToValue method call | Yes | Info | Code smell | `badpractice` [FunctionNameStartsWithGet](FunctionNameStartsWithGet.md) | Function name shouldn't start with "Получить" | No | Info | Code smell | `standard` + [FunctionOutParameter](FunctionOutParameter.md) | Out function parameter | No | Major | Code smell | `design` [FunctionReturnsSamePrimitive](FunctionReturnsSamePrimitive.md) | The function always returns the same primitive value | Yes | Major | Error | `design`
`badpractice` [FunctionShouldHaveReturn](FunctionShouldHaveReturn.md) | The function should have return | Yes | Major | Error | `suspicious`
`unpredictable` [GetFormMethod](GetFormMethod.md) | GetForm method call | Yes | Major | Error | `error` + [GlobalContextMethodCollision8312](GlobalContextMethodCollision8312.md) | Global context method names collision | Yes | Blocker | Error | `error`
`unpredictable` [IdenticalExpressions](IdenticalExpressions.md) | There are identical sub-expressions to the left and to the right of the "foo" operator | Yes | Major | Error | `suspicious` [IfConditionComplexity](IfConditionComplexity.md) | Usage of complex expressions in the "If" condition | Yes | Minor | Code smell | `brainoverload` [IfElseDuplicatedCodeBlock](IfElseDuplicatedCodeBlock.md) | Duplicated code blocks in If...Then...ElseIf... statements | Yes | Minor | Code smell | `suspicious` @@ -73,12 +77,17 @@ Total: **117** [IsInRoleMethod](IsInRoleMethod.md) | IsInRole global method call | Yes | Major | Code smell | `error` [JoinWithSubQuery](JoinWithSubQuery.md) | Join with sub queries | Yes | Major | Code smell | `sql`
`standard`
`performance` [JoinWithVirtualTable](JoinWithVirtualTable.md) | Join with virtual table | Yes | Major | Code smell | `sql`
`standard`
`performance` + [LatinAndCyrillicSymbolInWord](LatinAndCyrillicSymbolInWord.md) | Mixing Latin and Cyrillic characters in one identifier | Yes | Minor | Code smell | `brainoverload`
`suspicious` [LineLength](LineLength.md) | Line Length limit | Yes | Minor | Code smell | `standard`
`badpractice` + [MagicDate](MagicDate.md) | Magic dates | Yes | Minor | Code smell | `badpractice`
`brainoverload` [MagicNumber](MagicNumber.md) | Magic numbers | Yes | Minor | Code smell | `badpractice` [MetadataObjectNameLength](MetadataObjectNameLength.md) | Metadata object names must not exceed the allowed length | Yes | Major | Error | `standard` [MethodSize](MethodSize.md) | Method size | Yes | Major | Code smell | `badpractice` [MissingCodeTryCatchEx](MissingCodeTryCatchEx.md) | Missing code in Raise block in "Try ... Raise ... EndTry" | Yes | Major | Error | `standard`
`badpractice` - [MissingSpace](MissingSpace.md) | Missing spaces to the left or right of operators + - * / = % < > <> <= >=, and also to the right of , and ; | Yes | Info | Code smell | `badpractice` + [MissingEventSubscriptionHandler](MissingEventSubscriptionHandler.md) | Event subscription handler missing | Yes | Blocker | Error | `error` + [MissingParameterDescription](MissingParameterDescription.md) | Method parameters description are missing | Yes | Major | Code smell | `standard`
`badpractice` + [MissingReturnedValueDescription](MissingReturnedValueDescription.md) | Function returned values description is missing | Yes | Major | Code smell | `standard`
`badpractice` + [MissingSpace](MissingSpace.md) | Missing spaces to the left or right of operators + - * / = % < > <> <= >=, keywords, and also to the right of , and ; | Yes | Info | Code smell | `badpractice` [MissingTemporaryFileDeletion](MissingTemporaryFileDeletion.md) | Missing temporary file deletion after using | Yes | Major | Error | `badpractice`
`standard` [MissingVariablesDescription](MissingVariablesDescription.md) | All variables declarations must have a description | Yes | Minor | Code smell | `standard` [MultilingualStringHasAllDeclaredLanguages](MultilingualStringHasAllDeclaredLanguages.md) | There is a localized text for all languages declared in the configuration | Yes | Minor | Error | `error`
`localize` @@ -95,10 +104,13 @@ Total: **117** [OSUsersMethod](OSUsersMethod.md) | Using method OSUsers | Yes | Critical | Security Hotspot | `suspicious` [OneStatementPerLine](OneStatementPerLine.md) | One statement per line | Yes | Minor | Code smell | `standard`
`design` [OrderOfParams](OrderOfParams.md) | Order of Parameters in method | Yes | Major | Code smell | `standard`
`design` + [OrdinaryAppSupport](OrdinaryAppSupport.md) | Ordinary application support | Yes | Major | Code smell | `standard`
`unpredictable` [PairingBrokenTransaction](PairingBrokenTransaction.md) | Violation of pairing using methods "BeginTransaction()" & "CommitTransaction()" / "RollbackTransaction()" | Yes | Major | Error | `standard` [ParseError](ParseError.md) | Source code parse error | Yes | Critical | Error | `error` [ProcedureReturnsValue](ProcedureReturnsValue.md) | Procedure should not return Value | Yes | Blocker | Error | `error` [PublicMethodsDescription](PublicMethodsDescription.md) | All public methods must have a description | Yes | Info | Code smell | `standard`
`brainoverload`
`badpractice` + [RedundantAccessToObject](RedundantAccessToObject.md) | Redundant access to an object | Yes | Info | Code smell | `standard`
`clumsy` + [RefOveruse](RefOveruse.md) | Overuse "Reference" in a query | Yes | Major | Code smell | `sql`
`performance` [SelfAssign](SelfAssign.md) | Variable is assigned to itself | Yes | Major | Error | `suspicious` [SelfInsertion](SelfInsertion.md) | Insert a collection into itself | Yes | Major | Error | `standard`
`unpredictable`
`performance` [SemicolonPresence](SemicolonPresence.md) | Statement should end with semicolon symbol ";" | Yes | Minor | Code smell | `standard`
`badpractice` @@ -117,8 +129,8 @@ Total: **117** [UnknownPreprocessorSymbol](UnknownPreprocessorSymbol.md) | Unknown preprocessor symbol | Yes | Critical | Error | `standard`
`error` [UnreachableCode](UnreachableCode.md) | Unreachable Code | Yes | Minor | Error | `design`
`suspicious` [UnsafeSafeModeMethodCall](UnsafeSafeModeMethodCall.md) | Unsafe SafeMode method call | Yes | Blocker | Error | `deprecated`
`error` - [UnusedLocalMethod](UnusedLocalMethod.md) | Unused local method | Yes | Major | Code smell | `standard`
`suspicious` - [UnusedParameters](UnusedParameters.md) | Unused parameter | Yes | Major | Code smell | `design` + [UnusedLocalMethod](UnusedLocalMethod.md) | Unused local method | Yes | Major | Code smell | `standard`
`suspicious`
`unused` + [UnusedParameters](UnusedParameters.md) | Unused parameter | Yes | Major | Code smell | `design`
`unused` [UseLessForEach](UseLessForEach.md) | Useless collection iteration | Yes | Critical | Error | `clumsy` [UsingCancelParameter](UsingCancelParameter.md) | Using parameter "Cancel" | Yes | Major | Code smell | `standard`
`badpractice` [UsingExternalCodeTools](UsingExternalCodeTools.md) | Using external code tools | Yes | Critical | Security Hotspot | `standard`
`design` diff --git a/docs/en/features/ConfigurationFile.md b/docs/en/features/ConfigurationFile.md index c9126a0feef..ef793d53298 100644 --- a/docs/en/features/ConfigurationFile.md +++ b/docs/en/features/ConfigurationFile.md @@ -12,6 +12,7 @@ Name | Type | Description ⤷   `showCyclomaticComplexity` | `Boolean` | Similar to `showCognitiveComplexityCodeLens`, enables the display of the [cyclomatic complexity](../diagnostics/CyclomaticComplexity.md) value of the method. By default enabled (*is set to `true`*) `diagnostics` | `JSON-Object` | Contains diagnostic settings ⤷   `computeTrigger` | `String` | Event that will trigger the code analysis procedure to diagnose comments. Possible values:
* `onType` -when editing a file (online) ***on large files can significantly slow down editing ***
onSave - when saving a file (default)

`never` - analysis will not be performed +⤷ `ordinaryAppSupport` | `Boolean` | Ordinary client support. Diagnostics will require taking into account the features of a ordinary application. Values:
* `true` - the configuration uses ordinary application *(default)*
* `false` -
ignore ordinary application warnings ⤷   `skipSupport` | `String` | This parameter sets **1C configuration** file skipping mode *(for example files are not analyzed for issues)* which are "on support" from vendor configuration. Possible values:
* `withSupport` - skip all modules set "on support" *(all "locks" types)*
* `withSupportLocked` - skip modules set "on support" with prohibited modification *("yellow closed lock")*
* `never` - skip no modules as support mode is not analyzed *(set by default)* ⤷   `mode` | `String` | Setting for controlling the diagnostic settings accounting mode. Possible options:
* `OFF` - All diagnostics are considered to be turned off, regardless of their settings.
* `ON` - All diagnostics enabled by default are considered enabled, the rest - depending on personal settings
* `EXCEPT` - All diagnostics other than those specified are considered enabled.
* `ONLY` - Only the specified diagnostics are considered enabled.
* `ALL` - All diagnostics are considered enabled. ⤷   `parameters` | `JSON-Object` | Parameter is a collection of diagnostics parameters. Collection items are json-objects with the following structure:
* *object key* - string, is diagnostic key
* *object value* - if is boolean, then interpreted as diagnostic off-switch (`false`) or on-switch with default parameters (`true`), if is type `json-object`, collection of diagnostic parameters.

Key, if set to ON by default and all allowed parameters and examples are given on the diagnostic page. @@ -37,5 +38,17 @@ The following is an example of a settings: - Enables the calculation of diagnostics in continuous mode ( `computeTrigger = onType` ) ```json -{ "$schema": "https://1c-syntax.github.io/bsl-language-server/configuration/schema.json", "diagnosticLanguage": "en", "diagnostics": { "LineLength": { "maxLineLength": 140 }, "MethodSize": false } } +{ + "$schema": "https://1c-syntax.github.io/bsl-language-server/configuration/schema.json", + "language": "en", + "diagnostics": { + "computeTrigger": "onType", + "parameters": { + "LineLength": { + "maxLineLength": 140 + }, + "MethodSize": false + } + } +} ``` diff --git a/docs/en/index.md b/docs/en/index.md index ce78e792767..e6d397cc2e1 100644 --- a/docs/en/index.md +++ b/docs/en/index.md @@ -1,6 +1,15 @@ # BSL Language Server -[](https://github.com/1c-syntax/bsl-language-server/actions)![Actions Status](https://github.com/1c-syntax/bsl-language-server/workflows/Java%20CI/badge.svg) +[![Actions Status](https://github.com/1c-syntax/bsl-language-server/workflows/Java%20CI/badge.svg)](https://github.com/1c-syntax/bsl-language-server/actions) +[![Download](https://img.shields.io/github/release/1c-syntax/bsl-language-server.svg?label=download&style=flat)](https://github.com/1c-syntax/bsl-language-server/releases/latest) +[![JitPack](https://jitpack.io/v/1c-syntax/bsl-language-server.svg)](https://jitpack.io/#1c-syntax/bsl-language-server) +[![GitHub Releases](https://img.shields.io/github/downloads/1c-syntax/bsl-language-server/latest/total?style=flat-square)](https://github.com/1c-syntax/bsl-language-server/releases) +[![GitHub All Releases](https://img.shields.io/github/downloads/1c-syntax/bsl-language-server/total?style=flat-square)](https://github.com/1c-syntax/bsl-language-server/releases) +[![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=1c-syntax_bsl-language-server&metric=alert_status)](https://sonarcloud.io/dashboard?id=1c-syntax_bsl-language-server) +[![Maintainability](https://sonarcloud.io/api/project_badges/measure?project=1c-syntax_bsl-language-server&metric=sqale_rating)](https://sonarcloud.io/dashboard?id=1c-syntax_bsl-language-server) +[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=1c-syntax_bsl-language-server&metric=coverage)](https://sonarcloud.io/dashboard?id=1c-syntax_bsl-language-server) +[![Benchmark](bench/benchmark.svg)](../bench/index.html) +[![telegram](https://img.shields.io/badge/telegram-chat-green.svg)](https://t.me/bsl_language_server) [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) implementation for 1C (BSL) - 1C:Enterprise 8 and [OneScript](http://oscript.io) languages. @@ -81,12 +90,12 @@ To run in formatter mode use parameter `--format` (short `-f`). Usage: bsl-language-server format [-hq] [-s=] Format files in source directory -h, --help Show this help message and exit -q, --silent Silent mode -s, --srcDir= Source directory ``` -To set source code folder for formatting use parameter `--srcDir` (short `-s`) followed by the path (relative or absolute) to the source code folder. +To set source code folder (or source file) for formatting use parameter `--src` (short `-s`) followed by the path (relative or absolute) to the source code folder (or file). Command line example to run formatting: ```sh -java -jar bsl-language-server.jar --format --srcDir ./src/cf +java -jar bsl-language-server.jar --format --src ./src/cf ``` @@ -105,16 +114,16 @@ Thanks to companies supporting open source projects, and especially to those who --- -[](https://www.yourkit.com)![YourKit](https://www.yourkit.com/images/yklogo.png) +[![YourKit](https://www.yourkit.com/images/yklogo.png)](https://www.yourkit.com) -{a0 href="https://www.yourkit.com"}YourKit, LLC{/a0} is the creator of innovative and intelligent tools for profiling `Java` and `.NET` applications. YourKit has offered an open source license [YourKit Java Profiler](https://www.yourkit.com) for `BSL Language Server` to improve its performance. +[YourKit, LLC](https://www.yourkit.com) is the creator of innovative and intelligent tools for profiling `Java` and `.NET` applications. YourKit has offered an open source license [YourKit Java Profiler](https://www.yourkit.com) for `BSL Language Server` to improve its performance. With `YourKit Java Profiler` we profile and improve project performance. --- -[](https://www.jetbrains.com)![JetBrains](assets/images/jetbrains-variant-4.png) +[![JetBrains](assets/images/jetbrains-variant-4.png)](https://www.jetbrains.com?from=bsl-language-server) -[JetBrains](https://www.jetbrains.com) is the creator of professional software for development. JetBrains has offered an open source license for his products, including `IntelliJ IDEA Ultimate`. +[JetBrains](https://www.jetbrains.com?from=bsl-language-server) is the creator of professional software for development. JetBrains has offered an open source license for his products, including `IntelliJ IDEA Ultimate`. `IntelliJ IDEA Ultimate` is one of the best tools in its class. diff --git a/docs/en/systemRequirements.md b/docs/en/systemRequirements.md index 4082637a1c9..ca2a2f78936 100644 --- a/docs/en/systemRequirements.md +++ b/docs/en/systemRequirements.md @@ -6,7 +6,7 @@ Using ` BSL Language Server ` has some limitations, listed bellow `BSL Language Server` is a console Java application and requires the presence of a Java virtual machine on the computer. -The minimum supported version is Java 11, but as part of the build pipelines, a health check is performed when using more recent versions. Java versions 11, 13 and 14 are currently supported. +The minimum supported version is Java 11, but as part of the build pipelines, a health check is performed when using more recent versions. Java versions 11 and 15 are currently supported. JDK vendor is also interesting. Due to the changed licensing policy of Oracle, it is recommended to use open implementations of the `OpenJDK` virtual machine: AdoptOpenJDK, Liberica JDK. diff --git a/docs/features/ConfigurationFile.md b/docs/features/ConfigurationFile.md index a22e9ac295c..0bc6f374157 100644 --- a/docs/features/ConfigurationFile.md +++ b/docs/features/ConfigurationFile.md @@ -13,6 +13,7 @@ BSL Language Server предоставляет возможность измен |⤷   `showCyclomaticComplexity`|`Булево`|Включает отображение значения [цикломатической сложности](../diagnostics/CyclomaticComplexity.md) метода. По умолчанию параметр включен (*установлен в `true`*)| |`diagnostics`|`JSON-Объект`|Содержит настройки диагностик| |⤷   `computeTrigger`|`Строка`|С помощью этого параметра можно указать событие, при котором будет вызвана процедура анализа кода для диагностирования замечаний. Возможные значения:
* `onType` - при редактировании файла (онлайн) ***на больших файлах может ЗНАЧИТЕЛЬНО замедлять редактирование***
* `onSave` - при сохранении файла (*используется по умолчанию*)
* `never` - анализ выполняться не будет| +|⤷   `ordinaryAppSupport`|`Булево>`|Поддержка обычного клиента. Диагностики будут требовать учитывать особенности обычного приложения. Возможные значения:
* `true` - конфигурация разрабатывается с поддержкой обычного клиента *(установлен по умолчанию)*
* `false` - игнорировать предупреждения связанные с особенностями обычного клиента| |⤷   `skipSupport`|`Строка`|Этим параметром настраивается режим пропуска файлов *(т.е. файлы не анализируются на предмет наличия замечаний)* **конфигурации 1С**, находящихся "на поддержке" конфигурации поставщика. Возможные значения:
* `withSupport` - пропускаются все модули, находящиеся "на поддержке" *(все виды "замков")*
* `withSupportLocked` - пропускаются только модули, находящиеся "на поддержке" с запретом изменений *("желтый закрытый замок")*
* `never` - режим поддержки не анализируется и модули не пропускаются *(установлен по умолчанию)*| |⤷   `mode`|`Строка`|Настройка для управления режимом учета настроек диагностик. Возможные варианты:
* `OFF` - Все диагностики считаются выключенными, вне зависимости от их настроек
* `ON` - Все диагностики включенные по умолчанию считаются включенными, остальные - в зависимости от личных настроек
* `EXCEPT` - Все диагностистики, кроме указанных, считаются включенными
* `ONLY` - Только указанные диагностики считаются включенными
* `ALL` - Все диагностики считаются включенными| |⤷   `parameters`|`JSON-Объект`|Параметр представляет собой коллекцию настроек диагностик. Элементами коллекции являются json-объекты следующей структуры:
* *ключ объекта* - строка, являющаяся ключом диагностики
* *значение объекта* - может принимать либо булево значение, и тогда интерпретируется как отключение диагностики (`false`) или ее включение с параметрами по умолчанию (`true`), либо значение типа `json-объект`, представляющего собой набор настроек диагностики.

Ключ, включена ли по умолчанию, а также описание возможных параметров и примеры для конфигурационного файла представлены на странице с описанием каждой диагностики.| diff --git a/docs/index.md b/docs/index.md index d892bba5369..704800d302f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -114,15 +114,15 @@ Usage: bsl-language-server format [-hq] [-s=] Format files in source directory -h, --help Show this help message and exit -q, --silent Silent mode - -s, --srcDir= Source directory + -s, --src= Source directory or file ``` -Для указания каталога расположения форматируемых исходников используется параметр `--srcDir` (сокращенно `-s`), за которым следует путь (относительный или абсолютный) к каталогу исходников. +Для указания каталога расположения форматируемых исходников (или файла) используется параметр `--src` (сокращенно `-s`), за которым следует путь (относительный или абсолютный) к каталогу исходников (или файлу). Пример строки запуска форматирования: ```sh -java -jar bsl-language-server.jar --format --srcDir ./src/cf +java -jar bsl-language-server.jar --format --src ./src/cf ``` @@ -149,9 +149,9 @@ java -jar bsl-language-server.jar --format --srcDir ./src/cf --- -[![JetBrains](assets/images/jetbrains-variant-4.png)](https://www.jetbrains.com) +[![JetBrains](assets/images/jetbrains-variant-4.png)](https://www.jetbrains.com?from=bsl-language-server) -Создатель профессиональных инструментов разработки программного обеспечения, инновационных и мощных, [JetBrains](https://www.jetbrains.com) поддержал наш проект, предоставив лицензии на свои продукты, в том числе на `IntelliJ IDEA Ultimate`. +Создатель профессиональных инструментов разработки программного обеспечения, инновационных и мощных, [JetBrains](https://www.jetbrains.com?from=bsl-language-server) поддержал наш проект, предоставив лицензии на свои продукты, в том числе на `IntelliJ IDEA Ultimate`. `IntelliJ IDEA Ultimate` один из лучших инструментов в своем классе. diff --git a/docs/reporters/json.md b/docs/reporters/json.md index 69cdfc985c2..a3e8a886e11 100644 --- a/docs/reporters/json.md +++ b/docs/reporters/json.md @@ -6,6 +6,27 @@ Выводит результаты анализа в файл `bsl-json.json` в текущей рабочей директории. Выводится результат работы метода сериализатора JSON для объекта [AnalysisInfo](https://github.com/1c-syntax/bsl-language-server/blob/develop/src/main/java/com/github/_1c_syntax/bsl/languageserver/reporters/data/AnalysisInfo.java) +## Схема: + +- *date* - дата анализа. +- *fileinfos* - массив описаний файлов. +- *sourceDir* - Путь к папке с исходниками без префикса "file:///" с разделителями по умолчанию для ОС. + +- ### fileinfo: + - *path* - Полный путь к файлу с ошибками, с описанием схемы ("file:///") разделителем должен быть "/". + - *mdoRef* - Описание ссылки на объект (допускается пустое значение ("") ) пример: "Catalog.Организации" + - *diagnostics* - массив описаний диагностических сообщений. + - *metrics* - метрики файла (не обязательный). + + - #### diagnostic: + - *range* - Описание местоположения ошибки в файле. + - *severity* - Одно из Error, Warning, Hint, Information + - *code* - Код правила ошибки. + - *source* - Репозиторий правила. + - *message* - Сообщение ошибки. + - *tags* - Тэги, к которым будет отнесена ошибка. (допускается пустое значение (null)) + - *relatedInformation* - Массив (допускается пустое значение (null) ) дополнительные места срабатывания ошибки, дополнительная уточняющая информация. + ## Пример вывода ```json @@ -32,7 +53,40 @@ "source": "bsl-language-server", "message": "Функция не содержит \"Возврат\"", "tags": null, - "relatedInformation": null + "relatedInformation": [ + { + "location": { + "uri": "file:///tmp/src/Module.bsl", + "range": { + "end": { + "character": 29, + "line": 43 + }, + "start": { + "character": 8, + "line": 43 + } + } + }, + "message": "+1" + }, + { + "location": { + "uri": "file:///tmp/src/Module.bsl", + "range": { + "end": { + "character": 29, + "line": 100 + }, + "start": { + "character": 8, + "line": 100 + } + } + }, + "message": "+1" + } + ] } ], "metrics": { @@ -67,6 +121,6 @@ } } ], - "sourceDir": "file:///tmp/src" + "sourceDir": "/tmp/src" } ``` diff --git a/docs/systemRequirements.md b/docs/systemRequirements.md index c20e56ac85b..45b25c8c8d4 100644 --- a/docs/systemRequirements.md +++ b/docs/systemRequirements.md @@ -6,7 +6,7 @@ `BSL Language Server` представляет собой консольное Java приложение, соответственно, для его функционирования необходимо наличие виртуальной машины Java на компьютере. -На данный момент минимальной поддерживаемой версией является Java 11, но в рамках сборочных конвейеров происходит проверка работоспособности при использовании более свежих версий. На данный момент поддерживаются Java версий 11, 13 и 14. +На данный момент минимальной поддерживаемой версией является Java 11, но в рамках сборочных конвейеров происходит проверка работоспособности при использовании более свежих версий. На данный момент поддерживаются Java версий 11 и 15. Кроме версии Java интересен и вендор JDK. В связи с изменившейся политикой лицензирования Oracle, рекомендуется использование открытых реализаций виртуальной машины `OpenJDK`: AdoptOpenJDK, Liberica JDK. diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 62d4c053550..e708b1c023e 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 12d38de6a48..be52383ef49 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index fbd7c515832..4f906e0c811 100755 --- a/gradlew +++ b/gradlew @@ -130,7 +130,7 @@ fi if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath diff --git a/gradlew.bat b/gradlew.bat index 5093609d512..107acd32c4e 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -54,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -64,21 +64,6 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line @@ -86,7 +71,7 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/settings.gradle.kts b/settings.gradle.kts index d26c221f0f3..5d52f354c34 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -4,5 +4,6 @@ pluginManagement { repositories { gradlePluginPortal() maven(url = "https://jitpack.io") + mavenLocal() } } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/AutoServerInfo.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/AutoServerInfo.java new file mode 100644 index 00000000000..d3a1878cdf1 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/AutoServerInfo.java @@ -0,0 +1,73 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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; + +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +/** + * Информация о сервере. Автоматически заполняется на основании данных о версии и имени приложения. + */ +@Slf4j +@EqualsAndHashCode(exclude = "applicationName", callSuper = true) +@Component +public class AutoServerInfo extends org.eclipse.lsp4j.ServerInfo implements Serializable { + + private static final String MANIFEST_VERSION = readVersion(); + + @SuppressWarnings("FieldMayBeFinal") + @Value("${spring.application.name:Dummy Language Server}") + // Field is transient to exclude it from GSON serialization in jsonrpc. + private transient String applicationName = ""; + + @PostConstruct + private void init() { + setName(applicationName); + setVersion(MANIFEST_VERSION); + } + + private static String readVersion() { + final InputStream mfStream = Thread.currentThread() + .getContextClassLoader() + .getResourceAsStream("META-INF/MANIFEST.MF"); + + Manifest manifest = new Manifest(); + try { + manifest.read(mfStream); + } catch (IOException e) { + LOGGER.error("Can't read manifest", e); + return ""; + } + + return manifest.getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION); + } + +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLLanguageServer.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLLanguageServer.java index 61c8827fb1c..527a50949fe 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLLanguageServer.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLLanguageServer.java @@ -24,16 +24,19 @@ import com.github._1c_syntax.bsl.languageserver.configuration.LanguageServerConfiguration; import com.github._1c_syntax.bsl.languageserver.context.ServerContext; import com.github._1c_syntax.bsl.languageserver.jsonrpc.DiagnosticParams; +import com.github._1c_syntax.bsl.languageserver.jsonrpc.Diagnostics; import com.github._1c_syntax.bsl.languageserver.jsonrpc.ProtocolExtension; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.eclipse.lsp4j.CodeLensOptions; -import org.eclipse.lsp4j.Diagnostic; import org.eclipse.lsp4j.DocumentLinkOptions; import org.eclipse.lsp4j.InitializeParams; import org.eclipse.lsp4j.InitializeResult; +import org.eclipse.lsp4j.SaveOptions; import org.eclipse.lsp4j.ServerCapabilities; +import org.eclipse.lsp4j.ServerInfo; import org.eclipse.lsp4j.TextDocumentSyncKind; +import org.eclipse.lsp4j.TextDocumentSyncOptions; import org.eclipse.lsp4j.services.LanguageServer; import org.eclipse.lsp4j.services.TextDocumentService; import org.eclipse.lsp4j.services.WorkspaceService; @@ -44,7 +47,6 @@ import java.net.URI; import java.net.URISyntaxException; import java.nio.file.Path; -import java.util.List; import java.util.concurrent.CompletableFuture; @Slf4j @@ -55,8 +57,9 @@ public class BSLLanguageServer implements LanguageServer, ProtocolExtension { private final LanguageServerConfiguration configuration; private final BSLTextDocumentService textDocumentService; private final BSLWorkspaceService workspaceService; - private boolean shutdownWasCalled; private final ServerContext context; + private final ServerInfo serverInfo; + private boolean shutdownWasCalled; @Override public CompletableFuture initialize(InitializeParams params) { @@ -65,7 +68,7 @@ public CompletableFuture initialize(InitializeParams params) { CompletableFuture.runAsync(context::populateContext); ServerCapabilities capabilities = new ServerCapabilities(); - capabilities.setTextDocumentSync(TextDocumentSyncKind.Full); + capabilities.setTextDocumentSync(getTextDocumentSyncOptions()); capabilities.setDocumentRangeFormattingProvider(Boolean.TRUE); capabilities.setDocumentFormattingProvider(Boolean.TRUE); capabilities.setFoldingRangeProvider(Boolean.TRUE); @@ -75,7 +78,7 @@ public CompletableFuture initialize(InitializeParams params) { capabilities.setDocumentLinkProvider(new DocumentLinkOptions()); capabilities.setWorkspaceSymbolProvider(Boolean.TRUE); - InitializeResult result = new InitializeResult(capabilities); + InitializeResult result = new InitializeResult(capabilities, serverInfo); return CompletableFuture.completedFuture(result); } @@ -118,12 +121,8 @@ public void exit() { *

* См. {@link BSLTextDocumentService#diagnostics(DiagnosticParams)} */ -// @JsonRequest( -// value = "textDocument/x-diagnostics", -// useSegment = false -// ) @Override - public CompletableFuture> diagnostics(DiagnosticParams params) { + public CompletableFuture diagnostics(DiagnosticParams params) { return textDocumentService.diagnostics(params); } @@ -137,4 +136,19 @@ public WorkspaceService getWorkspaceService() { return workspaceService; } + private static TextDocumentSyncOptions getTextDocumentSyncOptions() { + TextDocumentSyncOptions textDocumentSync = new TextDocumentSyncOptions(); + + textDocumentSync.setOpenClose(Boolean.TRUE); + textDocumentSync.setChange(TextDocumentSyncKind.Full); + textDocumentSync.setWillSave(Boolean.FALSE); + textDocumentSync.setWillSaveWaitUntil(Boolean.FALSE); + + SaveOptions save = new SaveOptions(); + save.setIncludeText(Boolean.FALSE); + + textDocumentSync.setSave(save); + + return textDocumentSync; + } } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLTextDocumentService.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLTextDocumentService.java index be547ba0fa7..2e8811610eb 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLTextDocumentService.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLTextDocumentService.java @@ -26,6 +26,7 @@ import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; import com.github._1c_syntax.bsl.languageserver.context.ServerContext; import com.github._1c_syntax.bsl.languageserver.jsonrpc.DiagnosticParams; +import com.github._1c_syntax.bsl.languageserver.jsonrpc.Diagnostics; import com.github._1c_syntax.bsl.languageserver.jsonrpc.ProtocolExtension; import com.github._1c_syntax.bsl.languageserver.providers.CodeActionProvider; import com.github._1c_syntax.bsl.languageserver.providers.CodeLensProvider; @@ -46,7 +47,6 @@ import org.eclipse.lsp4j.CompletionList; import org.eclipse.lsp4j.CompletionParams; import org.eclipse.lsp4j.DefinitionParams; -import org.eclipse.lsp4j.Diagnostic; import org.eclipse.lsp4j.DidChangeTextDocumentParams; import org.eclipse.lsp4j.DidCloseTextDocumentParams; import org.eclipse.lsp4j.DidOpenTextDocumentParams; @@ -74,14 +74,10 @@ import org.eclipse.lsp4j.TextEdit; import org.eclipse.lsp4j.WorkspaceEdit; import org.eclipse.lsp4j.jsonrpc.messages.Either; -import org.eclipse.lsp4j.services.LanguageClient; -import org.eclipse.lsp4j.services.LanguageClientAware; import org.eclipse.lsp4j.services.TextDocumentService; import org.springframework.stereotype.Component; -import javax.annotation.CheckForNull; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; @@ -89,7 +85,7 @@ @Component @RequiredArgsConstructor -public class BSLTextDocumentService implements TextDocumentService, LanguageClientAware, ProtocolExtension { +public class BSLTextDocumentService implements TextDocumentService, ProtocolExtension { private final ServerContext context; private final LanguageServerConfiguration configuration; @@ -102,9 +98,6 @@ public class BSLTextDocumentService implements TextDocumentService, LanguageClie private final FormatProvider formatProvider; private final HoverProvider hoverProvider; - @CheckForNull - private LanguageClient client; - @Override public CompletableFuture, CompletionList>> completion(CompletionParams position) { List completionItems = new ArrayList<>(); @@ -245,7 +238,7 @@ public void didChange(DidChangeTextDocumentParams params) { return; } - documentContext.rebuild(params.getContentChanges().get(0).getText()); + documentContext.rebuild(params.getContentChanges().get(0).getText(), params.getTextDocument().getVersion()); if (configuration.getDiagnosticsOptions().getComputeTrigger() == ComputeTrigger.ONTYPE) { validate(documentContext); @@ -261,9 +254,7 @@ public void didClose(DidCloseTextDocumentParams params) { documentContext.clearSecondaryData(); - if (client != null) { - diagnosticProvider.publishEmptyDiagnosticList(client, documentContext); - } + diagnosticProvider.publishEmptyDiagnosticList(documentContext); } @Override @@ -278,11 +269,6 @@ public void didSave(DidSaveTextDocumentParams params) { } } - @Override - public void connect(LanguageClient client) { - this.client = client; - } - @Override public CompletableFuture> documentLink(DocumentLinkParams params) { DocumentContext documentContext = context.getDocument(params.getTextDocument().getUri()); @@ -294,10 +280,10 @@ public CompletableFuture> documentLink(DocumentLinkParams par } @Override - public CompletableFuture> diagnostics(DiagnosticParams params) { + public CompletableFuture diagnostics(DiagnosticParams params) { DocumentContext documentContext = context.getDocument(params.getTextDocument().getUri()); if (documentContext == null) { - return CompletableFuture.completedFuture(Collections.emptyList()); + return CompletableFuture.completedFuture(Diagnostics.EMPTY); } return CompletableFuture.supplyAsync(() -> { @@ -309,7 +295,7 @@ public CompletableFuture> diagnostics(DiagnosticParams params) .filter(diagnostic -> Ranges.containsRange(range, diagnostic.getRange())) .collect(Collectors.toList()); } - return diagnostics; + return new Diagnostics(diagnostics, documentContext.getVersion()); }); } @@ -318,10 +304,7 @@ public void reset() { } private void validate(DocumentContext documentContext) { - if (client == null) { - return; - } - diagnosticProvider.computeAndPublishDiagnostics(client, documentContext); + diagnosticProvider.computeAndPublishDiagnostics(documentContext); } } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/cli/AnalyzeCommand.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/cli/AnalyzeCommand.java index 363eb83e996..b64303f8273 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/cli/AnalyzeCommand.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/cli/AnalyzeCommand.java @@ -33,6 +33,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import me.tongfei.progressbar.ProgressBar; +import me.tongfei.progressbar.ProgressBarBuilder; import me.tongfei.progressbar.ProgressBarStyle; import org.apache.commons.io.FileUtils; import org.eclipse.lsp4j.Diagnostic; @@ -56,27 +57,27 @@ /** * Выполнение анализа * Ключ команды: - * -a, (--analyze) + * -a, (--analyze) * Параметры: - * -s, (--srcDir) <arg> - Путь к каталогу исходных файлов. - * Возможно указывать как в абсолютном, так и относительном виде. Если параметр опущен, - * то анализ выполняется в текущем каталоге запуска. - * -o, (--outputDir) <arg> - Путь к каталогу размещения отчетов - результатов анализа. - * Возможно указывать как в абсолютном, так и относительном виде. Если параметр опущен, - * то файлы отчета будут сохранены в текущем каталоге запуска. - * -w, (--workspaceDir) <arg> - Путь к каталогу проекта, относительно которого располагаются исходные файлы. - * Возможно указывать как в абсолютном, так и в относительном виде. Если параметр опущен, - * то пути к исходным файлам будут указываться относительно текущего каталога запуска. - * -c, (--configuration) <arg> - Путь к конфигурационному файлу BSL Language Server (.bsl-language-server.json). - * Возможно указывать как в абсолютном, так и относительном виде. Если параметр опущен, - * то будут использованы настройки по умолчанию. - * -r, (--reporter) <arg> - Ключи "Репортеров", т.е. форматов отчетов, котрые необходимо сгенерировать после - * выполнения анализа. Может быть указано более одного ключа. Если параметр опущен, - * то вывод результата будет призведен в консоль. - * -q, (--silent) - Флаг для отключения вывода прогресс-бара и дополнительных сообщений в консоль + * -s, (--srcDir) <arg> - Путь к каталогу исходных файлов. + * Возможно указывать как в абсолютном, так и относительном виде. Если параметр опущен, + * то анализ выполняется в текущем каталоге запуска. + * -o, (--outputDir) <arg> - Путь к каталогу размещения отчетов - результатов анализа. + * Возможно указывать как в абсолютном, так и относительном виде. Если параметр опущен, + * то файлы отчета будут сохранены в текущем каталоге запуска. + * -w, (--workspaceDir) <arg> - Путь к каталогу проекта, относительно которого располагаются исходные файлы. + * Возможно указывать как в абсолютном, так и в относительном виде. Если параметр опущен, + * то пути к исходным файлам будут указываться относительно текущего каталога запуска. + * -c, (--configuration) <arg> - Путь к конфигурационному файлу BSL Language Server (.bsl-language-server.json). + * Возможно указывать как в абсолютном, так и относительном виде. Если параметр опущен, + * то будут использованы настройки по умолчанию. + * -r, (--reporter) <arg> - Ключи "Репортеров", т.е. форматов отчетов, котрые необходимо сгенерировать после + * выполнения анализа. Может быть указано более одного ключа. Если параметр опущен, + * то вывод результата будет призведен в консоль. + * -q, (--silent) - Флаг для отключения вывода прогресс-бара и дополнительных сообщений в консоль * Выводимая информация: - * Выполняет анализ каталога исходных файлов и генерацию файлов отчета. Для каждого указанного ключа "Репортера" - * создается отдельный файл (каталог файлов). Реализованные "репортеры" находятся в пакете "reporter". + * Выполняет анализ каталога исходных файлов и генерацию файлов отчета. Для каждого указанного ключа "Репортера" + * создается отдельный файл (каталог файлов). Реализованные "репортеры" находятся в пакете "reporter". **/ @Slf4j @Command( @@ -172,7 +173,7 @@ public Integer call() { context.setConfigurationRoot(configurationPath); Collection files = FileUtils.listFiles(srcDir.toFile(), new String[]{"bsl", "os"}, true); - + context.populateContext(files); List fileInfos; @@ -181,7 +182,11 @@ public Integer call() { .map((File file) -> getFileInfoFromFile(workspaceDir, file)) .collect(Collectors.toList()); } else { - try (ProgressBar pb = new ProgressBar("Analyzing files...", files.size(), ProgressBarStyle.ASCII)) { + try (ProgressBar pb = new ProgressBarBuilder() + .setTaskName("Analyzing files...") + .setInitialMax(files.size()) + .setStyle(ProgressBarStyle.ASCII) + .build()) { fileInfos = files.parallelStream() .map((File file) -> { pb.step(); @@ -209,7 +214,7 @@ private FileInfo getFileInfoFromFile(Path srcDir, File file) { throw new RuntimeException(e); } - DocumentContext documentContext = context.addDocument(file.toURI(), textDocumentContent); + DocumentContext documentContext = context.addDocument(file.toURI(), textDocumentContent, 1); Path filePath = srcDir.relativize(Absolute.path(file)); List diagnostics = documentContext.getDiagnostics(); diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/cli/FormatCommand.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/cli/FormatCommand.java index b97d90c1cd0..01aabc8e000 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/cli/FormatCommand.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/cli/FormatCommand.java @@ -29,6 +29,7 @@ import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import me.tongfei.progressbar.ProgressBar; +import me.tongfei.progressbar.ProgressBarBuilder; import me.tongfei.progressbar.ProgressBarStyle; import org.apache.commons.io.FileUtils; import org.eclipse.lsp4j.DocumentFormattingParams; @@ -41,6 +42,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.concurrent.Callable; @@ -52,9 +54,11 @@ * Ключ команды: * -f, (--format) * Параметры: - * -s, (--srcDir) <arg> - Путь к каталогу исходных файлов. + * -s, (--src) - Путь к каталогу исходных файлов. * Возможно указывать как в абсолютном, так и относительном виде. Если параметр опущен, * то анализ выполняется в текущем каталоге запуска. + * Можно указать каталог, в котором будут найдены файлы для форматирования, либо один + * файл для форматирования * -q, (--silent) - Флаг для отключения вывода прогресс-бара и дополнительных сообщений в консоль * Выводимая информация: * Выполняет форматирование исходного кода в файлах каталога. Для форматирования используются правила и настройки @@ -81,8 +85,8 @@ public class FormatCommand implements Callable { private boolean usageHelpRequested; @Option( - names = {"-s", "--srcDir"}, - description = "Source directory", + names = {"-s", "--srcDir", "--src"}, // TODO delete old key --srcDir + description = "Source directory or file", paramLabel = "", defaultValue = "") private String srcDirOption; @@ -107,12 +111,22 @@ public Integer call() { return 1; } - Collection files = FileUtils.listFiles(srcDir.toFile(), new String[]{"bsl", "os"}, true); + Collection files; + + if(srcDir.toFile().isDirectory()) { + files = FileUtils.listFiles(srcDir.toFile(), new String[]{"bsl", "os"}, true); + } else { + files = Collections.singletonList(srcDir.toFile()); + } if (silentMode) { files.parallelStream().forEach(this::formatFile); } else { - try (ProgressBar pb = new ProgressBar("Formatting files...", files.size(), ProgressBarStyle.ASCII)) { + try (ProgressBar pb = new ProgressBarBuilder() + .setTaskName("Formatting files...") + .setInitialMax(files.size()) + .setStyle(ProgressBarStyle.ASCII) + .build()) { files.parallelStream() .forEach((File file) -> { pb.step(); @@ -129,7 +143,7 @@ private void formatFile(File file) { String textDocumentContent = FileUtils.readFileToString(file, StandardCharsets.UTF_8); final URI uri = file.toURI(); - DocumentContext documentContext = serverContext.addDocument(uri, textDocumentContent); + DocumentContext documentContext = serverContext.addDocument(uri, textDocumentContent, 1); DocumentFormattingParams params = new DocumentFormattingParams(); FormattingOptions options = new FormattingOptions(); diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/cli/VersionCommand.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/cli/VersionCommand.java index a6bd70f2a0b..98c36cb2ce3 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/cli/VersionCommand.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/cli/VersionCommand.java @@ -21,16 +21,14 @@ */ package com.github._1c_syntax.bsl.languageserver.cli; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.eclipse.lsp4j.ServerInfo; import org.springframework.stereotype.Component; import picocli.CommandLine.Command; import picocli.CommandLine.Option; -import java.io.IOException; -import java.io.InputStream; import java.util.concurrent.Callable; -import java.util.jar.Attributes; -import java.util.jar.Manifest; /** * Выводит версию приложения @@ -45,6 +43,7 @@ usageHelpAutoWidth = true, footer = "@|green Copyright(c) 2018-2020|@") @Component +@RequiredArgsConstructor public class VersionCommand implements Callable { @Option(names = "--spring.config.location", hidden = true) @@ -53,24 +52,18 @@ public class VersionCommand implements Callable { @Option(names = "--debug", hidden = true) private boolean debug; - public Integer call() { - final InputStream mfStream = Thread.currentThread() - .getContextClassLoader() - .getResourceAsStream("META-INF/MANIFEST.MF"); + private final ServerInfo serverInfo; - Manifest manifest = new Manifest(); - try { - manifest.read(mfStream); - } catch (IOException e) { - LOGGER.error("Can't read manifest", e); + public Integer call() { + String version = serverInfo.getVersion(); + if (version.isEmpty()) { return 1; } - System.out.print( - String.format( - "version: %s%n", - manifest.getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION) - )); + System.out.printf( + "version: %s%n", + version + ); return 0; } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/cli/package-info.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/cli/package-info.java index dbf7852daa6..3ac9c7811cf 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/cli/package-info.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/cli/package-info.java @@ -19,7 +19,6 @@ * You should have received a copy of the GNU Lesser General Public * License along with BSL Language Server. */ - /** * Пакет предназначен для реализации CLI функциональности BSL Language Server. * Каждый класс пакета реализовывает интерфейс Command (и одноименный суффикс имени) и имеет javadoc-описание своих diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/codeactions/AbstractQuickFixSupplier.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/codeactions/AbstractQuickFixSupplier.java index 033659b8e8b..1eb26e7b2c5 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/codeactions/AbstractQuickFixSupplier.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/codeactions/AbstractQuickFixSupplier.java @@ -23,13 +23,17 @@ import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; import lombok.RequiredArgsConstructor; +import lombok.Value; import org.eclipse.lsp4j.CodeAction; import org.eclipse.lsp4j.CodeActionKind; import org.eclipse.lsp4j.CodeActionParams; import org.eclipse.lsp4j.Diagnostic; +import org.eclipse.lsp4j.Range; +import org.eclipse.lsp4j.jsonrpc.messages.Either; import java.util.Collections; import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -50,10 +54,13 @@ public List getCodeActions(CodeActionParams params, DocumentContext return Collections.emptyList(); } - List computedDiagnostics = documentContext.getComputedDiagnostics(); + Set computedDiagnostics = documentContext.getComputedDiagnostics() + .stream() + .map(LightDiagnostic::new) + .collect(Collectors.toSet()); Stream diagnosticStream = incomingDiagnostics.stream() - .filter(computedDiagnostics::contains); + .filter(diagnostic -> computedDiagnostics.contains(new LightDiagnostic(diagnostic))); return processDiagnosticStream(diagnosticStream, params, documentContext) .collect(Collectors.toList()); @@ -65,4 +72,17 @@ protected abstract Stream processDiagnosticStream( CodeActionParams params, DocumentContext documentContext ); + + @Value + private static class LightDiagnostic { + Either code; + Range range; + String source; + + public LightDiagnostic(Diagnostic diagnostic) { + this.code = diagnostic.getCode(); + this.range = diagnostic.getRange(); + this.source = diagnostic.getSource(); + } + } } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/codeactions/DisableDiagnosticTriggeringSupplier.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/codeactions/DisableDiagnosticTriggeringSupplier.java new file mode 100644 index 00000000000..7caa1a49cf7 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/codeactions/DisableDiagnosticTriggeringSupplier.java @@ -0,0 +1,238 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.codeactions; + +import com.github._1c_syntax.bsl.languageserver.configuration.LanguageServerConfiguration; +import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; +import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticCode; +import com.github._1c_syntax.bsl.languageserver.utils.Ranges; +import com.github._1c_syntax.bsl.languageserver.utils.Resources; +import org.antlr.v4.runtime.Token; +import org.eclipse.lsp4j.CodeAction; +import org.eclipse.lsp4j.CodeActionKind; +import org.eclipse.lsp4j.CodeActionParams; +import org.eclipse.lsp4j.Diagnostic; +import org.eclipse.lsp4j.Range; +import org.eclipse.lsp4j.TextEdit; +import org.eclipse.lsp4j.WorkspaceEdit; +import org.jetbrains.annotations.NotNull; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + + +@Component +public class DisableDiagnosticTriggeringSupplier implements CodeActionSupplier { + + private static final String ALL_DIAGNOSTIC_NAME = ""; + private final LanguageServerConfiguration languageServerConfiguration; + + public DisableDiagnosticTriggeringSupplier(LanguageServerConfiguration languageServerConfiguration) { + this.languageServerConfiguration = languageServerConfiguration; + } + + /** + * При необходимости создает {@code CodeAction} для создания служебного комментария отключающего срабатывание + * диагностики. + * Может быть в трех вариантах: + * 1. Отключаются срабатывания в конкретной строке + * 2. Отключаются срабатывания в области между парой комментариев + * 3. Отключаются срабатывания во всем файле + * + * @param params параметры вызова генерации {@code codeAction} + * @param documentContext представление программного модуля + * @return {@code List} если модуль не содержит всех стандартных областей, + * пустой {@code List} если генерация областей не требуется + */ + @Override + public List getCodeActions(CodeActionParams params, DocumentContext documentContext) { + List result = new ArrayList<>(); + + if (!params.getContext().getDiagnostics().isEmpty()) { + if (params.getRange().getStart() != null && params.getRange().getEnd() != null) { + var selectedLineNumber = params.getRange().getEnd().getLine() + 1; + + documentContext + .getTokens() + .stream() + .filter(token -> token.getLine() == selectedLineNumber) + .max(Comparator.comparingInt(Token::getCharPositionInLine)) + .ifPresent(token -> { + if (params.getRange().getStart().getLine() == params.getRange().getEnd().getLine()) { + result.addAll(getDisableActionForLine(params, documentContext, token)); + } else { + result.addAll(getDisableActionForRange(params, documentContext, token)); + } + } + ); + } + + result.addAll( + actionDisableDiagnostic( + name -> createCodeAction( + getMessage("file", name), + createInFileTextEdits(":" + name), + documentContext + ), + params + ) + ); + } + + result.add( + createCodeAction( + getMessage("fileAll"), + createInFileTextEdits(ALL_DIAGNOSTIC_NAME), + documentContext + ) + ); + return new ArrayList<>(result); + } + + private List getDisableActionForLine( + CodeActionParams params, + DocumentContext documentContext, + Token lastToken + ) { + var result = actionDisableDiagnostic( + name -> createCodeAction( + getMessage("line", name), + createInLineTextEdits(":" + name, lastToken, params), + documentContext + ), + params + ); + result.add( + createCodeAction( + getMessage("lineAll"), + createInLineTextEdits(ALL_DIAGNOSTIC_NAME, lastToken, params), + documentContext + ) + ); + return result; + } + + private List getDisableActionForRange( + CodeActionParams params, + DocumentContext documentContext, + Token lastToken + ) { + var result = actionDisableDiagnostic( + name -> createCodeAction( + getMessage("range", name), + createInRegionTextEdits(":" + name, lastToken, params), + documentContext + ), + params + ); + result.add( + createCodeAction( + getMessage("rangeAll"), + createInRegionTextEdits(ALL_DIAGNOSTIC_NAME, lastToken, params), + documentContext + ) + ); + return result; + } + + private List actionDisableDiagnostic(Function func, CodeActionParams params) { + return params.getContext() + .getDiagnostics() + .stream() + .map(Diagnostic::getCode) + .map(DiagnosticCode::getStringValue) + .distinct() + .map(func) + .collect(Collectors.toList()); + } + + private List createInRegionTextEdits(String diagnosticName, Token last, CodeActionParams params) { + List edits = new ArrayList<>(); + + Range disableRange = Ranges.create( + params.getRange().getStart().getLine(), + 0, + params.getRange().getStart().getLine(), + 0 + ); + TextEdit disableTextEdit = new TextEdit(disableRange, String.format("// BSLLS%s-off%n", diagnosticName)); + edits.add(disableTextEdit); + + Range enableRange = Ranges.create( + params.getRange().getEnd().getLine(), + last.getCharPositionInLine() + last.getText().length(), + params.getRange().getEnd().getLine(), + last.getCharPositionInLine() + last.getText().length() + ); + TextEdit enableTextEdit = new TextEdit(enableRange, String.format("%n// BSLLS%s-on%n", diagnosticName)); + edits.add(enableTextEdit); + return edits; + } + + private List createInFileTextEdits(String diagnosticName) { + TextEdit textEdit = new TextEdit( + Ranges.create(0, 0, 0, 0), + String.format("// BSLLS%s-off%n", diagnosticName) + ); + return Collections.singletonList(textEdit); + } + + @NotNull + private CodeAction createCodeAction(String title, List edits, DocumentContext documentContext) { + Map> changes = Map.of(documentContext.getUri().toString(), edits); + WorkspaceEdit edit = new WorkspaceEdit(); + edit.setChanges(changes); + + CodeAction codeAction = new CodeAction(title); + codeAction.setDiagnostics(new ArrayList<>()); + codeAction.setKind(CodeActionKind.Refactor); + codeAction.setEdit(edit); + return codeAction; + } + + private String getMessage(String key) { + return Resources.getResourceString(languageServerConfiguration.getLanguage(), this.getClass(), key); + } + + private String getMessage(String key, Object... args) { + return Resources.getResourceString(languageServerConfiguration.getLanguage(), this.getClass(), key, args); + } + + private static List createInLineTextEdits(String diagnosticName, Token last, CodeActionParams params) { + Range range = Ranges.create( + params.getRange().getStart().getLine(), + last.getCharPositionInLine() + last.getText().length(), + params.getRange().getStart().getLine(), + last.getCharPositionInLine() + last.getText().length() + ); + + TextEdit textEdit = new TextEdit(range, String.format(" // BSLLS%s-off", diagnosticName)); + return Collections.singletonList(textEdit); + } + +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/CodeLensSupplier.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/CodeLensSupplier.java new file mode 100644 index 00000000000..019257848ce --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/CodeLensSupplier.java @@ -0,0 +1,31 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.codelenses; + +import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; +import org.eclipse.lsp4j.CodeLens; + +import java.util.List; + +public interface CodeLensSupplier { + List getCodeLenses(DocumentContext documentContext); +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/CognitiveComplexityCodeLensSupplier.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/CognitiveComplexityCodeLensSupplier.java new file mode 100644 index 00000000000..75ec763a0cd --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/CognitiveComplexityCodeLensSupplier.java @@ -0,0 +1,69 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.codelenses; + +import com.github._1c_syntax.bsl.languageserver.configuration.LanguageServerConfiguration; +import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; +import com.github._1c_syntax.bsl.languageserver.context.symbol.MethodSymbol; +import lombok.RequiredArgsConstructor; +import org.eclipse.lsp4j.CodeLens; +import org.eclipse.lsp4j.Command; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +@Component +@RequiredArgsConstructor +public class CognitiveComplexityCodeLensSupplier implements CodeLensSupplier { + + private final LanguageServerConfiguration configuration; + + @Override + public List getCodeLenses(DocumentContext documentContext) { + + if (!configuration.getCodeLensOptions().isShowCognitiveComplexity()) { + return Collections.emptyList(); + } + + Map methodsComplexity = documentContext.getCognitiveComplexityData() + .getMethodsComplexity(); + + List codeLenses = new ArrayList<>(methodsComplexity.size()); + + methodsComplexity.forEach((MethodSymbol methodSymbol, Integer complexity) -> { + String title = String.format("Cognitive complexity is %d", complexity); + Command command = new Command(title, ""); + CodeLens codeLens = new CodeLens( + methodSymbol.getSubNameRange(), + command, + null + ); + + codeLenses.add(codeLens); + }); + + return codeLenses; + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/CyclomaticComplexityCodeLensSupplier.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/CyclomaticComplexityCodeLensSupplier.java new file mode 100644 index 00000000000..23610668064 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/CyclomaticComplexityCodeLensSupplier.java @@ -0,0 +1,69 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.codelenses; + +import com.github._1c_syntax.bsl.languageserver.configuration.LanguageServerConfiguration; +import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; +import com.github._1c_syntax.bsl.languageserver.context.symbol.MethodSymbol; +import lombok.RequiredArgsConstructor; +import org.eclipse.lsp4j.CodeLens; +import org.eclipse.lsp4j.Command; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +@Component +@RequiredArgsConstructor +public class CyclomaticComplexityCodeLensSupplier implements CodeLensSupplier { + + private final LanguageServerConfiguration configuration; + + @Override + public List getCodeLenses(DocumentContext documentContext) { + + if (!configuration.getCodeLensOptions().isShowCyclomaticComplexity()) { + return Collections.emptyList(); + } + + Map methodsComplexity = documentContext.getCyclomaticComplexityData() + .getMethodsComplexity(); + + List codeLenses = new ArrayList<>(methodsComplexity.size()); + + methodsComplexity.forEach((MethodSymbol methodSymbol, Integer complexity) -> { + String title = String.format("Cyclomatic complexity is %d", complexity); + Command command = new Command(title, ""); + CodeLens codeLens = new CodeLens( + methodSymbol.getSubNameRange(), + command, + null + ); + + codeLenses.add(codeLens); + }); + + return codeLenses; + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/package-info.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/package-info.java new file mode 100644 index 00000000000..580ff867ae5 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/package-info.java @@ -0,0 +1,25 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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. + */ +@ParametersAreNonnullByDefault +package com.github._1c_syntax.bsl.languageserver.codelenses; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/codelens/package-info.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/codelens/package-info.java index 8648ddebe11..6e2d789b2d2 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/codelens/package-info.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/codelens/package-info.java @@ -19,7 +19,6 @@ * You should have received a copy of the GNU Lesser General Public * License along with BSL Language Server. */ - /** * Пакет содержит настройки {@link com.github._1c_syntax.bsl.languageserver.providers.CodeLensProvider} */ diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/diagnostics/DiagnosticsOptions.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/diagnostics/DiagnosticsOptions.java index f53e3977293..991638c2238 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/diagnostics/DiagnosticsOptions.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/diagnostics/DiagnosticsOptions.java @@ -23,6 +23,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.github._1c_syntax.bsl.languageserver.configuration.diagnostics.databind.ParametersDeserializer; import lombok.AllArgsConstructor; @@ -44,6 +45,7 @@ public class DiagnosticsOptions { private ComputeTrigger computeTrigger = ComputeTrigger.ONSAVE; private SkipSupport skipSupport = SkipSupport.NEVER; private Mode mode = Mode.ON; + private boolean ordinaryAppSupport = true; @JsonDeserialize(using = ParametersDeserializer.class) private Map>> parameters = new HashMap<>(); diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/documentlink/package-info.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/documentlink/package-info.java index 2c15f7357ea..125c0dc67ed 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/documentlink/package-info.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/documentlink/package-info.java @@ -19,7 +19,6 @@ * You should have received a copy of the GNU Lesser General Public * License along with BSL Language Server. */ - /** * Пакет содержит настройки {@link com.github._1c_syntax.bsl.languageserver.providers.DocumentLinkProvider} */ diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/package-info.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/package-info.java index f1f647eb85c..a4451c55cf2 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/package-info.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/package-info.java @@ -19,7 +19,6 @@ * You should have received a copy of the GNU Lesser General Public * License along with BSL Language Server. */ - /** * В пакете содержатся классы для конфигурирования BSL Language Server. *

diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/watcher/package-info.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/watcher/package-info.java index 15ee0a330f2..e9da672b2ef 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/watcher/package-info.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/watcher/package-info.java @@ -19,7 +19,6 @@ * You should have received a copy of the GNU Lesser General Public * License along with BSL Language Server. */ - /** * В пакете содержатся классы, относящиеся к отслеживанию факта изменения (удаление, создание, редактирование) файла * конфигурации ({@link com.github._1c_syntax.bsl.languageserver.configuration.LanguageServerConfiguration}). diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentContext.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentContext.java index 866d5deda06..dc743af79bc 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentContext.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentContext.java @@ -42,6 +42,7 @@ import com.github._1c_syntax.mdclasses.metadata.additional.ModuleType; import com.github._1c_syntax.mdclasses.metadata.additional.SupportVariant; import com.github._1c_syntax.utils.Lazy; +import lombok.Getter; import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.tree.TerminalNodeImpl; import org.antlr.v4.runtime.tree.Tree; @@ -67,6 +68,8 @@ public class DocumentContext { private final URI uri; private String content; + @Getter + private int version; private final ServerContext context; private final DiagnosticComputer diagnosticComputer; @@ -92,9 +95,16 @@ public class DocumentContext { private final Lazy> queries = new Lazy<>(this::computeQueries, computeLock); - public DocumentContext(URI uri, String content, ServerContext context, DiagnosticComputer diagnosticComputer) { + public DocumentContext( + URI uri, + String content, + ServerContext context, + int version, + DiagnosticComputer diagnosticComputer + ) { this.uri = uri; this.content = content; + this.version = version; this.context = context; this.diagnosticComputer = diagnosticComputer; @@ -219,28 +229,46 @@ public List getComputedDiagnostics() { .orElseGet(Collections::emptyList); } - public void rebuild(String content) { + public void rebuild(String content, int version) { computeLock.lock(); + + boolean versionMatches = version == this.version && version != 0; + boolean contentWasCleared = this.content == null; + + if (versionMatches && !contentWasCleared) { + clearDependantData(); + computeLock.unlock(); + return; + } + clearSecondaryData(); symbolTree.clear(); this.content = content; tokenizer = new BSLTokenizer(content); + this.version = version; computeLock.unlock(); } public void clearSecondaryData() { computeLock.lock(); - diagnosticsLock.lock(); content = null; contentList.clear(); tokenizer = null; - cognitiveComplexityData.clear(); cyclomaticComplexityData.clear(); metrics.clear(); diagnosticIgnoranceData.clear(); - diagnostics.clear(); queries.clear(); + clearDependantData(); + computeLock.unlock(); + } + + private void clearDependantData() { + computeLock.lock(); + diagnosticsLock.lock(); + + diagnostics.clear(); + diagnosticsLock.unlock(); computeLock.unlock(); } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/ServerContext.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/ServerContext.java index 37eff00d9af..7f64234b03a 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/ServerContext.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/ServerContext.java @@ -84,7 +84,7 @@ public void populateContext(Collection uris) { uris.parallelStream().forEach((File file) -> { DocumentContext documentContext = getDocument(file.toURI()); if (documentContext == null) { - documentContext = createDocumentContext(file); + documentContext = createDocumentContext(file, 0); documentContext.getSymbolTree(); documentContext.clearSecondaryData(); } @@ -120,14 +120,14 @@ public Map getDocuments(String mdoRef) { return documentsByMDORef.getOrDefault(mdoRef, Collections.emptyMap()); } - public DocumentContext addDocument(URI uri, String content) { + public DocumentContext addDocument(URI uri, String content, int version) { contextLock.readLock().lock(); DocumentContext documentContext = getDocument(uri); if (documentContext == null) { - documentContext = createDocumentContext(uri, content); + documentContext = createDocumentContext(uri, content, version); } else { - documentContext.rebuild(content); + documentContext.rebuild(content, version); } contextLock.readLock().unlock(); @@ -135,7 +135,11 @@ public DocumentContext addDocument(URI uri, String content) { } public DocumentContext addDocument(TextDocumentItem textDocumentItem) { - return addDocument(URI.create(textDocumentItem.getUri()), textDocumentItem.getText()); + return addDocument( + URI.create(textDocumentItem.getUri()), + textDocumentItem.getText(), + textDocumentItem.getVersion() + ); } public void removeDocument(URI uri) { @@ -156,18 +160,18 @@ public Configuration getConfiguration() { } @Lookup - protected abstract DocumentContext lookupDocumentContext(URI absoluteURI, String content); + protected abstract DocumentContext lookupDocumentContext(URI absoluteURI, String content, int version); @SneakyThrows - private DocumentContext createDocumentContext(File file) { + private DocumentContext createDocumentContext(File file, int version) { String content = FileUtils.readFileToString(file, StandardCharsets.UTF_8); - return createDocumentContext(file.toURI(), content); + return createDocumentContext(file.toURI(), content, version); } - private DocumentContext createDocumentContext(URI uri, String content) { + private DocumentContext createDocumentContext(URI uri, String content, int version) { URI absoluteURI = Absolute.uri(uri); - DocumentContext documentContext = lookupDocumentContext(absoluteURI, content); + DocumentContext documentContext = lookupDocumentContext(absoluteURI, content, version); documents.put(absoluteURI, documentContext); addMdoRefByUri(absoluteURI, documentContext); diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/computer/MethodSymbolComputer.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/computer/MethodSymbolComputer.java index ca7633db545..91be6b9aff0 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/computer/MethodSymbolComputer.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/computer/MethodSymbolComputer.java @@ -40,6 +40,7 @@ import org.antlr.v4.runtime.tree.ErrorNode; import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.TerminalNode; +import org.eclipse.lsp4j.Range; import javax.annotation.Nullable; import java.util.ArrayList; @@ -231,6 +232,7 @@ private static List createParameters(@Nullable BSLParser.Pa .name(getParameterName(param.IDENTIFIER())) .byValue(param.VAL_KEYWORD() != null) .optional(param.defaultValue() != null) + .range(getParameterRange(param)) .build() ).collect(Collectors.toList()); } @@ -241,6 +243,13 @@ private static String getParameterName(TerminalNode identifier) { .orElse(""); } + private static Range getParameterRange(BSLParser.ParamContext param) { + if(param.IDENTIFIER() == null) { + return Ranges.create(param.start); + } + return Ranges.create(param.IDENTIFIER()); + } + private static List getAnnotations(List annotationContext) { return annotationContext.stream() .map(MethodSymbolComputer::createAnnotation) 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 136de1ca6ab..604999d321f 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 @@ -40,12 +40,32 @@ public class QueryComputer extends BSLParserBaseVisitor implements Co private final DocumentContext documentContext; private final List queries = new ArrayList<>(); + /** + * Ключевые слова для поиска потенциально запросных строк + */ private static final Pattern QUERIES_ROOT_KEY = CaseInsensitivePattern.compile( - "select|выбрать|drop|уничтожить"); - private static final Pattern QUERIES_STARTING_QUOTE = CaseInsensitivePattern.compile("^\\s*\""); + "(?:[\\s\";]|^)(?:select|выбрать|drop|уничтожить)(?:\\s|$)"); + private static final Pattern NON_QUERIES_START = CaseInsensitivePattern.compile( + "(?:^\\s*(?:(?:\\|)|(?:\"\")))"); + + /** + * Минимальная строка для анализа + */ private static final int MINIMAL_QUERY_STRING_LENGTH = 8; + /** + * Поиск сдвоенных кавычек + */ + private static final Pattern QUOTE_LINE_PATTERN = CaseInsensitivePattern.compile( + "(?:\"{12}|\"{10}|\"{8}|\"{6}|\"{4}|\"{2})"); + + /** + * Поиск первой кавычки в строке + */ + private static final Pattern FIRST_QUOTE_PATTERN = CaseInsensitivePattern.compile( + "^\\s*(\")"); + public QueryComputer(DocumentContext documentContext) { this.documentContext = documentContext; } @@ -74,18 +94,44 @@ public ParseTree visitString(BSLParser.StringContext ctx) { boolean isQuery = false; + // конкатенация строк в одну + int prevTokenLine = -1; + String partString = ""; var strings = new StringJoiner("\n"); for (Token token : ctx.getTokens()) { - var partString = getString(startLine, token); + + // бывает несколько токенов строки в одной строе файла + // добавляем часть строки только в случае находления ее на другой строке файла + if (token.getLine() != prevTokenLine && prevTokenLine != -1) { + strings.add(partString); + partString = ""; + } + + // если новый токен строки находится на той же строке файла, что и предыдущий, то добавляем его к ней + if (token.getLine() == prevTokenLine && prevTokenLine != -1) { + String newString = getString(startLine, token); + partString = newString.substring(partString.length()); + } else { + partString = getString(startLine, token); + } + + // проверяем подстроку на вероятность запроса if (!isQuery) { - isQuery = QUERIES_ROOT_KEY.matcher(partString).find(); + isQuery = QUERIES_ROOT_KEY.matcher(partString).find() + && !NON_QUERIES_START.matcher(partString).find(); } - strings.add(partString); + startLine = token.getLine(); + prevTokenLine = token.getLine(); + } + + // последнюю часть тоже необходимо добавить к общему тексту + if (!partString.isEmpty()) { + strings.add(partString); } if (isQuery) { - queries.add(new SDBLTokenizer(startEmptyLines + removeExtremeQuotes(strings.toString()))); + queries.add(new SDBLTokenizer(startEmptyLines + removeDoubleQuotes(strings.toString()))); } return ctx; @@ -95,13 +141,37 @@ public ParseTree visitString(BSLParser.StringContext ctx) { private static String getString(int startLine, Token token) { var string = addEmptyLines(startLine, token) + " ".repeat(token.getCharPositionInLine()); if (token.getText().startsWith("|")) { - string += " " + token.getText().substring(1); + string += " " + trimLastQuote(token.getText().substring(1)); } else { - string += token.getText(); + string += trimQuotes(token.getText()); } return string; } + private static String trimLastQuote(String text) { + var quoteCount = text.length() - text.replace("\"", "").length(); + if (quoteCount % 2 == 1) { + String newString; + var quotePosition = text.lastIndexOf("\""); + newString = text.substring(0, quotePosition) + " "; + if (quotePosition + 1 < text.length()) { + newString += text.substring(quotePosition + 1); + } + return newString; + } + return text; + } + + private static String trimQuotes(String text) { + var matcher = FIRST_QUOTE_PATTERN.matcher(text); + if (matcher.find()) { + var newText = text.substring(0, matcher.start(1)) + " " + text.substring(matcher.end(1)); + return trimLastQuote(newText); + } + + return text; + } + private static String addEmptyLines(int startLine, Token token) { if (token.getLine() > startLine + 1) { return "\n".repeat(token.getLine() - startLine - 1); @@ -109,13 +179,34 @@ private static String addEmptyLines(int startLine, Token token) { return ""; } - private static String removeExtremeQuotes(String text) { - if (QUERIES_STARTING_QUOTE.matcher(text).find()) { - // Кавычка может быть не первым символом строки - var quoteIndex = text.indexOf("\""); - return text.substring(0, quoteIndex) + " " + text.substring(quoteIndex + 1, text.length() - 1); + private static String removeDoubleQuotes(String text) { + var leftQuoteFound = false; + var matcher = QUOTE_LINE_PATTERN.matcher(text); + var newText = text; + var textLength = text.length(); + var strings = new StringJoiner(""); + while (matcher.find()) { + var quotesLineLength = matcher.group(0).length(); + var emptyString = (" ".repeat(quotesLineLength / 2)).intern(); + strings.add(newText.substring(0, matcher.start()) + (leftQuoteFound ? "" : emptyString) + + matcher.group(0).substring(0, quotesLineLength / 2) + (leftQuoteFound ? emptyString : "")); + + if (matcher.end() < textLength) { + newText = newText.substring(matcher.end()); + textLength = newText.length(); + } else { + newText = ""; + break; + } + + matcher = QUOTE_LINE_PATTERN.matcher(newText); + leftQuoteFound = !leftQuoteFound; } - return text; + if (!newText.isEmpty()) { + strings.add(newText); + } + + return strings.toString(); } } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/infrastructure/DocumentContextConfiguration.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/infrastructure/DocumentContextConfiguration.java index 6ee824291b3..93b83409085 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/infrastructure/DocumentContextConfiguration.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/infrastructure/DocumentContextConfiguration.java @@ -40,10 +40,10 @@ public class DocumentContextConfiguration { @Bean @Scope("prototype") - public DocumentContext documentContext(URI uri, String content) { + public DocumentContext documentContext(URI uri, String content, int version) { var serverContext = applicationContext.getBean(ServerContext.class); var diagnosticComputer = applicationContext.getBean(DiagnosticComputer.class); - return new DocumentContext(uri, content, serverContext, diagnosticComputer); + return new DocumentContext(uri, content, serverContext, version, diagnosticComputer); } } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/MethodDescription.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/MethodDescription.java index bbe9699b07c..c88d0177bbf 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/MethodDescription.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/MethodDescription.java @@ -21,44 +21,90 @@ */ package com.github._1c_syntax.bsl.languageserver.context.symbol; -import com.github._1c_syntax.utils.CaseInsensitivePattern; -import lombok.Getter; +import com.github._1c_syntax.bsl.languageserver.context.symbol.description.DescriptionReader; +import com.github._1c_syntax.bsl.languageserver.context.symbol.description.ParameterDescription; +import com.github._1c_syntax.bsl.languageserver.context.symbol.description.TypeDescription; +import com.github._1c_syntax.bsl.parser.BSLMethodDescriptionParser; +import com.github._1c_syntax.bsl.parser.BSLMethodDescriptionTokenizer; +import lombok.Value; import org.antlr.v4.runtime.Token; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import java.util.stream.Collectors; -public class MethodDescription { +import static java.util.Objects.requireNonNull; - private static final int COMMENT_LENGTH = 2; - private static final Pattern DEPRECATED_PATTERN - = CaseInsensitivePattern.compile("(?:\\s*)(?:Устарела|Deprecated)\\.(.*)"); +/** + * Класс-описание метода (процедуры или функции) + */ +@Value +public class MethodDescription { - private final int startLine; - private final int endLine; - @Getter - private final String description; + /** + * Номер первой строки описания + */ + int startLine; + /** + * Номер последней строки описания + */ + int endLine; + /** + * Содержит полное описание метода (весь текст) + */ + String description; + /** + * Содержит часть строки после ключевого слова, в которой должно быть + * описание причины устаревания метода либо альтернативы + */ + String deprecationInfo; - @Getter - private final String deprecationInfo; - @Getter - private final boolean deprecated; + /** + * Признак устарения метода + */ + boolean deprecated; + /** + * Описание назначения метода + */ + String purposeDescription; + /** + * Примеры использования метода + */ + List examples; + /** + * Варианты вызова метода + */ + List callOptions; + /** + * Параметры метода с типами и описанием + */ + List parameters; + /** + * Возвращаемые значения (типы) + */ + List returnedValue; + /** + * Если описание содержит только ссылку, то здесь будет ее значение + *

+ * TODO Временное решение, надо будет продумать в следующем релизе + */ + String link; public MethodDescription(List comments) { description = comments.stream() .map(Token::getText) - .map(MethodDescription::uncomment) .collect(Collectors.joining("\n")); - Matcher matcher = DEPRECATED_PATTERN.matcher(description); - if (matcher.find()) { - deprecationInfo = matcher.group(1); - deprecated = true; - } else { - deprecationInfo = ""; - deprecated = false; - } + + var tokenizer = new BSLMethodDescriptionTokenizer(description); + var ast = requireNonNull(tokenizer.getAst()); + + purposeDescription = DescriptionReader.readPurposeDescription(ast); + link = DescriptionReader.readLink(ast); + deprecated = ast.deprecate() != null; + deprecationInfo = DescriptionReader.readDeprecationInfo(ast); + callOptions = DescriptionReader.readExamples(ast, BSLMethodDescriptionParser.RULE_callOptionsString); + examples = DescriptionReader.readExamples(ast, BSLMethodDescriptionParser.RULE_examplesString); + parameters = DescriptionReader.readParameters(ast); + returnedValue = DescriptionReader.readReturnedValue(ast); if (comments.isEmpty()) { startLine = 0; @@ -80,12 +126,4 @@ public boolean contains(Token first, Token last) { return (firstLine >= startLine && lastLine <= endLine); } - private static String uncomment(String text) { - String result = text; - if (result.startsWith("//")) { - result = result.substring(COMMENT_LENGTH); - } - return result; - } - } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/ParameterDefinition.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/ParameterDefinition.java index 7da5671b7b5..ea9c988a757 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/ParameterDefinition.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/ParameterDefinition.java @@ -23,6 +23,7 @@ import lombok.Builder; import lombok.Value; +import org.eclipse.lsp4j.Range; /** * Класс хранит информацию о параметре метода. @@ -34,4 +35,5 @@ public class ParameterDefinition { String name; boolean byValue; boolean optional; + Range range; } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/RegionSymbol.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/RegionSymbol.java index becd86eac17..9c5741c864e 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/RegionSymbol.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/RegionSymbol.java @@ -21,7 +21,6 @@ */ package com.github._1c_syntax.bsl.languageserver.context.symbol; -import lombok.AccessLevel; import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -38,7 +37,7 @@ import java.util.stream.Collectors; @Value -@Builder(access = AccessLevel.PUBLIC) +@Builder(access = lombok.AccessLevel.PUBLIC) @EqualsAndHashCode(exclude = {"children", "parent"}) @ToString(exclude = {"children", "parent"}) public class RegionSymbol implements Symbol { diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/annotations/package-info.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/annotations/package-info.java index 7720d5c6ea5..d9d815e55cc 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/annotations/package-info.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/annotations/package-info.java @@ -19,7 +19,6 @@ * You should have received a copy of the GNU Lesser General Public * License along with BSL Language Server. */ - /** * В пакете содержатся data-классы для представления аннотаций и директив компиляции. */ diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/description/DescriptionReader.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/description/DescriptionReader.java new file mode 100644 index 00000000000..196356f570c --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/description/DescriptionReader.java @@ -0,0 +1,434 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.context.symbol.description; + +import com.github._1c_syntax.bsl.languageserver.utils.Trees; +import com.github._1c_syntax.bsl.parser.BSLMethodDescriptionParser; +import com.github._1c_syntax.bsl.parser.BSLParserRuleContext; +import lombok.experimental.UtilityClass; +import org.antlr.v4.runtime.tree.ParseTree; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.StringJoiner; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; + +/** + * Вспомогательный класс для чтения данных из описания метода + */ +@UtilityClass +public class DescriptionReader { + + private static final int HYPERLINK_REF_LEN = 4; + + /** + * Выполняет разбор прочитанного AST дерева описания метода и формирует список описаний параметров метода + * + * @param ctx Дерево описания метода + * @return Список описаний параметров метода + */ + public static List readParameters(BSLMethodDescriptionParser.MethodDescriptionContext ctx) { + + List result = new ArrayList<>(); + var current = new TempParameterData(); + var strings = getParametersStrings(ctx); + for (BSLMethodDescriptionParser.ParametersStringContext string : strings) { + + // найдем дочерние ноды. на самом деле должна быть либо одна указанная нода, либо ни одной, что заставляет + // считать строку как описание + var child = Trees.findAllRuleNodes(string, + BSLMethodDescriptionParser.RULE_parameterString, BSLMethodDescriptionParser.RULE_subParameterString, + BSLMethodDescriptionParser.RULE_typeWithDescription) + .stream() + .findFirst(); + + // сразу необходимо обыграть неклассифицированную строку + if (child.isEmpty()) { + current = readUnknownParameterString(result, current, string); + } else { + var parameterPart = (BSLParserRuleContext) child.get(); + current = readSpecialParameterString(result, current, parameterPart); + } + } + + // не забываем сохранить последний прочитанный параметр + saveLastParameter(current, result); + return result; + } + + /** + * Выполняет разбор прочитанного AST дерева описания метода и формирует список описаний возвращаемых значений + * + * @param ctx Дерево описания метода + * @return Список описаний возвращаемых значений + */ + public static List readReturnedValue(BSLMethodDescriptionParser.MethodDescriptionContext ctx) { + + var current = new TempParameterData(); + var strings = getReturnedValuesStrings(ctx); + for (BSLMethodDescriptionParser.ReturnsValuesStringContext string : strings) { + current.empty = false; + + // найдем дочерние ноды. на самом деле должна быть либо одна указанная нода, либо ни одной, что заставляет + // считать строку как описание + var child = Trees.findAllRuleNodes(string, + BSLMethodDescriptionParser.RULE_returnsValueString, BSLMethodDescriptionParser.RULE_subParameterString, + BSLMethodDescriptionParser.RULE_typeWithDescription) + .stream() + .findFirst(); + + // сразу необходимо обыграть неклассифицированную строку + if (child.isEmpty()) { + // если прочитанных параметров не было, то учтем как тип без описания + if (current.children.isEmpty()) { + current.addType(string.getText()); + } else { + // считаем что текущая строка является продолжением описания прочитанного на шаге ранее + current.appendDescription(string.getText()); + } + } else { + var typePart = (BSLParserRuleContext) child.get(); + // выполняется разбор параметров в зависимости от типа подстроки + if (typePart.getRuleIndex() == BSLMethodDescriptionParser.RULE_subParameterString) { + current.addSubParam((BSLMethodDescriptionParser.SubParameterStringContext) typePart); + } else { + current.addType(typePart); + } + } + } + + return current.getReturnedValueDescription(); + } + + /** + * Выполняет разбор прочитанного AST дерева описания метода и возвращает описание устаревшего метода + * + * @param ctx Дерево описания метода + * @return Описание устаревшего метода + */ + public static String readDeprecationInfo(BSLMethodDescriptionParser.MethodDescriptionContext ctx) { + if (ctx.deprecate() != null) { + var deprecationDescription = ctx.deprecate().deprecateDescription(); + if (deprecationDescription != null) { + return deprecationDescription.getText().strip(); + } + } + return ""; + } + + /** + * Выполняет разбор прочитанного AST дерева описания метода и возвращает список примеров (или вариантов вызова) + * + * @param ctx Дерево описания метода + * @return Список примеров + */ + public static List readExamples(BSLMethodDescriptionParser.MethodDescriptionContext ctx, + int ruleIndex) { + var exampleStringNodes = Trees.findAllRuleNodes(ctx, ruleIndex); + if (exampleStringNodes.isEmpty()) { + return Collections.emptyList(); + } else { + return exampleStringNodes.stream() + .map(parseTree -> parseTree.getText().strip()) + .filter(str -> !str.isEmpty()) + .collect(Collectors.toList()); + } + } + + /** + * Выполняет разбор прочитанного AST дерева описания метода и возвращает описание назначения метода. + * + * @param ctx Дерево описания метода + * @return Описание назначения метода + */ + public static String readPurposeDescription(BSLMethodDescriptionParser.MethodDescriptionContext ctx) { + if (ctx.description() != null) { + var strings = ctx.description().descriptionString(); + if (strings != null) { + return strings.stream() + .map(BSLParserRuleContext::getText) + .collect(Collectors.joining("\n")) + .strip(); + } + } + return ""; + } + + /** + * Выполняет разбор прочитанного AST дерева описания метода и достает описание назначения метода. + * Если описание метода представляет собой только ссылку, то возвращает ее значение, иначе - пустая строка + * + * @param ctx Дерево описания метода + * @return Ссылка в методе + */ + public static String readLink(BSLMethodDescriptionParser.MethodDescriptionContext ctx) { + if (ctx.description() != null) { + var allStrings = ctx.description().descriptionString(); + if (allStrings == null) { + return ""; + } + + // достаем из описания непустые строки + var strings = allStrings.stream() + .filter(stringContext -> !stringContext.getText().isBlank()) + .collect(Collectors.toList()); + if (strings.size() == 1) { + AtomicReference result = new AtomicReference<>(""); + strings.get(0).getTokens(BSLMethodDescriptionParser.HYPERLINK).stream() + .findFirst() + .ifPresent(hyperLink -> result.set(hyperLink.getText().substring(HYPERLINK_REF_LEN))); + + return result.get(); + } + } + return ""; + } + + private List getParametersStrings( + BSLMethodDescriptionParser.MethodDescriptionContext ast) { + if (ast.parameters() != null) { + var strings = ast.parameters().parametersString(); + if (strings != null) { + return strings; + } + } + return Collections.emptyList(); + } + + private List getReturnedValuesStrings( + BSLMethodDescriptionParser.MethodDescriptionContext ast) { + if (ast.returnsValues() != null) { + var strings = ast.returnsValues().returnsValuesString(); + if (strings != null) { + return strings; + } + } + return Collections.emptyList(); + } + + private static TempParameterData readSpecialParameterString(List result, + TempParameterData current, + BSLParserRuleContext ctx) { + // выполняется разбор параметров в зависимости от типа подстроки + if (ctx.getRuleIndex() == BSLMethodDescriptionParser.RULE_parameterString) { + saveLastParameter(current, result); + current = new TempParameterData(ctx); + } else if (ctx.getRuleIndex() == BSLMethodDescriptionParser.RULE_subParameterString) { + current.addSubParam((BSLMethodDescriptionParser.SubParameterStringContext) ctx); + } else { // BSLMethodDescriptionParser.RULE_typeWithDescription + current.addType(ctx); + } + return current; + } + + private static TempParameterData readUnknownParameterString(List result, + TempParameterData current, + BSLParserRuleContext string) { + // Строка может состоят из одного слова и пробелов, запомним на будущее + var isOneWord = string.getTokens().stream() + .filter(t -> t.getType() != BSLMethodDescriptionParser.SPACE + && t.getType() != BSLMethodDescriptionParser.EOL).count() == 1; + + // если прочитанных параметров не было, то учтем как параметр без описания + if (isOneWord && current.isEmpty()) { + current = new TempParameterData(string.getText()); + // некоторые параметры ранее были прочитаны, но если у них нет описания, то учтем как параметр без описания + } else if (isOneWord && current.missingLastDescription()) { + saveLastParameter(current, result); + current = new TempParameterData(string.getText()); + // считаем что текущая строка является продолжением описания параметра, прочитанного на шаге ранее + } else { + current.appendDescription(string.getText()); + } + return current; + } + + private static void saveLastParameter(TempParameterData current, List result) { + if (current.isEmpty()) { + return; + } + result.add(current.getParameterDescription()); + } + + /** + * Служебный класс для временного хранения прочитанной информации из описания параметра + */ + private static class TempParameterData { + private String name; + private final StringJoiner description; + private boolean empty; + private final List children; + private TempParameterData last; + private TempParameterData parent; + private int level; + + TempParameterData() { + name = ""; + description = new StringJoiner("\n"); + empty = true; + children = new ArrayList<>(); + level = 0; + } + + TempParameterData(String text) { + this(); + name = text.strip(); + empty = false; + } + + TempParameterData(BSLParserRuleContext ctx) { + this(); + readAndAddType(ctx); + } + + TempParameterData(BSLParserRuleContext ctx, TempParameterData current) { + this(); + level = current.level + 1; + parent = current; + readAndAddType(ctx); + } + + TempParameterData(String text, TempParameterData current) { + this(text); + level = current.level; + parent = current; + } + + private void readAndAddType(BSLParserRuleContext ctx) { + Trees.getFirstChild(ctx, BSLMethodDescriptionParser.RULE_parameterName) + .ifPresent((BSLParserRuleContext child) -> { + name = child.getText(); + empty = false; + addType(ctx); + }); + } + + private boolean isEmpty() { + return empty; + } + + private void appendDescription(ParseTree ctx) { + appendDescription(ctx.getText()); + } + + private void appendDescription(String text) { + if (!isEmpty()) { + if (last == null) { + description.add(text.strip()); + } else { + last.appendDescription(text); + } + } + } + + private void addType(BSLParserRuleContext ctx) { + if (isEmpty()) { + return; + } + + if (last != null && !last.children.isEmpty()) { + last.addType(ctx); + } else if (ctx.getRuleIndex() == BSLMethodDescriptionParser.RULE_typeWithDescription + || ctx.getRuleIndex() == BSLMethodDescriptionParser.RULE_returnsValueString) { + addNewType(ctx); + } else { + Trees.getFirstChild(ctx, BSLMethodDescriptionParser.RULE_typeWithDescription) + .ifPresent(this::addNewType); + } + } + + private void addType(String text) { + var newType = new TempParameterData(text, this); + children.add(newType); + last = newType; + } + + private void addNewType(BSLParserRuleContext ctx) { + last = null; + Trees.getFirstChild(ctx, BSLMethodDescriptionParser.RULE_types).ifPresent( + (BSLParserRuleContext typeString) -> { + var newType = new TempParameterData(typeString.getText(), this); + Trees.findAllRuleNodes(ctx, BSLMethodDescriptionParser.RULE_typeDescription) + .stream().findFirst() + .ifPresent(newType::appendDescription); + children.add(newType); + last = newType; + }); + } + + private void addSubParam(BSLMethodDescriptionParser.SubParameterStringContext ctx) { + if (isEmpty()) { + return; + } + + // если тип не определен был, то подчиненных параметров быть не может + if (last == null) { + appendDescription(ctx.getText()); + return; + } + var child = ctx.starPreffix(); + var subParamLevel = child.getText().length(); + TempParameterData subParameter; + if (last.level >= subParamLevel) { + while (last.level >= subParamLevel) { + last = last.parent; + } + } + subParameter = new TempParameterData(ctx, last); + last.children.add(subParameter); + last = subParameter.last; + } + + private boolean missingLastDescription() { + if (last != null) { + return last.missingLastDescription(); + } + return description.toString().isEmpty(); + } + + private ParameterDescription getParameterDescription() { + var parameterTypes = children.stream() + .map((TempParameterData child) -> { + List subParameters = new ArrayList<>(); + if (!child.children.isEmpty()) { + child.children.forEach(subParam -> subParameters.add(subParam.getParameterDescription())); + } + return new TypeDescription(child.name, child.description.toString(), subParameters); + }).collect(Collectors.toList()); + + var descriptionStr = description.toString(); + if (descriptionStr.isEmpty() && parameterTypes.size() == 1) { + descriptionStr = parameterTypes.get(0).getDescription(); + } + return new ParameterDescription(name, parameterTypes, descriptionStr); + } + + private List getReturnedValueDescription() { + if (!isEmpty()) { + return getParameterDescription().getTypes(); + } + return Collections.emptyList(); + } + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/description/ParameterDescription.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/description/ParameterDescription.java new file mode 100644 index 00000000000..009a24c98e9 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/description/ParameterDescription.java @@ -0,0 +1,47 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.context.symbol.description; + +import lombok.AllArgsConstructor; +import lombok.Value; + +import java.util.List; + +/** + * Описание параметра из комментария - описания метода + */ +@AllArgsConstructor +@Value +public class ParameterDescription { + /** + * Имя параметра + */ + String name; + /** + * Возможные типы параметра. Может быть пустым + */ + List types; + /** + * Описание параметра. TODO а зачем, если все привязано к типам? + */ + String description; +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/description/TypeDescription.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/description/TypeDescription.java new file mode 100644 index 00000000000..be82f25af5f --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/description/TypeDescription.java @@ -0,0 +1,47 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.context.symbol.description; + +import lombok.AllArgsConstructor; +import lombok.Value; + +import java.util.List; + +/** + * Описание типа параметра, прочитанного из описания метода + */ +@AllArgsConstructor +@Value +public class TypeDescription { + /** + * Имя типа. На данный момент может быть строковый массив перечисления типов а также гиперссылка на метод + */ + String name; + /** + * Описание типа. Может быть пустым + */ + String description; + /** + * Параметры (ключи или поля) типа для сложных типов данных. Может быть пустым + */ + List parameters; +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/description/package-info.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/description/package-info.java new file mode 100644 index 00000000000..dbcd9b968bd --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/description/package-info.java @@ -0,0 +1,28 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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. + */ +/** + * Классы для хранения информации, прочитанной из комментариев-описаний + */ +@ParametersAreNonnullByDefault +package com.github._1c_syntax.bsl.languageserver.context.symbol.description; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractCommonModuleNameDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractCommonModuleNameDiagnostic.java index 57a781cbdb4..c5afbe6b925 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractCommonModuleNameDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractCommonModuleNameDiagnostic.java @@ -21,24 +21,32 @@ */ package com.github._1c_syntax.bsl.languageserver.diagnostics; +import com.github._1c_syntax.bsl.languageserver.configuration.LanguageServerConfiguration; +import com.github._1c_syntax.bsl.languageserver.utils.Ranges; import com.github._1c_syntax.mdclasses.mdo.CommonModule; import com.github._1c_syntax.mdclasses.mdo.MDObjectBase; import com.github._1c_syntax.utils.CaseInsensitivePattern; +import org.eclipse.lsp4j.Range; +import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; + abstract class AbstractCommonModuleNameDiagnostic extends AbstractDiagnostic { protected Pattern pattern; + private final LanguageServerConfiguration serverConfiguration; - public AbstractCommonModuleNameDiagnostic(String regexp) { - pattern = CaseInsensitivePattern.compile(regexp); + protected AbstractCommonModuleNameDiagnostic(LanguageServerConfiguration serverConfiguration, String regexp) { + this.serverConfiguration = serverConfiguration; + this.pattern = CaseInsensitivePattern.compile(regexp); } @Override protected void check() { - if (documentContext.getTokensFromDefaultChannel().isEmpty()) { + Optional range = Ranges.getFirstSignificantTokenRange(documentContext.getTokens()); + if (range.isEmpty()) { return; } @@ -49,7 +57,7 @@ protected void check() { .map(MDObjectBase::getName) .map(pattern::matcher) .filter(this::matchCheck) - .ifPresent(commonModule -> diagnosticStorage.addDiagnostic(documentContext.getTokensFromDefaultChannel().get(0))); + .ifPresent(commonModule -> diagnosticStorage.addDiagnostic(range.get())); } protected abstract boolean flagsCheck(CommonModule commonModule); @@ -58,21 +66,21 @@ protected boolean matchCheck(Matcher matcher) { return !matcher.find(); } - protected static boolean isClientServer(CommonModule commonModule) { + protected boolean isClientServer(CommonModule commonModule) { return !commonModule.isServerCall() && commonModule.isServer() && commonModule.isExternalConnection() && isClientApplication(commonModule); } - protected static boolean isClient(CommonModule commonModule) { + protected boolean isClient(CommonModule commonModule) { return !commonModule.isServerCall() && !commonModule.isServer() && !commonModule.isExternalConnection() && isClientApplication(commonModule); } - protected static boolean isServerCall(CommonModule commonModule) { + protected boolean isServerCall(CommonModule commonModule) { return commonModule.isServerCall() && commonModule.isServer() && !commonModule.isExternalConnection() @@ -80,17 +88,21 @@ protected static boolean isServerCall(CommonModule commonModule) { && !commonModule.isClientManagedApplication(); } - protected static boolean isServer(CommonModule commonModule) { + protected boolean isServer(CommonModule commonModule) { return !commonModule.isServerCall() && commonModule.isServer() && commonModule.isExternalConnection() - && commonModule.isClientOrdinaryApplication() + && isClientOrdinaryAppIfNeed(commonModule) && !commonModule.isClientManagedApplication(); } - private static boolean isClientApplication(CommonModule commonModule) { - return commonModule.isClientOrdinaryApplication() + private boolean isClientApplication(CommonModule commonModule) { + return isClientOrdinaryAppIfNeed(commonModule) && commonModule.isClientManagedApplication(); } + private boolean isClientOrdinaryAppIfNeed(CommonModule commonModule) { + return commonModule.isClientOrdinaryApplication() + || !serverConfiguration.getDiagnosticsOptions().isOrdinaryAppSupport(); + } } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeOutOfRegionDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeOutOfRegionDiagnostic.java index 7ea0bc4f30e..a0afa119274 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeOutOfRegionDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeOutOfRegionDiagnostic.java @@ -25,6 +25,7 @@ import com.github._1c_syntax.bsl.languageserver.context.symbol.RegionSymbol; import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticCompatibilityMode; import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticMetadata; +import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticParameter; 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; @@ -34,6 +35,7 @@ import com.github._1c_syntax.bsl.languageserver.utils.Trees; import com.github._1c_syntax.bsl.parser.BSLParser; import com.github._1c_syntax.bsl.parser.BSLParserRuleContext; +import com.github._1c_syntax.mdclasses.metadata.additional.ModuleType; import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.TerminalNode; import org.antlr.v4.runtime.tree.Tree; @@ -55,14 +57,27 @@ compatibilityMode = DiagnosticCompatibilityMode.COMPATIBILITY_MODE_8_3_1 ) public class CodeOutOfRegionDiagnostic extends AbstractVisitorDiagnostic { + private static final boolean CHECK_UNKNOWN_MODULE_TYPE = false; private final List regionsRanges = new ArrayList<>(); + @DiagnosticParameter( + type = Boolean.class, + defaultValue = "" + CHECK_UNKNOWN_MODULE_TYPE + ) + private boolean checkUnknownModuleType = CHECK_UNKNOWN_MODULE_TYPE; + @Override public ParseTree visitFile(BSLParser.FileContext ctx) { + + // Для неизвестных модулей не будем требовать нахождения кода в области + if (documentContext.getModuleType() == ModuleType.UNKNOWN && !checkUnknownModuleType) { + return ctx; + } + List regions = documentContext.getSymbolTree().getModuleLevelRegions(); regionsRanges.clear(); - // если областей нет, то и смысла дальше анализировть тоже нет + // если областей нет, то и смысла дальше анализировать тоже нет if (regions.isEmpty() && !ctx.getTokens().isEmpty()) { List relatedInformation = createRelatedInformations(ctx); diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommandModuleExportMethodsDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommandModuleExportMethodsDiagnostic.java new file mode 100644 index 00000000000..3db5d943782 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommandModuleExportMethodsDiagnostic.java @@ -0,0 +1,54 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.context.symbol.MethodSymbol; +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.mdclasses.metadata.additional.ModuleType; + +@DiagnosticMetadata( + type = DiagnosticType.CODE_SMELL, + severity = DiagnosticSeverity.INFO, + scope = DiagnosticScope.BSL, + modules = { + ModuleType.CommandModule + }, + minutesToFix = 1, + tags = { + DiagnosticTag.STANDARD, + DiagnosticTag.CLUMSY + } +) +public class CommandModuleExportMethodsDiagnostic extends AbstractSymbolTreeDiagnostic { + + @Override + public void visitMethod(MethodSymbol method) { + if (method.isExport()) { + diagnosticStorage.addDiagnostic(method.getSubNameRange()); + } + } + +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleInvalidTypeDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleInvalidTypeDiagnostic.java index 66cdca39556..5e5df5369b8 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleInvalidTypeDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleInvalidTypeDiagnostic.java @@ -21,6 +21,7 @@ */ package com.github._1c_syntax.bsl.languageserver.diagnostics; +import com.github._1c_syntax.bsl.languageserver.configuration.LanguageServerConfiguration; 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; @@ -46,9 +47,11 @@ } ) + public class CommonModuleInvalidTypeDiagnostic extends AbstractCommonModuleNameDiagnostic { - public CommonModuleInvalidTypeDiagnostic() { - super(""); + + public CommonModuleInvalidTypeDiagnostic(LanguageServerConfiguration serverConfiguration) { + super(serverConfiguration, ""); } @Override diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameCachedDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameCachedDiagnostic.java index 3f1d3f28ba8..84d67c9c295 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameCachedDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameCachedDiagnostic.java @@ -21,6 +21,7 @@ */ package com.github._1c_syntax.bsl.languageserver.diagnostics; +import com.github._1c_syntax.bsl.languageserver.configuration.LanguageServerConfiguration; 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; @@ -46,10 +47,11 @@ ) public class CommonModuleNameCachedDiagnostic extends AbstractCommonModuleNameDiagnostic { + private static final String REGEXP = "повторноеиспользование|повтисп|cached"; - public CommonModuleNameCachedDiagnostic() { - super(REGEXP); + public CommonModuleNameCachedDiagnostic(LanguageServerConfiguration serverConfiguration) { + super(serverConfiguration, REGEXP); } @Override diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameClientDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameClientDiagnostic.java index c80386391fb..cae69a4c310 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameClientDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameClientDiagnostic.java @@ -21,6 +21,7 @@ */ package com.github._1c_syntax.bsl.languageserver.diagnostics; +import com.github._1c_syntax.bsl.languageserver.configuration.LanguageServerConfiguration; 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; @@ -47,8 +48,8 @@ public class CommonModuleNameClientDiagnostic extends AbstractCommonModuleNameDi private static final String REGEXP = "клиент|client"; - public CommonModuleNameClientDiagnostic() { - super(REGEXP); + public CommonModuleNameClientDiagnostic(LanguageServerConfiguration serverConfiguration) { + super(serverConfiguration, REGEXP); } @Override diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameClientServerDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameClientServerDiagnostic.java index 0e790cf509d..366d605098b 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameClientServerDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameClientServerDiagnostic.java @@ -21,6 +21,7 @@ */ package com.github._1c_syntax.bsl.languageserver.diagnostics; +import com.github._1c_syntax.bsl.languageserver.configuration.LanguageServerConfiguration; 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; @@ -47,8 +48,8 @@ public class CommonModuleNameClientServerDiagnostic extends AbstractCommonModule private static final String REGEXP = "клиентсервер|clientserver"; - public CommonModuleNameClientServerDiagnostic() { - super(REGEXP); + public CommonModuleNameClientServerDiagnostic(LanguageServerConfiguration serverConfiguration) { + super(serverConfiguration, REGEXP); } @Override diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameFullAccessDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameFullAccessDiagnostic.java index 9563ff275fd..13ed5f2f049 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameFullAccessDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameFullAccessDiagnostic.java @@ -21,6 +21,7 @@ */ package com.github._1c_syntax.bsl.languageserver.diagnostics; +import com.github._1c_syntax.bsl.languageserver.configuration.LanguageServerConfiguration; 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; @@ -47,8 +48,8 @@ public class CommonModuleNameFullAccessDiagnostic extends AbstractCommonModuleNa private static final String REGEXP = "полныеправа|fullaccess"; - public CommonModuleNameFullAccessDiagnostic() { - super(REGEXP); + public CommonModuleNameFullAccessDiagnostic(LanguageServerConfiguration serverConfiguration) { + super(serverConfiguration, REGEXP); } @Override diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameGlobalClientDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameGlobalClientDiagnostic.java index bed1375036f..a3c21c68bd5 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameGlobalClientDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameGlobalClientDiagnostic.java @@ -21,6 +21,7 @@ */ package com.github._1c_syntax.bsl.languageserver.diagnostics; +import com.github._1c_syntax.bsl.languageserver.configuration.LanguageServerConfiguration; 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; @@ -45,8 +46,8 @@ public class CommonModuleNameGlobalClientDiagnostic extends AbstractCommonModule private static final String REGEXP = "^(?>(?!.+клиент|.+client).)*$"; - public CommonModuleNameGlobalClientDiagnostic() { - super(REGEXP); + public CommonModuleNameGlobalClientDiagnostic(LanguageServerConfiguration serverConfiguration) { + super(serverConfiguration, REGEXP); } @Override diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameGlobalDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameGlobalDiagnostic.java index 3985967c605..f90b2a98ecf 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameGlobalDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameGlobalDiagnostic.java @@ -21,6 +21,7 @@ */ package com.github._1c_syntax.bsl.languageserver.diagnostics; +import com.github._1c_syntax.bsl.languageserver.configuration.LanguageServerConfiguration; 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; @@ -47,8 +48,8 @@ public class CommonModuleNameGlobalDiagnostic extends AbstractCommonModuleNameDi private static final String REGEXP = "глобальный|global"; - public CommonModuleNameGlobalDiagnostic() { - super(REGEXP); + public CommonModuleNameGlobalDiagnostic(LanguageServerConfiguration serverConfiguration) { + super(serverConfiguration, REGEXP); } @Override diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameServerCallDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameServerCallDiagnostic.java index f262b7e5b04..11c59756353 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameServerCallDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameServerCallDiagnostic.java @@ -21,6 +21,7 @@ */ package com.github._1c_syntax.bsl.languageserver.diagnostics; +import com.github._1c_syntax.bsl.languageserver.configuration.LanguageServerConfiguration; 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; @@ -47,8 +48,8 @@ public class CommonModuleNameServerCallDiagnostic extends AbstractCommonModuleNa private static final String REGEXP = "вызовсервера|servercall"; - public CommonModuleNameServerCallDiagnostic() { - super(REGEXP); + public CommonModuleNameServerCallDiagnostic(LanguageServerConfiguration serverConfiguration) { + super(serverConfiguration, REGEXP); } @Override diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameWordsDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameWordsDiagnostic.java index dfad523521a..4aa405ca217 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameWordsDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameWordsDiagnostic.java @@ -21,6 +21,7 @@ */ package com.github._1c_syntax.bsl.languageserver.diagnostics; +import com.github._1c_syntax.bsl.languageserver.configuration.LanguageServerConfiguration; import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticMetadata; import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticParameter; import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticScope; @@ -61,8 +62,8 @@ public class CommonModuleNameWordsDiagnostic extends AbstractCommonModuleNameDia ) private String words = DEFAULT_WORDS; - public CommonModuleNameWordsDiagnostic() { - super(DEFAULT_WORDS); + public CommonModuleNameWordsDiagnostic(LanguageServerConfiguration serverConfiguration) { + super(serverConfiguration, DEFAULT_WORDS); } @Override diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DiagnosticStorage.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DiagnosticStorage.java index afd094b7db2..fc034e9d53f 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DiagnosticStorage.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DiagnosticStorage.java @@ -24,6 +24,7 @@ import com.github._1c_syntax.bsl.languageserver.utils.Ranges; import com.github._1c_syntax.bsl.parser.BSLParserRuleContext; import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.TerminalNode; import org.eclipse.lsp4j.Diagnostic; import org.eclipse.lsp4j.DiagnosticRelatedInformation; @@ -200,6 +201,16 @@ public void addDiagnostic( )); } + public void addDiagnostic(ParseTree tree) { + if(tree instanceof BSLParserRuleContext) { + addDiagnostic((BSLParserRuleContext) tree); + } else if (tree instanceof TerminalNode) { + addDiagnostic((TerminalNode) tree); + } else { + throw new IllegalArgumentException("Unsupported parameter type " + tree); + } + } + private static Diagnostic createDiagnostic( BSLDiagnostic bslDiagnostic, Range range, @@ -214,6 +225,7 @@ private static Diagnostic createDiagnostic( ); diagnostic.setCode(bslDiagnostic.getInfo().getCode()); + diagnostic.setTags(bslDiagnostic.getInfo().getLSPTags()); if (relatedInformation != null) { diagnostic.setRelatedInformation(relatedInformation); diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/FunctionOutParameterDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/FunctionOutParameterDiagnostic.java new file mode 100644 index 00000000000..53ce201e4ad --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/FunctionOutParameterDiagnostic.java @@ -0,0 +1,90 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.context.symbol.MethodSymbol; +import com.github._1c_syntax.bsl.languageserver.context.symbol.ParameterDefinition; +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.Trees; +import com.github._1c_syntax.bsl.parser.BSLParser; +import com.github._1c_syntax.bsl.parser.BSLParserRuleContext; +import org.antlr.v4.runtime.tree.ParseTree; +import org.apache.commons.collections4.map.CaseInsensitiveMap; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +@DiagnosticMetadata( + type = DiagnosticType.CODE_SMELL, + severity = DiagnosticSeverity.MAJOR, + minutesToFix = 10, + activatedByDefault = false, + tags = { + DiagnosticTag.DESIGN + } + +) +public class FunctionOutParameterDiagnostic extends AbstractVisitorDiagnostic { + + @Override + public ParseTree visitFunction(BSLParser.FunctionContext ctx) { + + List parameters = documentContext + .getSymbolTree() + .getMethodSymbol((BSLParserRuleContext) ctx.getParent()) + .stream() + .map(MethodSymbol::getParameters) + .flatMap(Collection::stream) + .filter(param -> !param.isByValue()) + .collect(Collectors.toList()); + + if (parameters.isEmpty()) { + return ctx; + } + + Map lvalues = Trees + .findAllRuleNodes(ctx.subCodeBlock(), BSLParser.RULE_lValue) + .stream() + .collect( + Collectors.toMap( + ParseTree::getText, + node -> (BSLParserRuleContext) node, + (existing, replacement) -> existing, + CaseInsensitiveMap::new) + ); + + parameters. + stream() + .filter(param -> lvalues.containsKey(param.getName())) + .map(param -> lvalues.get(param.getName())) + .filter(Objects::nonNull) + .forEach(diagnosticStorage::addDiagnostic); + + return ctx; + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/GlobalContextMethodCollision8312Diagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/GlobalContextMethodCollision8312Diagnostic.java new file mode 100644 index 00000000000..659c942b893 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/GlobalContextMethodCollision8312Diagnostic.java @@ -0,0 +1,63 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.DiagnosticCompatibilityMode; +import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticInfo; +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.utils.CaseInsensitivePattern; + +import java.util.regex.Pattern; + +@DiagnosticMetadata( + type = DiagnosticType.ERROR, + severity = DiagnosticSeverity.BLOCKER, + minutesToFix = 10, + tags = { + DiagnosticTag.ERROR, + DiagnosticTag.UNPREDICTABLE + }, + compatibilityMode = DiagnosticCompatibilityMode.COMPATIBILITY_MODE_8_3_12 + +) +public class GlobalContextMethodCollision8312Diagnostic extends AbstractDiagnostic { + + private static final Pattern COLLISION_METHODS = CaseInsensitivePattern.compile("(ПроверитьБит|ПроверитьПоБитовойМаске|УстановитьБит|ПобитовоеИ|ПобитовоеИли|ПобитовоеНе|ПобитовоеИНе|" + + "ПобитовоеИсключительноеИли|ПобитовыйСдвигВлево|ПобитовыйСдвигВправо|" + + "CheckBit|CheckByBitMask|SetBit|BitwiseAnd|BitwiseOr|BitwiseNot|BitwiseAndNot|BitwiseXor|BitwiseShiftLeft|" + + "BitwiseShiftRight)"); + + @Override + protected void check() { + documentContext.getSymbolTree().getMethods().stream() + .filter(method -> COLLISION_METHODS.matcher(method.getName()).matches()) + .forEach(method -> + diagnosticStorage.addDiagnostic( + method.getSubNameRange(), + info.getMessage(method.getName()) + ) + ); + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IfConditionComplexityDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IfConditionComplexityDiagnostic.java index 9f5db0685b3..535fb3df0a5 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IfConditionComplexityDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/IfConditionComplexityDiagnostic.java @@ -19,7 +19,6 @@ * 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/diagnostics/LatinAndCyrillicSymbolInWordDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/LatinAndCyrillicSymbolInWordDiagnostic.java new file mode 100644 index 00000000000..4ffd5cd3432 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/LatinAndCyrillicSymbolInWordDiagnostic.java @@ -0,0 +1,131 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.DiagnosticParameter; +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.BSLParser; +import com.github._1c_syntax.utils.CaseInsensitivePattern; +import org.antlr.v4.runtime.tree.ParseTree; + +import java.util.Map; +import java.util.StringJoiner; +import java.util.regex.Pattern; +import java.util.stream.Stream; + +@DiagnosticMetadata( + type = DiagnosticType.CODE_SMELL, + severity = DiagnosticSeverity.MINOR, + minutesToFix = 5, + tags = { + DiagnosticTag.BRAINOVERLOAD, + DiagnosticTag.SUSPICIOUS + } +) +public class LatinAndCyrillicSymbolInWordDiagnostic extends AbstractDiagnostic { + /** + * Минимальная длина имени для анализа + */ + private static final int MINIMAL_WORD_LEN = 2; + + /** + * Список слов-исключений через `,` + */ + private static final String DEFAULT_EXCLUDE_WORDS = "ЧтениеXML, ЧтениеJSON, ЗаписьXML, ЗаписьJSON, ComОбъект, " + + "ФабрикаXDTO, ОбъектXDTO, СоединениеFTP, HTTPСоединение, HTTPЗапрос, HTTPСервисОтвет, SMSСообщение, WSПрокси"; + + /** + * Паттерн для поиска кириллических символов в имени + */ + private static final Pattern RU_LANG_PATTERN = CaseInsensitivePattern.compile("[а-яё]"); + + /** + * Паттерн для поиска латинских символов в имени + */ + private static final Pattern EN_LANG_PATTERN = CaseInsensitivePattern.compile("[a-z]"); + + @DiagnosticParameter( + type = String.class, + defaultValue = "" + DEFAULT_EXCLUDE_WORDS + ) + private Pattern excludeWords = createExcludeWordPattern(DEFAULT_EXCLUDE_WORDS); + + private static Pattern createExcludeWordPattern(String words) { + StringJoiner stringJoiner = new StringJoiner("|"); + for (String elem : words.split(",")) { + stringJoiner.add(Pattern.quote(elem.trim())); + } + + return CaseInsensitivePattern.compile("(?:^" + stringJoiner.toString() + ")"); + } + + @Override + public void configure(Map configuration) { + this.excludeWords = createExcludeWordPattern( + (String) configuration.getOrDefault("excludeWords", DEFAULT_EXCLUDE_WORDS)); + } + + @Override + protected void check() { + check(BSLParser.RULE_subName); + check(BSLParser.RULE_var_name); + check(BSLParser.RULE_annotationName); + check(BSLParser.RULE_annotationParamName); + check(BSLParser.RULE_regionName); + + checkLabel(); + checkParameters(); + checkLValue(); + } + + private void check(int ruleID) { + checkTree(Trees.findAllRuleNodes(documentContext.getAst(), ruleID).stream()); + } + + private void checkLValue() { + checkTree(Trees.findAllRuleNodes(documentContext.getAst(), BSLParser.RULE_lValue).stream() + .filter(ctx -> ((BSLParser.LValueContext) ctx).IDENTIFIER() != null) + .map(ctx -> ((BSLParser.LValueContext) ctx).IDENTIFIER())); + } + + private void checkParameters() { + checkTree(Trees.findAllRuleNodes(documentContext.getAst(), BSLParser.RULE_param).stream() + .filter(ctx -> ((BSLParser.ParamContext) ctx).IDENTIFIER() != null) + .map(ctx -> ((BSLParser.ParamContext) ctx).IDENTIFIER())); + } + + private void checkLabel() { + checkTree(Trees.findAllRuleNodes(documentContext.getAst(), BSLParser.RULE_labelName).stream() + .filter(ctx -> ctx.getParent() instanceof BSLParser.GotoStatementContext)); + } + + private void checkTree(Stream tree) { + tree.filter(ctx -> ctx.getText() != null && ctx.getText().length() >= MINIMAL_WORD_LEN) + .filter(ctx -> !excludeWords.matcher(ctx.getText()).matches()) + .filter(ctx -> RU_LANG_PATTERN.matcher(ctx.getText()).find() && EN_LANG_PATTERN.matcher(ctx.getText()).find()) + .forEach(diagnosticStorage::addDiagnostic); + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java new file mode 100644 index 00000000000..7ed3a5f01d7 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic.java @@ -0,0 +1,133 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.DiagnosticParameter; +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.parser.BSLParser; +import com.github._1c_syntax.bsl.parser.BSLParserRuleContext; +import com.github._1c_syntax.utils.CaseInsensitivePattern; +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.tree.ParseTree; +import org.antlr.v4.runtime.tree.TerminalNode; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +@DiagnosticMetadata( + type = DiagnosticType.CODE_SMELL, + severity = DiagnosticSeverity.MINOR, + minutesToFix = 5, + tags = { + DiagnosticTag.BADPRACTICE, + DiagnosticTag.BRAINOVERLOAD + } + +) +public class MagicDateDiagnostic extends AbstractVisitorDiagnostic { + + private static final String DEFAULT_AUTHORIZED_DATES = "00010101,00010101000000,000101010000"; + + private static final Pattern methodPattern = CaseInsensitivePattern.compile( + "Дата|Date" + ); + + private static final Pattern paramPattern = CaseInsensitivePattern.compile( + "\"\\d{8}.*" + ); + + private static final Pattern nonNumberPattern = CaseInsensitivePattern.compile( + "\\D" + ); + + @DiagnosticParameter( + type = String.class, + defaultValue = "" + DEFAULT_AUTHORIZED_DATES + ) + private Set authorizedDates = new HashSet<>(Arrays.asList(DEFAULT_AUTHORIZED_DATES.split(","))); + + @Override + public void configure(Map configuration) { + String authorizedDatesString = + (String) configuration.getOrDefault("authorizedDates", DEFAULT_AUTHORIZED_DATES); + Set authD = + Arrays.stream(authorizedDatesString.split(",")).map(s -> s.trim()).collect(Collectors.toSet()); + this.authorizedDates.addAll(authD); + } + + @Override + public ParseTree visitGlobalMethodCall(BSLParser.GlobalMethodCallContext ctx) { + Optional.of(ctx) + .filter(it -> methodPattern.matcher(it.methodName().getText()).matches()) + .map(BSLParser.GlobalMethodCallContext::doCall) + .map(BSLParser.DoCallContext::callParamList) + .filter(callParamList -> paramPattern.matcher(callParamList.getText()).matches()) + .ifPresent(this::checkExclAddDiagnostic); + + return super.visitGlobalMethodCall(ctx); + } + + @Override + public ParseTree visitConstValue(BSLParser.ConstValueContext ctx) { + TerminalNode tNode = ctx.DATETIME(); + if (tNode != null) { + checkExclAddDiagnostic(ctx); + } + + return ctx; + } + + private void checkExclAddDiagnostic(BSLParserRuleContext ctx){ + String checked = ctx.getText(); + if (checked != null && !isExcluded(checked)) { + ParserRuleContext expression; + if (ctx instanceof BSLParser.CallParamListContext){ + expression = ctx.getParent().getParent().getParent().getParent().getParent(); + } + else { + expression = ctx.getParent().getParent(); + } + if (expression instanceof BSLParser.ExpressionContext + && (!isAssignExpression((BSLParser.ExpressionContext) expression))) { + diagnosticStorage.addDiagnostic(ctx.stop, info.getMessage(checked)); + } + } + } + + private boolean isExcluded(String sIn) { + String s = nonNumberPattern.matcher(sIn).replaceAll(""); + return authorizedDates.contains(s); + } + + private static boolean isAssignExpression(BSLParser.ExpressionContext expression) { + return (expression.getChildCount() <= 1); + } + +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MetadataObjectNameLengthDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MetadataObjectNameLengthDiagnostic.java index 76b08dc0d5f..793dfbeb1c5 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MetadataObjectNameLengthDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MetadataObjectNameLengthDiagnostic.java @@ -27,8 +27,11 @@ 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.Ranges; import com.github._1c_syntax.mdclasses.mdo.MDObjectBase; -import org.antlr.v4.runtime.Token; +import org.eclipse.lsp4j.Range; + +import java.util.Optional; @DiagnosticMetadata( type = DiagnosticType.ERROR, @@ -52,18 +55,20 @@ public class MetadataObjectNameLengthDiagnostic extends AbstractDiagnostic { @Override protected void check() { - if (!documentContext.getTokens().isEmpty() - && documentContext.getTokens().get(0).getType() != Token.EOF - ) { - documentContext - .getMdObject() - .map(MDObjectBase::getName) - .filter(this::checkName) - .ifPresent(name -> diagnosticStorage.addDiagnostic( - documentContext.getTokens().get(0), - info.getMessage(maxMetadataObjectNameLength)) - ); + + Optional range = Ranges.getFirstSignificantTokenRange(documentContext.getTokens()); + if (range.isEmpty()) { + return; } + + documentContext + .getMdObject() + .map(MDObjectBase::getName) + .filter(this::checkName) + .ifPresent(name -> diagnosticStorage.addDiagnostic( + range.get(), + info.getMessage(maxMetadataObjectNameLength)) + ); } private boolean checkName(String name) { diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingEventSubscriptionHandlerDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingEventSubscriptionHandlerDiagnostic.java new file mode 100644 index 00000000000..6cec5f00d4a --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingEventSubscriptionHandlerDiagnostic.java @@ -0,0 +1,143 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.Ranges; +import com.github._1c_syntax.mdclasses.mdo.CommonModule; +import com.github._1c_syntax.mdclasses.mdo.EventSubscription; +import com.github._1c_syntax.mdclasses.metadata.additional.ConfigurationSource; +import com.github._1c_syntax.mdclasses.metadata.additional.MDOType; +import com.github._1c_syntax.mdclasses.metadata.additional.ModuleType; +import org.eclipse.lsp4j.Range; + +import java.util.regex.Pattern; + +@DiagnosticMetadata( + type = DiagnosticType.ERROR, + severity = DiagnosticSeverity.BLOCKER, + minutesToFix = 5, + tags = { + DiagnosticTag.ERROR + }, + scope = DiagnosticScope.BSL, + modules = { + // todo переделать, когда появится привязка к объектам метаданных + ModuleType.SessionModule + } +) +public class MissingEventSubscriptionHandlerDiagnostic extends AbstractDiagnostic { + + /** + * Рендж на который будут повешены замечания + * Костыль, но пока так + */ + private Range diagnosticRange; + private static final Pattern SPLIT_PATTERN = Pattern.compile("\\."); + + @Override + protected void check() { + + Ranges.getFirstSignificantTokenRange(documentContext.getTokens()) + .ifPresent(range -> diagnosticRange = range); + + if (diagnosticRange == null) { + // нет ренджа - нет и диагностик :) + return; + } + + var configuration = documentContext.getServerContext().getConfiguration(); + if (configuration.getConfigurationSource() == ConfigurationSource.EMPTY) { + return; + } + + // для анализа выбираются все имеющиеся подписки на события + configuration.getChildren().stream() + .filter(mdo -> mdo.getType() == MDOType.EVENT_SUBSCRIPTION) + .map(mdo -> (EventSubscription) mdo) + .forEach((EventSubscription eventSubs) -> { + // проверка на пустой обработчик + if (eventSubs.getHandler().isEmpty()) { + addDiagnostic(eventSubs); + return; + } + + var handlerParts = SPLIT_PATTERN.split(eventSubs.getHandler()); + + // правильный обработчик состоит из трех частей: + // - CommonModule - тип объекта, всегда постоянный: общий модуль + // - Имя - имя модуля + // - ИмяМетода - имя метода в модуле + + if (handlerParts.length != 3) { + addDiagnostic("incorrectHandler", eventSubs, eventSubs.getHandler()); + return; + } + + // проверка на существование модуля + var module = configuration.getCommonModule(handlerParts[1]); + if (module.isEmpty()) { + addDiagnostic("missingModule", eventSubs, handlerParts[1]); + return; + } + + var commonModule = module.get(); + // проверка наличия у модуля серверного флага + if (!commonModule.isServer()) { + addDiagnostic("shouldBeServer", eventSubs, handlerParts[1]); + } + + // проверка на наличие метода и его экспортности + checkMethod(eventSubs, handlerParts[2], commonModule); + }); + } + + private void checkMethod(EventSubscription eventSubs, String methodName, CommonModule commonModule) { + documentContext.getServerContext() + .getDocument(commonModule.getMdoReference().getMdoRef(), ModuleType.CommonModule) + .ifPresent(commonModuleContext -> { + var method = commonModuleContext.getSymbolTree().getMethods().stream() + .filter(methodSymbol -> methodSymbol.getName().equalsIgnoreCase(methodName)) + .findFirst(); + if (method.isEmpty()) { + addDiagnostic("missingMethod", eventSubs, commonModule.getName() + "." + methodName); + return; + } + if (!method.get().isExport()) { + addDiagnostic("nonExportMethod", eventSubs, commonModule.getName() + "." + methodName); + } + }); + } + + private void addDiagnostic(String messageString, EventSubscription eventSubs, String text) { + diagnosticStorage.addDiagnostic(diagnosticRange, + info.getResourceString(messageString, text, eventSubs.getName())); + } + + private void addDiagnostic(EventSubscription eventSubs) { + diagnosticStorage.addDiagnostic(diagnosticRange, info.getMessage(eventSubs.getName())); + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingParameterDescriptionDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingParameterDescriptionDiagnostic.java new file mode 100644 index 00000000000..2f9af87e556 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingParameterDescriptionDiagnostic.java @@ -0,0 +1,165 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.context.symbol.MethodDescription; +import com.github._1c_syntax.bsl.languageserver.context.symbol.MethodSymbol; +import com.github._1c_syntax.bsl.languageserver.context.symbol.ParameterDefinition; +import com.github._1c_syntax.bsl.languageserver.context.symbol.description.ParameterDescription; +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 org.apache.commons.collections4.map.CaseInsensitiveMap; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Function; +import java.util.stream.Collectors; + +@DiagnosticMetadata( + type = DiagnosticType.CODE_SMELL, + severity = DiagnosticSeverity.MAJOR, + minutesToFix = 5, + tags = { + DiagnosticTag.STANDARD, + DiagnosticTag.BADPRACTICE + } +) +public class MissingParameterDescriptionDiagnostic extends AbstractSymbolTreeDiagnostic { + + /** + * Анализируется только методы, имеющие описание + * Для удобства кидается несколько разных замечаний + */ + @Override + public void visitMethod(MethodSymbol methodSymbol) { + + var description = methodSymbol.getDescription(); + + boolean hasDescription = description + .map(methodDescription -> !methodDescription.isEmpty()) + .orElse(false); + + if (!hasDescription) { + return; + } + + List parameters = methodSymbol.getParameters(); + List parametersDescriptions = description + .map(MethodDescription::getParameters) + .orElse(Collections.emptyList()); + + // параметров и описания нет, что в принципе не ошибка + if (parameters.isEmpty() && parametersDescriptions.isEmpty()) { + return; + } + + // параметров нет, но есть их описания, что есть ошибка + if (parameters.isEmpty()) { + addDiagnostic(methodSymbol, parametersDescriptions); + return; + } + + if (parametersDescriptions.isEmpty()) { + if (!description.get().getLink().isEmpty()) { + // пока считаем ссылку наличием описания всего и вся + return; + } + // ошибка отсутствует описание всех параметров + diagnosticStorage.addDiagnostic(methodSymbol.getSubNameRange()); + return; + } + + // сопоставление параметров и описаний + checkParameterDescription(methodSymbol, parameters, parametersDescriptions); + } + + private void checkParameterDescription(MethodSymbol methodSymbol, + List parameters, + List parametersDescriptions) { + + AtomicBoolean hasMissingDescription = new AtomicBoolean(false); + + var parametersDescriptionsCopy = new ArrayList<>(parametersDescriptions); + var descriptions = parametersDescriptions.stream() + .collect( + Collectors.toMap( + ParameterDescription::getName, + Function.identity(), + (first, second) -> first, + CaseInsensitiveMap::new)); + + parameters.forEach((ParameterDefinition parameter) -> { + var description = descriptions.get(parameter.getName()); + // описание параметра отсутствует как таковое + if (description == null) { + addDiagnostic(parameter, "missingDescription"); + hasMissingDescription.set(true); + return; + } + + // параметр в описании есть, но нет типа и описания типа + if (description.getTypes().isEmpty() && description.getDescription().isEmpty()) { + addDiagnostic(parameter, "emptyDescription"); + } + + // найденный параметр удалим из кэша + parametersDescriptionsCopy.remove(description); + }); + + // лишние описания параметров, отсутствующие в сигнатуре + if (!parametersDescriptionsCopy.isEmpty()) { + hasMissingDescription.set(true); + addDiagnostic(methodSymbol, parametersDescriptionsCopy); + } + + // проверить порядок параметров в описании + // но это имеет смысл только при отсутствии ошибок + + if (!hasMissingDescription.get()) { + var paramDescriptionString = parametersDescriptions.stream() + .map(ParameterDescription::getName).collect(Collectors.joining(",")).toLowerCase(Locale.ENGLISH); + var paramString = parameters.stream() + .map(ParameterDefinition::getName).collect(Collectors.joining(",")).toLowerCase(Locale.ENGLISH); + // если строки не равны, значит порядок описаний не совпадает + if (!paramDescriptionString.equals(paramString)) { + diagnosticStorage.addDiagnostic(methodSymbol.getSubNameRange(), info.getResourceString("wrongOrder")); + } + } + } + + private void addDiagnostic(ParameterDefinition parameter, String messageKey) { + diagnosticStorage.addDiagnostic(parameter.getRange(), info.getResourceString(messageKey, parameter.getName())); + } + + private void addDiagnostic(MethodSymbol methodSymbol, List parametersDescriptions) { + var parametersString = parametersDescriptions.stream() + .map(ParameterDescription::getName).collect(Collectors.joining(", ")); + diagnosticStorage.addDiagnostic( + methodSymbol.getSubNameRange(), + info.getResourceString("missingInSignature", parametersString)); + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingReturnedValueDescriptionDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingReturnedValueDescriptionDiagnostic.java new file mode 100644 index 00000000000..20672f50e7d --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingReturnedValueDescriptionDiagnostic.java @@ -0,0 +1,100 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.context.symbol.MethodDescription; +import com.github._1c_syntax.bsl.languageserver.context.symbol.MethodSymbol; +import com.github._1c_syntax.bsl.languageserver.context.symbol.description.TypeDescription; +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 java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +@DiagnosticMetadata( + type = DiagnosticType.CODE_SMELL, + severity = DiagnosticSeverity.MAJOR, + minutesToFix = 5, + tags = { + DiagnosticTag.STANDARD, + DiagnosticTag.BADPRACTICE + } +) +public class MissingReturnedValueDescriptionDiagnostic extends AbstractSymbolTreeDiagnostic { + + /** + * Анализируется только методы, имеющие описание + * Для удобства кидается несколько разных замечаний + */ + @Override + public void visitMethod(MethodSymbol methodSymbol) { + + var description = methodSymbol.getDescription(); + + boolean hasDescription = description + .map(methodDescription -> !methodDescription.isEmpty()) + .orElse(false); + + if (!hasDescription) { + return; + } + + List returnedValueDescription = description + .map(MethodDescription::getReturnedValue) + .orElse(Collections.emptyList()); + + // процедура и описания возвращаемого значения нет, все нормально + if (!methodSymbol.isFunction() && returnedValueDescription.isEmpty()) { + return; + } + + // процедура не должна иметь описания + if (!methodSymbol.isFunction()) { + diagnosticStorage.addDiagnostic(methodSymbol.getSubNameRange(), info.getResourceString("isProcedure")); + return; + } + + // функция без описания - ошибка + if (returnedValueDescription.isEmpty()) { + if (!description.get().getLink().isEmpty()) { + // пока считаем ссылку наличием описания всего и вся + return; + } + diagnosticStorage.addDiagnostic(methodSymbol.getSubNameRange(), info.getMessage()); + return; + } + + // тип возвращаемого значения должен иметь описание или быть сложным + var typesWithoutDescription = returnedValueDescription.stream() + .filter((TypeDescription typeDescription) -> + typeDescription.getDescription().isEmpty() && typeDescription.getParameters().isEmpty()) + .map(TypeDescription::getName) + .collect(Collectors.joining(", ")); + if (!typesWithoutDescription.isEmpty()) { + diagnosticStorage.addDiagnostic(methodSymbol.getSubNameRange(), + info.getResourceString("typesWithoutDescription", typesWithoutDescription)); + } + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingSpaceDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingSpaceDiagnostic.java index c2d54a4afd7..aef2968c2b7 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingSpaceDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingSpaceDiagnostic.java @@ -67,6 +67,19 @@ public class MissingSpaceDiagnostic extends AbstractDiagnostic implements QuickF private static final String UNARY = "+ - * / = % < > ( [ , Возврат Return <> <= >="; + /** + * Ключевые слова, требующие пробел слева и справа + */ + private static final Set KEYWORDS_WITH_LEFT_RIGHT_SPACE = computeKeywordsWithLeftRightSpace(); + /** + * Ключевые слова, требующие пробел слева + */ + private static final Set KEYWORDS_WITH_LEFT_SPACE = computeKeywordsWithLeftSpace(); + /** + * Ключевые слова, требующие пробел справа + */ + private static final Set KEYWORDS_WITH_RIGHT_SPACE = computeKeywordsWithRightSpace(); + @DiagnosticParameter( type = String.class, defaultValue = "" + DEFAULT_LIST_FOR_CHECK_LEFT @@ -128,19 +141,21 @@ public void check() { String tokenText = token.getText(); // проверяем слева - if (setL.contains(tokenText) && (noSpaceLeft = noSpaceLeft(tokens, token))) { + if ((setL.contains(tokenText) || KEYWORDS_WITH_LEFT_SPACE.contains(token.getType())) + && (noSpaceLeft = noSpaceLeft(tokens, token))) { leftComputed = true; addDiagnostic(token, mainMessage, indexWordLeftMsg); } // проверяем справа - if (setR.contains(tokenText) && (noSpaceRight = noSpaceRight(tokens, token))) { + if ((setR.contains(tokenText) || KEYWORDS_WITH_RIGHT_SPACE.contains(token.getType())) + && (noSpaceRight = noSpaceRight(tokens, token))) { rightComputed = true; addDiagnostic(token, mainMessage, indexWordRightMsg); } // проверяем слева и справа - if (setLR.contains(tokenText)) { + if (setLR.contains(tokenText) || KEYWORDS_WITH_LEFT_RIGHT_SPACE.contains(token.getType())) { if (!leftComputed) { noSpaceLeft = noSpaceLeft(tokens, token); } @@ -275,4 +290,33 @@ private boolean isUnaryChar(List tokens, Token t) { private static String getErrorMessage(String formatString, String errorMessage, String tokenText) { return String.format(formatString, errorMessage, tokenText).intern(); } + + private static Set computeKeywordsWithLeftRightSpace() { + return Set.of( + BSLParser.TO_KEYWORD, + BSLParser.IN_KEYWORD, + BSLParser.OR_KEYWORD, + BSLParser.AND_KEYWORD + ); + } + + private static Set computeKeywordsWithLeftSpace() { + return Set.of( + BSLParser.EXPORT_KEYWORD, + BSLParser.THEN_KEYWORD, + BSLParser.DO_KEYWORD + ); + } + + private static Set computeKeywordsWithRightSpace() { + return Set.of( + BSLParser.IF_KEYWORD, + BSLParser.ELSIF_KEYWORD, + BSLParser.WHILE_KEYWORD, + BSLParser.FOR_KEYWORD, + BSLParser.NOT_KEYWORD, + BSLParser.EACH_KEYWORD + ); + } + } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/NestedFunctionInParametersDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/NestedFunctionInParametersDiagnostic.java index 4a765ff2b2e..7e5274236e6 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/NestedFunctionInParametersDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/NestedFunctionInParametersDiagnostic.java @@ -33,7 +33,7 @@ @DiagnosticMetadata( type = DiagnosticType.CODE_SMELL, severity = DiagnosticSeverity.MINOR, - minutesToFix = 5, + minutesToFix = 2, tags = { DiagnosticTag.STANDARD, DiagnosticTag.BRAINOVERLOAD, diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/OrdinaryAppSupportDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/OrdinaryAppSupportDiagnostic.java new file mode 100644 index 00000000000..314bdb1e37f --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/OrdinaryAppSupportDiagnostic.java @@ -0,0 +1,79 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.configuration.LanguageServerConfiguration; +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.Ranges; +import com.github._1c_syntax.mdclasses.metadata.Configuration; +import com.github._1c_syntax.mdclasses.metadata.additional.ModuleType; +import lombok.RequiredArgsConstructor; +import org.eclipse.lsp4j.Range; + +@DiagnosticMetadata( + type = DiagnosticType.CODE_SMELL, + severity = DiagnosticSeverity.MAJOR, + scope = DiagnosticScope.BSL, + modules = { + ModuleType.SessionModule + }, + minutesToFix = 1, + tags = { + DiagnosticTag.STANDARD, + DiagnosticTag.UNPREDICTABLE + } +) +@RequiredArgsConstructor +public class OrdinaryAppSupportDiagnostic extends AbstractDiagnostic { + + private final LanguageServerConfiguration serverConfiguration; + + @Override + protected void check() { + + if (!serverConfiguration.getDiagnosticsOptions().isOrdinaryAppSupport()) { + return; + } + + Ranges.getFirstSignificantTokenRange(documentContext.getTokens()) + .ifPresent(this::checkProperties); + + } + + private void checkProperties(Range range) { + + Configuration configuration = documentContext.getServerContext().getConfiguration(); + if (!configuration.isUseManagedFormInOrdinaryApplication()) { + diagnosticStorage.addDiagnostic(range, info.getResourceString("managedFormInOrdinaryApp")); + } + + if (configuration.isUseOrdinaryFormInManagedApplication()) { + diagnosticStorage.addDiagnostic(range, info.getResourceString("ordinaryFormInManagedApp")); + } + + } + +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/RedundantAccessToObjectDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/RedundantAccessToObjectDiagnostic.java new file mode 100644 index 00000000000..1d1dc5b0434 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/RedundantAccessToObjectDiagnostic.java @@ -0,0 +1,195 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.context.DocumentContext; +import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticMetadata; +import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticParameter; +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.parser.BSLParser; +import com.github._1c_syntax.mdclasses.metadata.additional.MDOType; +import com.github._1c_syntax.mdclasses.metadata.additional.ModuleType; +import com.github._1c_syntax.utils.CaseInsensitivePattern; +import org.antlr.v4.runtime.tree.ParseTree; +import org.eclipse.lsp4j.Diagnostic; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + +@DiagnosticMetadata( + type = DiagnosticType.CODE_SMELL, + severity = DiagnosticSeverity.INFO, + minutesToFix = 1, + modules = { + ModuleType.CommonModule, + ModuleType.ObjectModule, + ModuleType.ManagerModule, + ModuleType.FormModule, + ModuleType.RecordSetModule + }, + tags = { + DiagnosticTag.STANDARD, + DiagnosticTag.CLUMSY + }, + scope = DiagnosticScope.BSL +) +public class RedundantAccessToObjectDiagnostic extends AbstractVisitorDiagnostic { + + private static final Pattern PATTERN = CaseInsensitivePattern.compile("^ЭтотОбъект|ThisObject"); + private static final Pattern PATTERN_WITH_DOT = CaseInsensitivePattern.compile("^(ЭтотОбъект|ThisObject)\\..*"); + + private static final boolean CHECK_OBJECT_MODULE = true; + private static final boolean CHECK_FORM_MODULE = true; + private static final boolean CHECK_RECORD_SET_MODULE = true; + + private boolean needCheckName = false; + private boolean skipLValue = false; + private Pattern namePattern; + private Pattern namePatternWithDot; + + @DiagnosticParameter( + type = Boolean.class, + defaultValue = "" + CHECK_OBJECT_MODULE + ) + private boolean checkObjectModule = CHECK_OBJECT_MODULE; + + @DiagnosticParameter( + type = Boolean.class, + defaultValue = "" + CHECK_FORM_MODULE + ) + private boolean checkFormModule = CHECK_FORM_MODULE; + + @DiagnosticParameter( + type = Boolean.class, + defaultValue = "" + CHECK_RECORD_SET_MODULE + ) + private boolean checkRecordSetModule = CHECK_RECORD_SET_MODULE; + + @Override + public List getDiagnostics(DocumentContext documentContext) { + var typeModule = documentContext.getModuleType(); + if (typeModule == ModuleType.CommonModule || typeModule == ModuleType.ManagerModule) { + documentContext.getMdObject().ifPresent(mdObjectBase -> { + needCheckName = true; + skipLValue = true; + namePattern = CaseInsensitivePattern.compile(String.format("^%s", mdObjectBase.getName())); + namePatternWithDot = CaseInsensitivePattern.compile( + String.format(getManagerModuleName(mdObjectBase.getType()), mdObjectBase.getName()) + ); + }); + } + + if (skipModule(typeModule)) { + return new ArrayList<>(); + } + return super.getDiagnostics(documentContext); + } + + @Override + public ParseTree visitCallStatement(BSLParser.CallStatementContext ctx) { + if (ctx.globalMethodCall() != null && ctx.getStart() == ctx.globalMethodCall().getStart()) { + return super.visitCallStatement(ctx); + } + + if (PATTERN_WITH_DOT.matcher(ctx.getText()).matches()) { + diagnosticStorage.addDiagnostic(ctx.getStart()); + } + + if (needCheckName && namePatternWithDot.matcher(ctx.getText()).matches()) { + diagnosticStorage.addDiagnostic(ctx.getStart()); + } + + return super.visitCallStatement(ctx); + } + + @Override + public ParseTree visitComplexIdentifier(BSLParser.ComplexIdentifierContext ctx) { + var identifier = ctx.IDENTIFIER(); + var modifiers = ctx.modifier(); + + if (identifier == null || modifiers.size() == 0) { + return ctx; + } + + if (PATTERN.matcher(identifier.getText()).matches() && modifiers.get(0) != null) { + diagnosticStorage.addDiagnostic(ctx.getStart()); + } + + if (needCheckName && namePattern.matcher(identifier.getText()).matches() && modifiers.get(0) != null) { + diagnosticStorage.addDiagnostic(ctx.getStart()); + } + + return ctx; + } + + @Override + public ParseTree visitLValue(BSLParser.LValueContext ctx) { + if (skipLValue) { + return ctx; + } + + var identifier = ctx.IDENTIFIER(); + var acceptor = ctx.acceptor(); + + if (identifier == null || acceptor == null) { + return ctx; + } + + if (PATTERN.matcher(identifier.getText()).matches() && acceptor.accessProperty() != null) { + diagnosticStorage.addDiagnostic(ctx.getStart()); + } + + if (needCheckName && namePattern.matcher(identifier.getText()).matches() && acceptor.accessProperty() != null) { + diagnosticStorage.addDiagnostic(ctx.getStart()); + } + + return ctx; + } + + private static String getManagerModuleName(MDOType objectType) { + if (objectType == MDOType.CATALOG) { + return "^(Справочники|Catalogs)\\.%s\\..*"; + } else if (objectType == MDOType.DOCUMENT) { + return "^(Документы|Documents)\\.%s\\..*"; + } else if (objectType == MDOType.ACCOUNTING_REGISTER) { + return "^(РегистрыБухгалтерии|AccountingRegisters)\\.%s\\..*"; + } else if (objectType == MDOType.ACCUMULATION_REGISTER) { + return "^(РегистрыНакопления|AccumulationRegisters)\\.%s\\..*"; + } else if (objectType == MDOType.CALCULATION_REGISTER) { + return "^(РегистрыРасчета|CalculationRegisters)\\.%s\\..*"; + } else if (objectType == MDOType.INFORMATION_REGISTER) { + return "^(РегистрыСведений|InformationRegisters)\\.%s\\..*"; + } else { + return "^%s\\..*"; + } + } + + private boolean skipModule(ModuleType typeModule) { + return typeModule == ModuleType.ObjectModule && !checkObjectModule + || typeModule == ModuleType.RecordSetModule && !checkRecordSetModule + || typeModule == ModuleType.FormModule && !checkFormModule; + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/RefOveruseDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/RefOveruseDiagnostic.java new file mode 100644 index 00000000000..acfc00ebe95 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/RefOveruseDiagnostic.java @@ -0,0 +1,138 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.BSLParserRuleContext; +import com.github._1c_syntax.bsl.parser.SDBLParser; +import com.github._1c_syntax.utils.CaseInsensitivePattern; +import org.antlr.v4.runtime.tree.ParseTree; + +import java.util.Collection; +import java.util.Optional; +import java.util.Set; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +@DiagnosticMetadata( + type = DiagnosticType.CODE_SMELL, + severity = DiagnosticSeverity.MAJOR, + scope = DiagnosticScope.BSL, + minutesToFix = 5, + tags = { + DiagnosticTag.SQL, + DiagnosticTag.PERFORMANCE + } +) +public class RefOveruseDiagnostic extends AbstractSDBLVisitorDiagnostic { + + private static final String REF_REGEX = "Ссылка|Reference"; + private static final Pattern REF_PATTERN = CaseInsensitivePattern.compile(REF_REGEX); + private static final int BAD_CHILD_COUNT = 3; + + @Override + public ParseTree visitQuery(SDBLParser.QueryContext ctx) { + var columnsCollection = Trees.findAllRuleNodes(ctx, SDBLParser.RULE_column); + + if (columnsCollection.isEmpty()) { + return ctx; + } + + var dataSourceCollection = Trees.findAllRuleNodes(ctx, SDBLParser.RULE_dataSource); + + if (dataSourceCollection.stream().anyMatch(Trees::treeContainsErrors)) { + return ctx; + } + + if (dataSourceCollection.isEmpty()) { + performSimpleCheck(columnsCollection); + return ctx; + } + + Set tableNames = dataSourceCollection.stream() + .map(RefOveruseDiagnostic::getTableNameOrAlias) + .collect(Collectors.toSet()); + + columnsCollection.forEach(column -> checkColumnNode((SDBLParser.ColumnContext) column, tableNames)); + return ctx; + + } + + private void performSimpleCheck(Collection columnsCollection) { + columnsCollection.stream() + .filter(columnNode -> columnNode.getChildCount() > BAD_CHILD_COUNT) + .map(column -> column.getChild(column.getChildCount() - 1)) + .filter(lastChild -> REF_PATTERN.matcher(lastChild.getText()).matches()) + .forEach(node -> diagnosticStorage.addDiagnostic((BSLParserRuleContext) node)); + } + + private void checkColumnNode(SDBLParser.ColumnContext ctx, Set tableNames) { + + if (ctx.children == null) { + return; + } + + var lastChild = ctx.getChild(Math.min(ctx.children.size(), ctx.children.size() - 1)); + var penultimateChild = ctx.getChild(Math.min(ctx.children.size(), ctx.children.size() - 3)); + + if (lastChild != penultimateChild + && lastChild instanceof SDBLParser.IdentifierContext + && penultimateChild instanceof SDBLParser.IdentifierContext) { + + performCheck(ctx, (SDBLParser.IdentifierContext) lastChild, + (SDBLParser.IdentifierContext) penultimateChild, tableNames); + } + + } + + private void performCheck(SDBLParser.ColumnContext ctx, SDBLParser.IdentifierContext lastChild, + SDBLParser.IdentifierContext penultimateChild, Set tableNames) { + + if (!tableNames.contains(penultimateChild.getText()) && + REF_PATTERN.matcher(lastChild.getText()).matches()) { + diagnosticStorage.addDiagnostic(ctx); + } + } + + private static String getTableNameOrAlias(ParseTree dataSource) { + return Optional.of(dataSource) + .flatMap(dataSrc -> extractTextFromChild(dataSrc, SDBLParser.RULE_alias)) + .or(() -> Optional.of(dataSource) + .flatMap(dataSrc -> extractTextFromChild(dataSrc, SDBLParser.RULE_table))) + .or(() -> Optional.of(dataSource) + .flatMap(dataSrc -> extractTextFromChild(dataSrc, SDBLParser.RULE_parameterTable))) + .orElse(""); + } + + private static Optional extractTextFromChild(ParseTree parseTree, int childRuleType) { + return Optional.of(parseTree) + .flatMap(tree -> Trees.getFirstChild(tree, childRuleType)) + .flatMap(child -> Trees.getFirstChild(child, SDBLParser.RULE_identifier)) + .map(BSLParserRuleContext::getText); + } + +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic.java index 9e70380761a..35698328f91 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic.java @@ -73,7 +73,6 @@ public class TypoDiagnostic extends AbstractDiagnostic { private static final Pattern SPACES_PATTERN = Pattern.compile("\\s+"); private static final Pattern QUOTE_PATTERN = Pattern.compile("\""); - private static final Pattern NEWLINE_PATTERN = Pattern.compile("\\n"); private static final Integer[] rulesToFind = new Integer[]{ BSLParser.RULE_string, @@ -107,15 +106,15 @@ public void configure(Map configuration) { } private String getWordsToIgnore() { - String exceptions = NEWLINE_PATTERN.matcher(info.getResourceString("diagnosticExceptions")).replaceAll(""); + String exceptions = SPACES_PATTERN.matcher(info.getResourceString("diagnosticExceptions")).replaceAll(""); if (!userWordsToIgnore.isEmpty()) { - exceptions = exceptions + "," + NEWLINE_PATTERN.matcher(userWordsToIgnore).replaceAll(""); + exceptions = exceptions + "," + SPACES_PATTERN.matcher(userWordsToIgnore).replaceAll(""); } return exceptions.intern(); } - private JLanguageToolPoolEntry acquireLanguageTool(String lang) { + JLanguageToolPoolEntry acquireLanguageTool(String lang) { return getLanguageToolPoolMap().get(lang).checkOut(); } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UnusedLocalMethodDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UnusedLocalMethodDiagnostic.java index aaf2633ecd8..f380552ed17 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UnusedLocalMethodDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UnusedLocalMethodDiagnostic.java @@ -52,7 +52,8 @@ minutesToFix = 1, tags = { DiagnosticTag.STANDARD, - DiagnosticTag.SUSPICIOUS + DiagnosticTag.SUSPICIOUS, + DiagnosticTag.UNUSED } ) public class UnusedLocalMethodDiagnostic extends AbstractVisitorDiagnostic { diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UnusedParametersDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UnusedParametersDiagnostic.java index 76e1b788ab3..e19b4c8d178 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UnusedParametersDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UnusedParametersDiagnostic.java @@ -43,9 +43,11 @@ severity = DiagnosticSeverity.MAJOR, scope = DiagnosticScope.OS, minutesToFix = 5, - tags = {DiagnosticTag.DESIGN} + tags = { + DiagnosticTag.DESIGN, + DiagnosticTag.UNUSED + } ) - public class UnusedParametersDiagnostic extends AbstractVisitorDiagnostic { private static final Pattern HANDLER_PATTERN = CaseInsensitivePattern.compile( diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UsingModalWindowsDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UsingModalWindowsDiagnostic.java index e74bca64582..9b7d8f3b3bd 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UsingModalWindowsDiagnostic.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UsingModalWindowsDiagnostic.java @@ -23,6 +23,7 @@ import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticCompatibilityMode; import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticMetadata; +import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticParameter; 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; @@ -58,6 +59,12 @@ public class UsingModalWindowsDiagnostic extends AbstractVisitorDiagnostic { private final HashMap pairMethods = new HashMap<>(); + @DiagnosticParameter( + type = Boolean.class, + defaultValue = "false" + ) + private boolean forceModalityMode; + public UsingModalWindowsDiagnostic() { pairMethods.put("ВОПРОС", "ПоказатьВопрос"); pairMethods.put("DOQUERYBOX", "ShowQueryBox"); @@ -88,9 +95,10 @@ public UsingModalWindowsDiagnostic() { @Override public ParseTree visitFile(BSLParser.FileContext ctx) { var configuration = documentContext.getServerContext().getConfiguration(); - // если использование модальных окон разрешено (без предупреждение), то + // если использование модальных окон разрешено (без предупреждение) + // и не установлен флаг игнорирования использования модальных окон, то // ничего не диагностируется - if (configuration.getModalityUseMode() == UseMode.USE) { + if (!forceModalityMode && configuration.getModalityUseMode() == UseMode.USE) { return ctx; } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/metadata/DiagnosticInfo.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/metadata/DiagnosticInfo.java index 34c8a04e13f..e41cdac8c8e 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/metadata/DiagnosticInfo.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/metadata/DiagnosticInfo.java @@ -36,6 +36,7 @@ import java.util.EnumMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; @@ -44,6 +45,7 @@ public class DiagnosticInfo { private static final Map severityToLSPSeverityMap = createSeverityToLSPSeverityMap(); + private static final Map diagnosticTagMap = createDiagnosticTagMap(); private final Class diagnosticClass; private final LanguageServerConfiguration configuration; @@ -154,6 +156,13 @@ public List getTags() { return new ArrayList<>(Arrays.asList(diagnosticMetadata.tags())); } + public List getLSPTags() { + return getTags().stream() + .map(diagnosticTag -> diagnosticTagMap.getOrDefault(diagnosticTag, null)) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } + public List getParameters() { return new ArrayList<>(diagnosticParameters); } @@ -186,4 +195,11 @@ private static Map cre return map; } + + private static Map createDiagnosticTagMap() { + return Map.of( + DiagnosticTag.UNUSED, org.eclipse.lsp4j.DiagnosticTag.Unnecessary, + DiagnosticTag.DEPRECATED, org.eclipse.lsp4j.DiagnosticTag.Deprecated + ); + } } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/metadata/DiagnosticTag.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/metadata/DiagnosticTag.java index 99161a06208..be9b5861072 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/metadata/DiagnosticTag.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/metadata/DiagnosticTag.java @@ -33,6 +33,7 @@ public enum DiagnosticTag { SUSPICIOUS("Подозрительный код"), UNPREDICTABLE("Непредсказуемо работающий код"), DEPRECATED("Устаревшая функциональность"), + UNUSED("Неиспользуемый код"), ERROR("Ошибочная конструкция"), LOCALIZE("Проблемы локализации"); diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/AbstractCommentFoldingRangeSupplier.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/AbstractCommentFoldingRangeSupplier.java new file mode 100644 index 00000000000..505c0bcbd1a --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/AbstractCommentFoldingRangeSupplier.java @@ -0,0 +1,78 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.folding; + +import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; +import org.antlr.v4.runtime.Token; +import org.eclipse.lsp4j.FoldingRange; +import org.eclipse.lsp4j.FoldingRangeKind; + +import java.util.ArrayList; +import java.util.List; + +/** + * Абстрактный сапплаер для получения областей сворачивания комментариев. + */ +public abstract class AbstractCommentFoldingRangeSupplier implements FoldingRangeSupplier { + + @Override + public List getFoldingRanges(DocumentContext documentContext) { + List foldingRanges = new ArrayList<>(); + + List comments = getComments(documentContext); + + int lastRangeStart = -1; + int previousLine = -1; + + for (Token token : comments) { + int tokenLine = token.getLine(); + + if (tokenLine != previousLine + 1) { + if (lastRangeStart != previousLine) { + FoldingRange foldingRange = new FoldingRange(lastRangeStart - 1, previousLine - 1); + foldingRange.setKind(FoldingRangeKind.Comment); + + foldingRanges.add(foldingRange); + } + // new range + lastRangeStart = tokenLine; + } + + previousLine = tokenLine; + } + + // add last range + if (lastRangeStart != previousLine) { + FoldingRange foldingRange = new FoldingRange(lastRangeStart - 1, previousLine - 1); + foldingRange.setKind(FoldingRangeKind.Comment); + + foldingRanges.add(foldingRange); + } + return foldingRanges; + } + + /** + * @param documentContext Контекст документа, для которого надо получить список комментариев + * @return Список токенов-комментариев + */ + protected abstract List getComments(DocumentContext documentContext); +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/CodeBlockFoldingRangeSupplier.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/CodeBlockFoldingRangeSupplier.java new file mode 100644 index 00000000000..3c179796378 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/CodeBlockFoldingRangeSupplier.java @@ -0,0 +1,115 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.folding; + +import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; +import com.github._1c_syntax.bsl.parser.BSLParser; +import com.github._1c_syntax.bsl.parser.BSLParserBaseVisitor; +import lombok.Getter; +import org.antlr.v4.runtime.tree.ParseTree; +import org.antlr.v4.runtime.tree.TerminalNode; +import org.eclipse.lsp4j.FoldingRange; +import org.eclipse.lsp4j.FoldingRangeKind; +import org.springframework.stereotype.Component; + +import javax.annotation.CheckForNull; +import java.util.ArrayList; +import java.util.List; + +/** + * Сапплаер областей сворачивания блоков кода: методов, условий, циклов, попыток. + */ +@Component +public class CodeBlockFoldingRangeSupplier implements FoldingRangeSupplier { + + @Override + public List getFoldingRanges(DocumentContext documentContext) { + CodeBlockVisitor codeBlockVisitor = new CodeBlockVisitor(); + codeBlockVisitor.visitFile(documentContext.getAst()); + return codeBlockVisitor.getRegionRanges(); + } + + private static class CodeBlockVisitor extends BSLParserBaseVisitor { + + @Getter + private final List regionRanges = new ArrayList<>(); + + @Override + public ParseTree visitProcedure(BSLParser.ProcedureContext ctx) { + addRegionRange(ctx.procDeclaration().PROCEDURE_KEYWORD(), ctx.ENDPROCEDURE_KEYWORD()); + return super.visitProcedure(ctx); + } + + @Override + public ParseTree visitFunction(BSLParser.FunctionContext ctx) { + addRegionRange(ctx.funcDeclaration().FUNCTION_KEYWORD(), ctx.ENDFUNCTION_KEYWORD()); + return super.visitFunction(ctx); + } + + @Override + public ParseTree visitIfStatement(BSLParser.IfStatementContext ctx) { + addRegionRange(ctx.ifBranch().IF_KEYWORD(), ctx.ENDIF_KEYWORD()); + return super.visitIfStatement(ctx); + } + + @Override + public ParseTree visitWhileStatement(BSLParser.WhileStatementContext ctx) { + addRegionRange(ctx.WHILE_KEYWORD(), ctx.ENDDO_KEYWORD()); + return super.visitWhileStatement(ctx); + } + + @Override + public ParseTree visitForStatement(BSLParser.ForStatementContext ctx) { + addRegionRange(ctx.FOR_KEYWORD(), ctx.ENDDO_KEYWORD()); + return super.visitForStatement(ctx); + } + + @Override + public ParseTree visitForEachStatement(BSLParser.ForEachStatementContext ctx) { + addRegionRange(ctx.FOR_KEYWORD(), ctx.ENDDO_KEYWORD()); + return super.visitForEachStatement(ctx); + } + + @Override + public ParseTree visitTryStatement(BSLParser.TryStatementContext ctx) { + addRegionRange(ctx.TRY_KEYWORD(), ctx.ENDTRY_KEYWORD()); + return super.visitTryStatement(ctx); + } + + private void addRegionRange(@CheckForNull TerminalNode start, @CheckForNull TerminalNode stop) { + if (start == null || stop == null) { + return; + } + + int startLine = start.getSymbol().getLine(); + int stopLine = stop.getSymbol().getLine(); + + if (stopLine > startLine) { + FoldingRange foldingRange = new FoldingRange(startLine - 1, stopLine - 1); + foldingRange.setKind(FoldingRangeKind.Region); + + regionRanges.add(foldingRange); + } + } + } + +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/CommentFoldingRangeSupplier.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/CommentFoldingRangeSupplier.java new file mode 100644 index 00000000000..987b08ba40b --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/CommentFoldingRangeSupplier.java @@ -0,0 +1,41 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.folding; + +import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; +import org.antlr.v4.runtime.Token; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * Сапплаер областей сворачивания блоков комментариев. + */ +@Component +public class CommentFoldingRangeSupplier extends AbstractCommentFoldingRangeSupplier { + + @Override + protected List getComments(DocumentContext documentContext) { + return documentContext.getComments(); + } + +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/FoldingRangeSupplier.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/FoldingRangeSupplier.java new file mode 100644 index 00000000000..48aebd214b6 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/FoldingRangeSupplier.java @@ -0,0 +1,39 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.folding; + +import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; +import org.eclipse.lsp4j.FoldingRange; + +import java.util.List; + +/** + * Базовый интерфейс для наполнения {@link com.github._1c_syntax.bsl.languageserver.providers.FoldingRangeProvider} + * данными о областях сворачивания. + */ +public interface FoldingRangeSupplier { + /** + * @param documentContext Контекст документа, для которого надо рассчитать области сворачивания + * @return Список областей сворачивания + */ + List getFoldingRanges(DocumentContext documentContext); +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/PreprocIfFoldingRangeSupplier.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/PreprocIfFoldingRangeSupplier.java new file mode 100644 index 00000000000..ff46bd3dc0f --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/PreprocIfFoldingRangeSupplier.java @@ -0,0 +1,83 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.folding; + +import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; +import com.github._1c_syntax.bsl.parser.BSLParser; +import com.github._1c_syntax.bsl.parser.BSLParserBaseVisitor; +import lombok.Getter; +import org.antlr.v4.runtime.tree.ParseTree; +import org.eclipse.lsp4j.FoldingRange; +import org.eclipse.lsp4j.FoldingRangeKind; +import org.springframework.stereotype.Component; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.List; + +/** + * Сапплаер областей сворачивания инструкций препроцессору #Если ... #КонецЕсли. + */ +@Component +public class PreprocIfFoldingRangeSupplier implements FoldingRangeSupplier { + + @Override + public List getFoldingRanges(DocumentContext documentContext) { + PreprocIfVisitor preprocIfVisitor = new PreprocIfVisitor(); + preprocIfVisitor.visitFile(documentContext.getAst()); + return preprocIfVisitor.getRegionRanges(); + } + + private static class PreprocIfVisitor extends BSLParserBaseVisitor { + + @Getter + private final List regionRanges = new ArrayList<>(); + private final Deque preprocIfRegionStack = new ArrayDeque<>(); + + @Override + public ParseTree visitPreproc_if(BSLParser.Preproc_ifContext ctx) { + preprocIfRegionStack.push(ctx); + return super.visitPreproc_if(ctx); + } + + @Override + public ParseTree visitPreproc_endif(BSLParser.Preproc_endifContext ctx) { + + if (preprocIfRegionStack.isEmpty()) { + return super.visitPreproc_endif(ctx); + } + + BSLParser.Preproc_ifContext regionStart = preprocIfRegionStack.pop(); + + int start = regionStart.getStart().getLine(); + int stop = ctx.getStop().getLine(); + + FoldingRange foldingRange = new FoldingRange(start - 1, stop - 1); + foldingRange.setKind(FoldingRangeKind.Region); + + regionRanges.add(foldingRange); + + return super.visitPreproc_endif(ctx); + } + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/QueryCommentFoldingRangeSupplier.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/QueryCommentFoldingRangeSupplier.java new file mode 100644 index 00000000000..aaae541d8f8 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/QueryCommentFoldingRangeSupplier.java @@ -0,0 +1,51 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.folding; + +import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; +import com.github._1c_syntax.bsl.parser.SDBLLexer; +import com.github._1c_syntax.bsl.parser.Tokenizer; +import org.antlr.v4.runtime.Token; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Сапплаер областей сворачивания блоков комментариев в тексте запроса. + */ +@Component +public class QueryCommentFoldingRangeSupplier extends AbstractCommentFoldingRangeSupplier { + + @Override + protected List getComments(DocumentContext documentContext) { + return documentContext.getQueries().stream() + .map(Tokenizer::getTokens) + .flatMap(Collection::stream) + .filter(token -> token.getType() == SDBLLexer.LINE_COMMENT) + .sorted(Comparator.comparing(Token::getLine)) + .collect(Collectors.toList()); + } + +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/QueryPackageFoldingRangeSupplier.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/QueryPackageFoldingRangeSupplier.java new file mode 100644 index 00000000000..0f7e2192cbe --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/QueryPackageFoldingRangeSupplier.java @@ -0,0 +1,61 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.folding; + +import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; +import com.github._1c_syntax.bsl.parser.SDBLParser; +import com.github._1c_syntax.bsl.parser.Tokenizer; +import org.eclipse.lsp4j.FoldingRange; +import org.eclipse.lsp4j.FoldingRangeKind; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Сапплаер областей сворачивания для пакетов запросов. + */ +@Component +public class QueryPackageFoldingRangeSupplier implements FoldingRangeSupplier { + + @Override + public List getFoldingRanges(DocumentContext documentContext) { + return documentContext.getQueries().stream() + .map(Tokenizer::getAst) + .map(SDBLParser.QueryPackageContext::queries) + .flatMap(Collection::stream) + .map(QueryPackageFoldingRangeSupplier::toFoldingRange) + .filter(foldingRange -> foldingRange.getStartLine() != foldingRange.getEndLine()) + .collect(Collectors.toList()); + } + + private static FoldingRange toFoldingRange(SDBLParser.QueriesContext queriesContext) { + FoldingRange foldingRange = new FoldingRange( + queriesContext.getStart().getLine() - 1, + queriesContext.getStop().getLine() - 1 + ); + foldingRange.setKind(FoldingRangeKind.Region); + return foldingRange; + } + +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/RegionFoldingRangeSupplier.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/RegionFoldingRangeSupplier.java new file mode 100644 index 00000000000..7999ed4a8f8 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/RegionFoldingRangeSupplier.java @@ -0,0 +1,57 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.folding; + +import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; +import com.github._1c_syntax.bsl.languageserver.context.symbol.RegionSymbol; +import org.eclipse.lsp4j.FoldingRange; +import org.eclipse.lsp4j.FoldingRangeKind; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * Сапплаер областей сворачивания областей (#Область ... #КонецОбласти). + */ +@Component +public class RegionFoldingRangeSupplier implements FoldingRangeSupplier { + + @Override + public List getFoldingRanges(DocumentContext documentContext) { + return documentContext.getSymbolTree().getRegionsFlat().stream() + .map(RegionFoldingRangeSupplier::toFoldingRange) + .collect(Collectors.toList()); + } + + private static FoldingRange toFoldingRange(RegionSymbol regionSymbol) { + + FoldingRange foldingRange = new FoldingRange( + regionSymbol.getStartRange().getStart().getLine(), + regionSymbol.getEndRange().getEnd().getLine() + ); + foldingRange.setKind(FoldingRangeKind.Region); + + return foldingRange; + } + +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/UseFoldingRangeSupplier.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/UseFoldingRangeSupplier.java new file mode 100644 index 00000000000..126e083b6c5 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/UseFoldingRangeSupplier.java @@ -0,0 +1,59 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.folding; + +import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; +import com.github._1c_syntax.bsl.languageserver.utils.Trees; +import com.github._1c_syntax.bsl.parser.BSLParser; +import org.antlr.v4.runtime.tree.ParseTree; +import org.eclipse.lsp4j.FoldingRange; +import org.eclipse.lsp4j.FoldingRangeKind; +import org.springframework.stereotype.Component; + +import java.util.Collections; +import java.util.List; + +/** + * Сапплаер областей сворачивания импортов библиотек OneScript (#Использовать ...). + */ +@Component +public class UseFoldingRangeSupplier implements FoldingRangeSupplier { + + @Override + public List getFoldingRanges(DocumentContext documentContext) { + BSLParser.FileContext fileContext = documentContext.getAst(); + ParseTree[] uses = Trees.findAllRuleNodes(fileContext, BSLParser.RULE_use).toArray(new ParseTree[0]); + + if (uses.length <= 1) { + return Collections.emptyList(); + } + + int start = ((BSLParser.UseContext) uses[0]).getStart().getLine(); + int stop = ((BSLParser.UseContext) uses[uses.length - 1]).getStop().getLine(); + + FoldingRange foldingRange = new FoldingRange(start - 1, stop - 1); + foldingRange.setKind(FoldingRangeKind.Imports); + + return Collections.singletonList(foldingRange); + } + +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/package-info.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/package-info.java new file mode 100644 index 00000000000..74dd0f0193c --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/package-info.java @@ -0,0 +1,29 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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. + */ +/** + * Пакет предназначен для реализации различных видов сворачивания ("folding"), + * используемых {@link com.github._1c_syntax.bsl.languageserver.providers.FoldingRangeProvider}. + */ +@ParametersAreNonnullByDefault +package com.github._1c_syntax.bsl.languageserver.folding; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/jsonrpc/Diagnostics.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/jsonrpc/Diagnostics.java new file mode 100644 index 00000000000..fe8ad6b3ffa --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/jsonrpc/Diagnostics.java @@ -0,0 +1,52 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.jsonrpc; + +import lombok.Value; +import org.eclipse.lsp4j.Diagnostic; + +import java.util.Collections; +import java.util.List; + +/** + * Ответ на запрос textDocument/x-diagnostics. + *
+ * См. {@link com.github._1c_syntax.bsl.languageserver.BSLTextDocumentService#diagnostics(DiagnosticParams)} + */ +@Value +public class Diagnostics { + + /** + * Пустой ответ. + */ + public static final Diagnostics EMPTY = new Diagnostics(Collections.emptyList(), 0); + + /** + * Список рассчитанных диагностик документа. + */ + List diagnostics; + + /** + * Версия документа, для которого были рассчитаны диагностики. + */ + Integer version; +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/jsonrpc/ProtocolExtension.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/jsonrpc/ProtocolExtension.java index db0547e46cd..1cb7561974c 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/jsonrpc/ProtocolExtension.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/jsonrpc/ProtocolExtension.java @@ -21,22 +21,20 @@ */ package com.github._1c_syntax.bsl.languageserver.jsonrpc; -import org.eclipse.lsp4j.Diagnostic; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; -import java.util.List; import java.util.concurrent.CompletableFuture; public interface ProtocolExtension { /** * @param params Параметры запроса. - * @return Список диагностик. + * @return Список рассчитанных диагностик. */ @JsonRequest( value = "textDocument/x-diagnostics", useSegment = false ) - CompletableFuture> diagnostics(DiagnosticParams params); + CompletableFuture diagnostics(DiagnosticParams params); } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/CodeActionProvider.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/CodeActionProvider.java index 441e4690ebc..e4dca5e0282 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/CodeActionProvider.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/CodeActionProvider.java @@ -39,6 +39,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; @Component @@ -72,6 +73,9 @@ public static List createCodeActions( codeAction.setDiagnostics(diagnostics); codeAction.setEdit(edit); codeAction.setKind(CodeActionKind.QuickFix); + if (diagnostics.size() == 1) { + codeAction.setIsPreferred(Boolean.TRUE); + } return Collections.singletonList(codeAction); @@ -82,8 +86,12 @@ public List> getCodeActions( DocumentContext documentContext ) { + List only = Optional.ofNullable(params.getContext().getOnly()) + .orElse(Collections.emptyList()); + return codeActionSuppliers.stream() .flatMap(codeActionSupplier -> codeActionSupplier.getCodeActions(params, documentContext).stream()) + .filter(codeAction -> only.isEmpty() || only.contains(codeAction.getKind())) .map(Either::forRight) .collect(Collectors.toList()); } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/CodeLensProvider.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/CodeLensProvider.java index 832a2375777..cc151602887 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/CodeLensProvider.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/CodeLensProvider.java @@ -21,76 +21,25 @@ */ package com.github._1c_syntax.bsl.languageserver.providers; -import com.github._1c_syntax.bsl.languageserver.configuration.LanguageServerConfiguration; +import com.github._1c_syntax.bsl.languageserver.codelenses.CodeLensSupplier; import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; -import com.github._1c_syntax.bsl.languageserver.context.symbol.MethodSymbol; import lombok.RequiredArgsConstructor; import org.eclipse.lsp4j.CodeLens; -import org.eclipse.lsp4j.Command; import org.springframework.stereotype.Component; -import java.util.ArrayList; +import java.util.Collection; import java.util.List; -import java.util.Map; +import java.util.stream.Collectors; @Component @RequiredArgsConstructor public final class CodeLensProvider { - - private final LanguageServerConfiguration configuration; + private final List codeLensSuppliers; public List getCodeLens(DocumentContext documentContext) { - List codeLenses = new ArrayList<>(); - codeLenses.addAll(getCognitiveComplexityCodeLenses(documentContext)); - codeLenses.addAll(getCyclomaticComplexityCodeLenses(documentContext)); - return codeLenses; - } - - private List getCognitiveComplexityCodeLenses(DocumentContext documentContext) { - List codeLenses = new ArrayList<>(); - - if (configuration.getCodeLensOptions().isShowCognitiveComplexity()) { - Map methodsComplexity = documentContext.getCognitiveComplexityData() - .getMethodsComplexity(); - - methodsComplexity.forEach((MethodSymbol methodSymbol, Integer complexity) -> { - String title = String.format("Cognitive complexity is %d", complexity); - Command command = new Command(title, ""); - CodeLens codeLens = new CodeLens( - methodSymbol.getSubNameRange(), - command, - null - ); - - codeLenses.add(codeLens); - }); - } - - return codeLenses; + return codeLensSuppliers.stream() + .map(codeLensSupplier -> codeLensSupplier.getCodeLenses(documentContext)) + .flatMap(Collection::stream) + .collect(Collectors.toList()); } - - private List getCyclomaticComplexityCodeLenses(DocumentContext documentContext) { - List codeLenses = new ArrayList<>(); - - if (configuration.getCodeLensOptions().isShowCyclomaticComplexity()) { - - Map methodsComplexity = documentContext.getCyclomaticComplexityData() - .getMethodsComplexity(); - - methodsComplexity.forEach((MethodSymbol methodSymbol, Integer complexity) -> { - String title = String.format("Cyclomatic complexity is %d", complexity); - Command command = new Command(title, ""); - CodeLens codeLens = new CodeLens( - methodSymbol.getSubNameRange(), - command, - null - ); - - codeLenses.add(codeLens); - }); - } - - return codeLenses; - } - } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/DiagnosticProvider.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/DiagnosticProvider.java index 1f710655185..8e6132a176f 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/DiagnosticProvider.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/DiagnosticProvider.java @@ -27,28 +27,45 @@ import org.eclipse.lsp4j.Diagnostic; import org.eclipse.lsp4j.PublishDiagnosticsParams; import org.eclipse.lsp4j.services.LanguageClient; +import org.eclipse.lsp4j.services.LanguageClientAware; import org.springframework.stereotype.Component; +import javax.annotation.CheckForNull; import java.util.Collections; import java.util.List; +import java.util.function.Supplier; @Slf4j @Component @RequiredArgsConstructor -public final class DiagnosticProvider { +public final class DiagnosticProvider implements LanguageClientAware { public static final String SOURCE = "bsl-language-server"; - public void computeAndPublishDiagnostics(LanguageClient client, DocumentContext documentContext) { - List diagnostics = documentContext.getDiagnostics(); + @CheckForNull + private LanguageClient client; - client.publishDiagnostics(new PublishDiagnosticsParams(documentContext.getUri().toString(), diagnostics)); + public void computeAndPublishDiagnostics(DocumentContext documentContext) { + publishDiagnostics(documentContext, documentContext::getDiagnostics); } - public void publishEmptyDiagnosticList(LanguageClient client, DocumentContext documentContext) { + public void publishEmptyDiagnosticList(DocumentContext documentContext) { + publishDiagnostics(documentContext, Collections::emptyList); + } + + private void publishDiagnostics(DocumentContext documentContext, Supplier> diagnostics) { + if (client == null) { + return; + } + client.publishDiagnostics( - new PublishDiagnosticsParams(documentContext.getUri().toString(), Collections.emptyList()) + new PublishDiagnosticsParams(documentContext.getUri().toString(), diagnostics.get(), documentContext.getVersion()) ); } + @Override + public void connect(LanguageClient client) { + this.client = client; + } + } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/FoldingRangeProvider.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/FoldingRangeProvider.java index d32f7bb7c70..fa2502a6daa 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/FoldingRangeProvider.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/FoldingRangeProvider.java @@ -22,243 +22,26 @@ package com.github._1c_syntax.bsl.languageserver.providers; import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; -import com.github._1c_syntax.bsl.languageserver.context.symbol.RegionSymbol; -import com.github._1c_syntax.bsl.languageserver.utils.Trees; -import com.github._1c_syntax.bsl.parser.BSLParser; -import com.github._1c_syntax.bsl.parser.BSLParserBaseVisitor; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.tree.ParseTree; -import org.antlr.v4.runtime.tree.TerminalNode; +import com.github._1c_syntax.bsl.languageserver.folding.FoldingRangeSupplier; +import lombok.RequiredArgsConstructor; import org.eclipse.lsp4j.FoldingRange; -import org.eclipse.lsp4j.FoldingRangeKind; import org.springframework.stereotype.Component; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Deque; +import java.util.Collection; import java.util.List; import java.util.stream.Collectors; @Component +@RequiredArgsConstructor public final class FoldingRangeProvider { - public List getFoldingRange(DocumentContext documentContext) { - - List foldingRanges = getCommentRanges(documentContext); - - CodeBlockRangeFinder codeBlockRangeFinder = new CodeBlockRangeFinder(); - codeBlockRangeFinder.visitFile(documentContext.getAst()); - List codeBlockRegionRanges = codeBlockRangeFinder.getRegionRanges(); - - UseRangeFinder useRangeFinder = new UseRangeFinder(); - useRangeFinder.visitFile(documentContext.getAst()); - List useRegionRanges = useRangeFinder.getRegionRanges(); - - RegionRangeFinder regionRangeFinder = new RegionRangeFinder(documentContext); - List regionRanges = regionRangeFinder.getRegionRanges(); - - PreprocIfRegionRangeFinder preprocIfRegionRangeFinder = new PreprocIfRegionRangeFinder(); - preprocIfRegionRangeFinder.visitFile(documentContext.getAst()); - List preprocRegionRanges = preprocIfRegionRangeFinder.getRegionRanges(); - - foldingRanges.addAll(codeBlockRegionRanges); - foldingRanges.addAll(useRegionRanges); - foldingRanges.addAll(regionRanges); - foldingRanges.addAll(preprocRegionRanges); - - return foldingRanges; - } - - private List getCommentRanges(DocumentContext documentContext) { - List foldingRanges = new ArrayList<>(); - - int lastRangeStart = -1; - int previousLine = -1; - List comments = documentContext.getComments(); - for (Token token : comments) { - int tokenLine = token.getLine(); - - if (tokenLine != previousLine + 1) { - if (lastRangeStart != previousLine) { - FoldingRange foldingRange = new FoldingRange(lastRangeStart - 1, previousLine - 1); - foldingRange.setKind(FoldingRangeKind.Comment); - - foldingRanges.add(foldingRange); - } - // new range - lastRangeStart = tokenLine; - } - - previousLine = tokenLine; - } - - // add last range - if (lastRangeStart != previousLine) { - FoldingRange foldingRange = new FoldingRange(lastRangeStart - 1, previousLine - 1); - foldingRange.setKind(FoldingRangeKind.Comment); - - foldingRanges.add(foldingRange); - } - return foldingRanges; - } - - private static class UseRangeFinder extends BSLParserBaseVisitor { - - private final List regionRanges = new ArrayList<>(); - - public List getRegionRanges() { - return new ArrayList<>(regionRanges); - } - - @Override - public ParseTree visitFile(BSLParser.FileContext ctx) { - ParseTree[] uses = Trees.findAllRuleNodes(ctx, BSLParser.RULE_use).toArray(new ParseTree[0]); - - if (uses.length <= 1) { - return ctx; - } - - int start = ((BSLParser.UseContext) uses[0]).getStart().getLine(); - int stop = ((BSLParser.UseContext) uses[uses.length - 1]).getStop().getLine(); - - FoldingRange foldingRange = new FoldingRange(start - 1, stop - 1); - foldingRange.setKind(FoldingRangeKind.Imports); - - regionRanges.add(foldingRange); - - return ctx; - } - - } - - private static class CodeBlockRangeFinder extends BSLParserBaseVisitor { - - private final List regionRanges = new ArrayList<>(); - - public List getRegionRanges() { - return new ArrayList<>(regionRanges); - } - - @Override - public ParseTree visitProcedure(BSLParser.ProcedureContext ctx) { - addRegionRange(ctx.procDeclaration().PROCEDURE_KEYWORD(), ctx.ENDPROCEDURE_KEYWORD()); - return super.visitProcedure(ctx); - } - - @Override - public ParseTree visitFunction(BSLParser.FunctionContext ctx) { - addRegionRange(ctx.funcDeclaration().FUNCTION_KEYWORD(), ctx.ENDFUNCTION_KEYWORD()); - return super.visitFunction(ctx); - } - - @Override - public ParseTree visitIfStatement(BSLParser.IfStatementContext ctx) { - addRegionRange(ctx.ifBranch().IF_KEYWORD(), ctx.ENDIF_KEYWORD()); - return super.visitIfStatement(ctx); - } - - @Override - public ParseTree visitWhileStatement(BSLParser.WhileStatementContext ctx) { - addRegionRange(ctx.WHILE_KEYWORD(), ctx.ENDDO_KEYWORD()); - return super.visitWhileStatement(ctx); - } - - @Override - public ParseTree visitForStatement(BSLParser.ForStatementContext ctx) { - addRegionRange(ctx.FOR_KEYWORD(), ctx.ENDDO_KEYWORD()); - return super.visitForStatement(ctx); - } - - @Override - public ParseTree visitForEachStatement(BSLParser.ForEachStatementContext ctx) { - addRegionRange(ctx.FOR_KEYWORD(), ctx.ENDDO_KEYWORD()); - return super.visitForEachStatement(ctx); - } - - @Override - public ParseTree visitTryStatement(BSLParser.TryStatementContext ctx) { - addRegionRange(ctx.TRY_KEYWORD(), ctx.ENDTRY_KEYWORD()); - return super.visitTryStatement(ctx); - } - - private void addRegionRange(TerminalNode start, TerminalNode stop) { - if (start == null || stop == null) { - return; - } - - int startLine = start.getSymbol().getLine(); - int stopLine = stop.getSymbol().getLine(); - - if (stopLine > startLine) { - FoldingRange foldingRange = new FoldingRange(startLine - 1, stopLine - 1); - foldingRange.setKind(FoldingRangeKind.Region); - - regionRanges.add(foldingRange); - } - } - } - - private static class RegionRangeFinder { - - private final List regionRanges; - - RegionRangeFinder(DocumentContext documentContext) { - regionRanges = documentContext.getSymbolTree().getRegionsFlat().stream() - .map(RegionRangeFinder::toFoldingRange) - .collect(Collectors.toList()); - } - - List getRegionRanges() { - return new ArrayList<>(regionRanges); - } - - private static FoldingRange toFoldingRange(RegionSymbol regionSymbol) { - - FoldingRange foldingRange = new FoldingRange( - regionSymbol.getStartRange().getStart().getLine(), - regionSymbol.getEndRange().getEnd().getLine() - ); - foldingRange.setKind(FoldingRangeKind.Region); - - return foldingRange; - } + private final List foldingRangeSuppliers; + public List getFoldingRange(DocumentContext documentContext) { + return foldingRangeSuppliers.stream() + .map(foldingRangeSupplier -> foldingRangeSupplier.getFoldingRanges(documentContext)) + .flatMap(Collection::stream) + .collect(Collectors.toList()); } - private static class PreprocIfRegionRangeFinder extends BSLParserBaseVisitor { - - private final Deque preprocIfRegionStack = new ArrayDeque<>(); - private final List regionRanges = new ArrayList<>(); - - public List getRegionRanges() { - return new ArrayList<>(regionRanges); - } - - @Override - public ParseTree visitPreproc_if(BSLParser.Preproc_ifContext ctx) { - preprocIfRegionStack.push(ctx); - return super.visitPreproc_if(ctx); - } - - @Override - public ParseTree visitPreproc_endif(BSLParser.Preproc_endifContext ctx) { - - if (preprocIfRegionStack.isEmpty()) { - return super.visitPreproc_endif(ctx); - } - - BSLParser.Preproc_ifContext regionStart = preprocIfRegionStack.pop(); - - int start = regionStart.getStart().getLine(); - int stop = ctx.getStop().getLine(); - - FoldingRange foldingRange = new FoldingRange(start - 1, stop - 1); - foldingRange.setKind(FoldingRangeKind.Region); - - regionRanges.add(foldingRange); - - return super.visitPreproc_endif(ctx); - } - - } } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/FormatProvider.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/FormatProvider.java index 2fae789090a..4da30581004 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/FormatProvider.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/FormatProvider.java @@ -162,6 +162,7 @@ private static List getTextEdits( int lastLine = firstToken.getLine(); int previousTokenType = -1; + boolean previousIsUnary = false; for (Token token : filteredTokens) { int tokenType = token.getType(); @@ -222,7 +223,7 @@ private static List getTextEdits( String currentIndentation = StringUtils.repeat(indentation, currentIndentLevel); newTextBuilder.append("\n"); newTextBuilder.append(currentIndentation); - } else if (needAddSpace(tokenType, previousTokenType)) { + } else if (needAddSpace(tokenType, previousTokenType, previousIsUnary)) { newTextBuilder.append(' '); } else { // no-op @@ -256,6 +257,7 @@ private static List getTextEdits( } lastLine = token.getLine(); + previousIsUnary = isUnary(tokenType, previousTokenType); previousTokenType = tokenType; } @@ -283,7 +285,12 @@ private static List filteredTokens(List tokens) { .collect(Collectors.toList()); } - private static boolean needAddSpace(int type, int previousTokenType) { + private static boolean needAddSpace(int type, int previousTokenType, boolean previousIsUnary) { + + if (previousIsUnary) { + return false; + } + switch (previousTokenType) { case BSLLexer.DOT: case BSLLexer.HASH: @@ -330,6 +337,32 @@ private static boolean needAddSpace(int type, int previousTokenType) { } } + private static boolean isUnary(int type, int previousTokenType) { + if (type != BSLLexer.MINUS) { + return false; + } + switch (previousTokenType) { + case BSLLexer.PLUS: + case BSLLexer.MINUS: + case BSLLexer.MUL: + case BSLLexer.QUOTIENT: + case BSLLexer.ASSIGN: + case BSLLexer.MODULO: + case BSLLexer.LESS: + case BSLLexer.GREATER: + case BSLLexer.LBRACK: + case BSLLexer.LPAREN: + case BSLLexer.RETURN_KEYWORD: + case BSLLexer.NOT_EQUAL: + case BSLLexer.COMMA: + case BSLLexer.LESS_OR_EQUAL: + case BSLLexer.GREATER_OR_EQUAL: + return true; + default: + return false; + } + } + private static boolean needIncrementIndent(int tokenType) { return incrementIndentTokens.contains(tokenType); } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/reporters/databind/package-info.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/reporters/databind/package-info.java index a4e49223690..47238d64c7d 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/reporters/databind/package-info.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/reporters/databind/package-info.java @@ -19,7 +19,6 @@ * You should have received a copy of the GNU Lesser General Public * License along with BSL Language Server. */ - /** * Пакет содержит дополнительные классы для настройки сериализации и десериализации классов родительского пакета. */ diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/Ranges.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/Ranges.java index 7a14c47cdcd..a0bb1c4ab84 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/Ranges.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/Ranges.java @@ -21,12 +21,16 @@ */ package com.github._1c_syntax.bsl.languageserver.utils; +import com.github._1c_syntax.bsl.parser.BSLLexer; import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.tree.TerminalNode; import org.eclipse.lsp4j.Position; import org.eclipse.lsp4j.Range; +import java.util.Collection; +import java.util.Optional; + public final class Ranges { private Ranges() { @@ -95,4 +99,13 @@ public static boolean containsRange(Range bigger, Range smaller) { public static boolean containsPosition(Range range, Position position) { return org.eclipse.lsp4j.util.Ranges.containsPosition(range, position); } + + public static Optional getFirstSignificantTokenRange(Collection tokens) { + return tokens.stream() + .filter(token -> token.getType() != Token.EOF) + .filter(token -> token.getType() != BSLLexer.WHITE_SPACE) + .map(Ranges::create) + .filter(range -> (!range.getStart().equals(range.getEnd()))) + .findFirst(); + } } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/Regions.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/Regions.java index 630da54c302..369a89727b7 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/Regions.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/Regions.java @@ -115,6 +115,7 @@ public Set getStandardRegionsPatternsByModuleType(ModuleType moduleType case CommandModule: case SessionModule: case HTTPServiceModule: + case WEBServiceModule: standardRegions.add(EVENT_HANDLERS_REGION_NAME); break; case ExternalConnectionModule: @@ -196,6 +197,7 @@ private static Set getStandardRegionNames(ModuleType moduleType, ScriptV case CommandModule: case SessionModule: case HTTPServiceModule: + case WEBServiceModule: addCommandAndSessionModulesRegionsNames(regionsName, language); break; case ExternalConnectionModule: diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 9a8bf3c448c..ae3d1ae55f2 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -3,3 +3,4 @@ spring.main.banner-mode=off spring.main.log-startup-info=false logging.level.org.springframework.boot.autoconfigure.logging=INFO logging.level.org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler=warn +spring.application.name=BSL Language Server \ No newline at end of file diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/codeactions/DisableDiagnosticTriggeringSupplier_en.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/codeactions/DisableDiagnosticTriggeringSupplier_en.properties new file mode 100644 index 00000000000..0ef72da70a5 --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/codeactions/DisableDiagnosticTriggeringSupplier_en.properties @@ -0,0 +1,6 @@ +line=Disable %s in line +range=Disable %s in range +file=Disable %s in file +lineAll=Disable all diagnostic in line +rangeAll=Disable all diagnostic in range +fileAll=Disable all diagnostic in file \ No newline at end of file diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/codeactions/DisableDiagnosticTriggeringSupplier_ru.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/codeactions/DisableDiagnosticTriggeringSupplier_ru.properties new file mode 100644 index 00000000000..737baecca5a --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/codeactions/DisableDiagnosticTriggeringSupplier_ru.properties @@ -0,0 +1,6 @@ +line=Отключить %s в строке +range=Отключить %s в выделенном диапазоне +file=Отключить %s в файле +lineAll=Отключить все диагностики в строке +rangeAll=Отключить все диагностики в выделенном диапазоне +fileAll=Отключить все диагностики в файле \ No newline at end of file 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 bd4878e470b..d84473a236f 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 @@ -52,6 +52,14 @@ "object" ], "title": "Code out of region", + "properties": { + "checkUnknownModuleType": { + "description": "Check unknown module type", + "default": false, + "type": "boolean", + "title": "Check unknown module type" + } + }, "$id": "#/definitions/CodeOutOfRegion" }, "CognitiveComplexity": { @@ -78,6 +86,16 @@ }, "$id": "#/definitions/CognitiveComplexity" }, + "CommandModuleExportMethods": { + "description": "Export methods in command and general command modules", + "default": true, + "type": [ + "boolean", + "object" + ], + "title": "Export methods in command and general command modules", + "$id": "#/definitions/CommandModuleExportMethods" + }, "CommentedCode": { "description": "Commented out code", "default": true, @@ -512,6 +530,16 @@ "title": "Function name shouldn't start with \"\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\"", "$id": "#/definitions/FunctionNameStartsWithGet" }, + "FunctionOutParameter": { + "description": "Out function parameter", + "default": false, + "type": [ + "boolean", + "object" + ], + "title": "Out function parameter", + "$id": "#/definitions/FunctionOutParameter" + }, "FunctionReturnsSamePrimitive": { "description": "The function always returns the same primitive value", "default": true, @@ -556,6 +584,16 @@ "title": "GetForm method call", "$id": "#/definitions/GetFormMethod" }, + "GlobalContextMethodCollision8312": { + "description": "Global context method names collision", + "default": true, + "type": [ + "boolean", + "object" + ], + "title": "Global context method names collision", + "$id": "#/definitions/GlobalContextMethodCollision8312" + }, "IdenticalExpressions": { "description": "There are identical sub-expressions to the left and to the right of the \"foo\" operator", "default": true, @@ -654,6 +692,24 @@ "title": "Join with virtual table", "$id": "#/definitions/JoinWithVirtualTable" }, + "LatinAndCyrillicSymbolInWord": { + "description": "Mixing Latin and Cyrillic characters in one identifier", + "default": true, + "type": [ + "boolean", + "object" + ], + "title": "Mixing Latin and Cyrillic characters in one identifier", + "properties": { + "excludeWords": { + "description": "A list of exclusion words, specified as a comma-separated string", + "default": "\u0427\u0442\u0435\u043d\u0438\u0435XML, \u0427\u0442\u0435\u043d\u0438\u0435JSON, \u0417\u0430\u043f\u0438\u0441\u044cXML, \u0417\u0430\u043f\u0438\u0441\u044cJSON, Com\u041e\u0431\u044a\u0435\u043a\u0442, \u0424\u0430\u0431\u0440\u0438\u043a\u0430XDTO, \u041e\u0431\u044a\u0435\u043a\u0442XDTO, \u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435FTP, HTTP\u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435, HTTP\u0417\u0430\u043f\u0440\u043e\u0441, HTTP\u0421\u0435\u0440\u0432\u0438\u0441\u041e\u0442\u0432\u0435\u0442, SMS\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, WS\u041f\u0440\u043e\u043a\u0441\u0438", + "type": "string", + "title": "A list of exclusion words, specified as a comma-separated string" + } + }, + "$id": "#/definitions/LatinAndCyrillicSymbolInWord" + }, "LineLength": { "description": "Line Length limit", "default": true, @@ -672,6 +728,24 @@ }, "$id": "#/definitions/LineLength" }, + "MagicDate": { + "description": "Magic dates", + "default": true, + "type": [ + "boolean", + "object" + ], + "title": "Magic dates", + "properties": { + "authorizedDates": { + "description": "Allowed dates, comma separated. Example: 00010101,00010101000000,000101010000", + "default": "00010101,00010101000000,000101010000", + "type": "string", + "title": "Allowed dates, comma separated. Example: 00010101,00010101000000,000101010000" + } + }, + "$id": "#/definitions/MagicDate" + }, "MagicNumber": { "description": "Magic numbers", "default": true, @@ -750,20 +824,50 @@ }, "$id": "#/definitions/MissingCodeTryCatchEx" }, + "MissingEventSubscriptionHandler": { + "description": "Event subscription handler missing", + "default": true, + "type": [ + "boolean", + "object" + ], + "title": "Event subscription handler missing", + "$id": "#/definitions/MissingEventSubscriptionHandler" + }, + "MissingParameterDescription": { + "description": "Method parameters description are missing", + "default": true, + "type": [ + "boolean", + "object" + ], + "title": "Method parameters description are missing", + "$id": "#/definitions/MissingParameterDescription" + }, + "MissingReturnedValueDescription": { + "description": "Function returned values description is missing", + "default": true, + "type": [ + "boolean", + "object" + ], + "title": "Function returned values description is missing", + "$id": "#/definitions/MissingReturnedValueDescription" + }, "MissingSpace": { - "description": "Missing spaces to the left or right of operators + - * / = % < > <> <= >=, and also to the right of , and ;", + "description": "Missing spaces to the left or right of operators + - * / = % < > <> <= >=, keywords, and also to the right of , and ;", "default": true, "type": [ "boolean", "object" ], - "title": "Missing spaces to the left or right of operators + - * / = % < > <> <= >=, and also to the right of , and ;", + "title": "Missing spaces to the left or right of operators + - * / = % < > <> <= >=, keywords, and also to the right of , and ;", "properties": { "listForCheckLeftAndRight": { - "description": "List of symbols to check for the space from both sides of (separated by space)", + "description": "List to check for the space from both sides of (separated by space)", "default": "+ - * / = % < > <> <= >=", "type": "string", - "title": "List of symbols to check for the space from both sides of (separated by space)" + "title": "List to check for the space from both sides of (separated by space)" }, "allowMultipleCommas": { "description": "Allow several commas in a row", @@ -778,16 +882,16 @@ "title": "Check for space to the right of unary signs (+ -)" }, "listForCheckLeft": { - "description": "List of symbols to check for the space to the left of (separated by space)", + "description": "List to check for the space to the left of (separated by space)", "default": "", "type": "string", - "title": "List of symbols to check for the space to the left of (separated by space)" + "title": "List to check for the space to the left of (separated by space)" }, "listForCheckRight": { - "description": "List of symbols to check for the space to the right of (separated by space)", + "description": "List to check for the space to the right of (separated by space)", "default": ", ;", "type": "string", - "title": "List of symbols to check for the space to the right of (separated by space)" + "title": "List to check for the space to the right of (separated by space)" } }, "$id": "#/definitions/MissingSpace" @@ -1008,6 +1112,16 @@ "title": "Order of Parameters in method", "$id": "#/definitions/OrderOfParams" }, + "OrdinaryAppSupport": { + "description": "Ordinary application support", + "default": true, + "type": [ + "boolean", + "object" + ], + "title": "Ordinary application support", + "$id": "#/definitions/OrdinaryAppSupport" + }, "PairingBrokenTransaction": { "description": "Violation of pairing using methods \"BeginTransaction()\" & \"CommitTransaction()\" / \"RollbackTransaction()\"", "default": true, @@ -1056,6 +1170,46 @@ }, "$id": "#/definitions/PublicMethodsDescription" }, + "RedundantAccessToObject": { + "description": "Redundant access to an object", + "default": true, + "type": [ + "boolean", + "object" + ], + "title": "Redundant access to an object", + "properties": { + "checkRecordSetModule": { + "description": "Check record set modules", + "default": true, + "type": "boolean", + "title": "Check record set modules" + }, + "checkFormModule": { + "description": "Check form modules", + "default": true, + "type": "boolean", + "title": "Check form modules" + }, + "checkObjectModule": { + "description": "Check object modules", + "default": true, + "type": "boolean", + "title": "Check object modules" + } + }, + "$id": "#/definitions/RedundantAccessToObject" + }, + "RefOveruse": { + "description": "Overuse \"Reference\" in a query", + "default": true, + "type": [ + "boolean", + "object" + ], + "title": "Overuse \"Reference\" in a query", + "$id": "#/definitions/RefOveruse" + }, "SelfAssign": { "description": "Variable is assigned to itself", "default": true, @@ -1210,10 +1364,10 @@ "title": "Typo", "properties": { "userWordsToIgnore": { - "description": "Dictionary for excluding words (comma separated, without spaces)", + "description": "Dictionary for excluding words (comma separated)", "default": "", "type": "string", - "title": "Dictionary for excluding words (comma separated, without spaces)" + "title": "Dictionary for excluding words (comma separated)" }, "minWordLength": { "description": "Minimum length for checked words", @@ -1406,6 +1560,14 @@ "object" ], "title": "Using modal windows", + "properties": { + "forceModalityMode": { + "description": "Ignore configurations modality mode", + "default": false, + "type": "boolean", + "title": "Ignore configurations modality mode" + } + }, "$id": "#/definitions/UsingModalWindows" }, "UsingObjectNotAvailableUnix": { 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 803582c25b6..49a2536490f 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 @@ -41,6 +41,9 @@ "CognitiveComplexity": { "$ref": "parameters-schema.json#/definitions/CognitiveComplexity" }, + "CommandModuleExportMethods": { + "$ref": "parameters-schema.json#/definitions/CommandModuleExportMethods" + }, "CommentedCode": { "$ref": "parameters-schema.json#/definitions/CommentedCode" }, @@ -155,6 +158,9 @@ "FunctionNameStartsWithGet": { "$ref": "parameters-schema.json#/definitions/FunctionNameStartsWithGet" }, + "FunctionOutParameter": { + "$ref": "parameters-schema.json#/definitions/FunctionOutParameter" + }, "FunctionReturnsSamePrimitive": { "$ref": "parameters-schema.json#/definitions/FunctionReturnsSamePrimitive" }, @@ -164,6 +170,9 @@ "GetFormMethod": { "$ref": "parameters-schema.json#/definitions/GetFormMethod" }, + "GlobalContextMethodCollision8312": { + "$ref": "parameters-schema.json#/definitions/GlobalContextMethodCollision8312" + }, "IdenticalExpressions": { "$ref": "parameters-schema.json#/definitions/IdenticalExpressions" }, @@ -191,9 +200,15 @@ "JoinWithVirtualTable": { "$ref": "parameters-schema.json#/definitions/JoinWithVirtualTable" }, + "LatinAndCyrillicSymbolInWord": { + "$ref": "parameters-schema.json#/definitions/LatinAndCyrillicSymbolInWord" + }, "LineLength": { "$ref": "parameters-schema.json#/definitions/LineLength" }, + "MagicDate": { + "$ref": "parameters-schema.json#/definitions/MagicDate" + }, "MagicNumber": { "$ref": "parameters-schema.json#/definitions/MagicNumber" }, @@ -206,6 +221,15 @@ "MissingCodeTryCatchEx": { "$ref": "parameters-schema.json#/definitions/MissingCodeTryCatchEx" }, + "MissingEventSubscriptionHandler": { + "$ref": "parameters-schema.json#/definitions/MissingEventSubscriptionHandler" + }, + "MissingParameterDescription": { + "$ref": "parameters-schema.json#/definitions/MissingParameterDescription" + }, + "MissingReturnedValueDescription": { + "$ref": "parameters-schema.json#/definitions/MissingReturnedValueDescription" + }, "MissingSpace": { "$ref": "parameters-schema.json#/definitions/MissingSpace" }, @@ -257,6 +281,9 @@ "OrderOfParams": { "$ref": "parameters-schema.json#/definitions/OrderOfParams" }, + "OrdinaryAppSupport": { + "$ref": "parameters-schema.json#/definitions/OrdinaryAppSupport" + }, "PairingBrokenTransaction": { "$ref": "parameters-schema.json#/definitions/PairingBrokenTransaction" }, @@ -269,6 +296,12 @@ "PublicMethodsDescription": { "$ref": "parameters-schema.json#/definitions/PublicMethodsDescription" }, + "RedundantAccessToObject": { + "$ref": "parameters-schema.json#/definitions/RedundantAccessToObject" + }, + "RefOveruse": { + "$ref": "parameters-schema.json#/definitions/RefOveruse" + }, "SelfAssign": { "$ref": "parameters-schema.json#/definitions/SelfAssign" }, @@ -510,6 +543,22 @@ ], "title": "Diagnostics enabling/disabling mode.", "default": "on" + }, + "ordinaryAppSupport": { + "$id": "#/properties/ordinaryAppSupport", + "type": "boolean", + "title": "Ordinary client support. Diagnostics will require taking into account the features of a ordinary application.", + "default": true, + "oneOf": [ + { + "const": true, + "description": "Configuration uses ordinary application (default)." + }, + { + "const": false, + "description": "Ignore ordinary application warnings." + } + ] } } }, diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeOutOfRegionDiagnostic_en.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeOutOfRegionDiagnostic_en.properties index 68c84cce80e..0a57ff175b4 100644 --- a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeOutOfRegionDiagnostic_en.properties +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeOutOfRegionDiagnostic_en.properties @@ -1,2 +1,3 @@ diagnosticMessage=Move code to region diagnosticName=Code out of region +checkUnknownModuleType=Check unknown module type diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeOutOfRegionDiagnostic_ru.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeOutOfRegionDiagnostic_ru.properties index f6c4ae83fed..d85a7563952 100644 --- a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeOutOfRegionDiagnostic_ru.properties +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeOutOfRegionDiagnostic_ru.properties @@ -1,2 +1,3 @@ diagnosticMessage=Переместите код в область diagnosticName=Код расположен вне области +checkUnknownModuleType=Проверять неизвестные типы модулей diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommandModuleExportMethodsDiagnostic_en.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommandModuleExportMethodsDiagnostic_en.properties new file mode 100644 index 00000000000..64b07a542b3 --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommandModuleExportMethodsDiagnostic_en.properties @@ -0,0 +1,2 @@ +diagnosticMessage=You should not place export methods in command and general command modules +diagnosticName=Export methods in command and general command modules diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommandModuleExportMethodsDiagnostic_ru.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommandModuleExportMethodsDiagnostic_ru.properties new file mode 100644 index 00000000000..67405d57396 --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommandModuleExportMethodsDiagnostic_ru.properties @@ -0,0 +1,2 @@ +diagnosticMessage=Не следует размещать экспортные методы в модулях команд и общих команд +diagnosticName=Экспортные методы в модулях команд и общих команд diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/CreateQueryInCycleDiagnostic_ru.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/CreateQueryInCycleDiagnostic_ru.properties index dce29154096..8a3920c4b51 100644 --- a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/CreateQueryInCycleDiagnostic_ru.properties +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/CreateQueryInCycleDiagnostic_ru.properties @@ -1,2 +1,2 @@ diagnosticName=Выполнение запроса в цикле -diagnosticMessage=Необходимо модифицировать запрос для подержки множества значений и удалить цикл +diagnosticMessage=Необходимо модифицировать запрос для поддержки множества значений и удалить цикл diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/FunctionOutParameterDiagnostic_en.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/FunctionOutParameterDiagnostic_en.properties new file mode 100644 index 00000000000..07fd4968db6 --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/FunctionOutParameterDiagnostic_en.properties @@ -0,0 +1,2 @@ +diagnosticMessage=Function parameter shouldn't return a value +diagnosticName=Out function parameter diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/FunctionOutParameterDiagnostic_ru.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/FunctionOutParameterDiagnostic_ru.properties new file mode 100644 index 00000000000..464dd568b77 --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/FunctionOutParameterDiagnostic_ru.properties @@ -0,0 +1,2 @@ +diagnosticMessage=Параметр функции не должен возвращать значение +diagnosticName=Исходящий параметр функции diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/GlobalContextMethodCollision8312Diagnostic_en.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/GlobalContextMethodCollision8312Diagnostic_en.properties new file mode 100644 index 00000000000..0ba217e4051 --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/GlobalContextMethodCollision8312Diagnostic_en.properties @@ -0,0 +1,2 @@ +diagnosticMessage=Method "%s" needs to be removed or renamed +diagnosticName=Global context method names collision diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/GlobalContextMethodCollision8312Diagnostic_ru.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/GlobalContextMethodCollision8312Diagnostic_ru.properties new file mode 100644 index 00000000000..879f9e418c0 --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/GlobalContextMethodCollision8312Diagnostic_ru.properties @@ -0,0 +1,2 @@ +diagnosticMessage=Метод "%s" должен быть удален или переименован +diagnosticName=Конфликт имен методов с методами глобального контекста diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/LatinAndCyrillicSymbolInWordDiagnostic_en.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/LatinAndCyrillicSymbolInWordDiagnostic_en.properties new file mode 100644 index 00000000000..a06440461f6 --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/LatinAndCyrillicSymbolInWordDiagnostic_en.properties @@ -0,0 +1,3 @@ +diagnosticMessage=Can't use Latin and Cyrillic characters in one identifier +diagnosticName=Mixing Latin and Cyrillic characters in one identifier +excludeWords=A list of exclusion words, specified as a comma-separated string diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/LatinAndCyrillicSymbolInWordDiagnostic_ru.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/LatinAndCyrillicSymbolInWordDiagnostic_ru.properties new file mode 100644 index 00000000000..5fe2a1a935f --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/LatinAndCyrillicSymbolInWordDiagnostic_ru.properties @@ -0,0 +1,3 @@ +diagnosticMessage=Нельзя использовать латинские и кириллические символы в одном идентификаторе +diagnosticName=Смешивание латинских и кириллических символов в одном идентификаторе +excludeWords=Список слов-исключений, задается строкой через запятую \ No newline at end of file diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic_en.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic_en.properties new file mode 100644 index 00000000000..be6acd86912 --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic_en.properties @@ -0,0 +1,4 @@ +diagnosticMessage=Assign this magic number "%s" to a well-named constant, and use the constant instead. +diagnosticName=Magic dates + +authorizedDates=Allowed dates, comma separated. Example: 00010101,00010101000000,000101010000 diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic_ru.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic_ru.properties new file mode 100644 index 00000000000..3eaaf6e5c5d --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnostic_ru.properties @@ -0,0 +1,4 @@ +diagnosticMessage=Создайте переменную с понятным названием, присвойте ей значение "%s" и используйте эту константу вместо магической даты. +diagnosticName=Магические даты + +authorizedDates=Разрешенные даты, через запятую. Например: 00010101,00010101000000,000101010000 \ No newline at end of file diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingEventSubscriptionHandlerDiagnostic_en.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingEventSubscriptionHandlerDiagnostic_en.properties new file mode 100644 index 00000000000..edb9161d0f0 --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingEventSubscriptionHandlerDiagnostic_en.properties @@ -0,0 +1,8 @@ +diagnosticMessage=Fill out the "%s" event subscription +diagnosticName=Event subscription handler missing +incorrectHandler=Fix incorrect handler "%s" for "%s" event subscription +missingModule=Create common module "%s" or fix incorrect handler "%s" for "%s" event subscription +shouldBeServer=Set "Server" for common module "%s" or fix incorrect handler "%s" for "%s" event subscription +missingMethod=Create procedure "%s" or fix incorrect handler "%s" for "%s" event subscription +nonExportMethod=Set "Export" for procedure "%s" or fix incorrect handler "%s" for "%s" event subscription + diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingEventSubscriptionHandlerDiagnostic_ru.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingEventSubscriptionHandlerDiagnostic_ru.properties new file mode 100644 index 00000000000..8d7984a8afe --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingEventSubscriptionHandlerDiagnostic_ru.properties @@ -0,0 +1,7 @@ +diagnosticMessage=Заполните обработчик подписки на событие "%s" +diagnosticName=Отсутствует обработчик подписки на событие +incorrectHandler=Исправьте некорректный обработчик "%s" у подписки на событие "%s" +missingModule=Создайте модуль "%s" или исправьте некорректный обработчик подписки на событие "%s" +shouldBeServer=Добавьте "Сервер" модулю "%s" или исправьте некорректный обработчик подписки на событие "%s" +missingMethod=Создайте процедуру "%s" или исправьте некорректный обработчик подписки на событие "%s" +nonExportMethod=Добавьте "Экспорт" процедуре "%s" или исправьте некорректный обработчик подписки на событие "%s" diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingParameterDescriptionDiagnostic_en.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingParameterDescriptionDiagnostic_en.properties new file mode 100644 index 00000000000..b86ac31152d --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingParameterDescriptionDiagnostic_en.properties @@ -0,0 +1,6 @@ +diagnosticMessage=Add description for all method parameters +diagnosticName=Method parameters description are missing +missingDescription=Add description for the "%s" parameter +emptyDescription=Add type description for the "%s" parameter +missingInSignature=Remove description for the "%s", they are missing in the signature +wrongOrder=Correct the order for parameter descriptions diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingParameterDescriptionDiagnostic_ru.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingParameterDescriptionDiagnostic_ru.properties new file mode 100644 index 00000000000..451cf342263 --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingParameterDescriptionDiagnostic_ru.properties @@ -0,0 +1,6 @@ +diagnosticMessage=Необходимо добавить описание всех параметров метода +diagnosticName=Отсутствует описание параметров метода +missingDescription=Необходимо добавить описание параметра "%s" +emptyDescription=Необходимо добавить описание типа параметра "%s" +missingInSignature=Необходимо удалить описания параметров "%s", отсутствующих в сигнатуре метода +wrongOrder=Необходимо исправить порядок описаний параметров diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingReturnedValueDescriptionDiagnostic_en.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingReturnedValueDescriptionDiagnostic_en.properties new file mode 100644 index 00000000000..9b19b25d510 --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingReturnedValueDescriptionDiagnostic_en.properties @@ -0,0 +1,4 @@ +diagnosticMessage=Add description for returned value function +diagnosticName=Function returned values description is missing +isProcedure=Remove returned values description for procedure +typesWithoutDescription=Add description for the "%s" types of the function returned value diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingReturnedValueDescriptionDiagnostic_ru.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingReturnedValueDescriptionDiagnostic_ru.properties new file mode 100644 index 00000000000..d022e8d944a --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingReturnedValueDescriptionDiagnostic_ru.properties @@ -0,0 +1,4 @@ +diagnosticMessage=Добавьте описание возвращаемого значения функции +diagnosticName=Отсутствует описание возвращаемого значения функции +isProcedure=Удалите описание возвращаемого значения для процедуры +typesWithoutDescription=Необходимо добавить описание типов "%s" возвращаемого значения \ No newline at end of file diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingSpaceDiagnostic_en.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingSpaceDiagnostic_en.properties index bc529e8370b..59c90122442 100644 --- a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingSpaceDiagnostic_en.properties +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingSpaceDiagnostic_en.properties @@ -1,11 +1,11 @@ -diagnosticMessage=%s of the character %s missing space -diagnosticName=Missing spaces to the left or right of operators + - * / = % < > <> <= >=, and also to the right of , and ; +diagnosticMessage=%s of the '%s' missing space +diagnosticName=Missing spaces to the left or right of operators + - * / = % < > <> <= >=, keywords, and also to the right of , and ; quickFixMessage=Add space wordLeft=To the left wordRight=To the right wordLeftAndRight=Left and right -listForCheckLeft=List of symbols to check for the space to the left of (separated by space) -listForCheckRight=List of symbols to check for the space to the right of (separated by space) -listForCheckLeftAndRight=List of symbols to check for the space from both sides of (separated by space) +listForCheckLeft=List to check for the space to the left of (separated by space) +listForCheckRight=List to check for the space to the right of (separated by space) +listForCheckLeftAndRight=List to check for the space from both sides of (separated by space) checkSpaceToRightOfUnary=Check for space to the right of unary signs (+ -) allowMultipleCommas=Allow several commas in a row diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingSpaceDiagnostic_ru.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingSpaceDiagnostic_ru.properties index 254b9b3ce9e..de8bed7176d 100644 --- a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingSpaceDiagnostic_ru.properties +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingSpaceDiagnostic_ru.properties @@ -1,11 +1,11 @@ -diagnosticMessage=%s от символа %s не хватает пробела -diagnosticName=Пропущены пробелы слева или справа от операторов `+ - * / = % < > <> <= >=`, а так же справа от `,` и `;` +diagnosticMessage=%s от '%s' не хватает пробела +diagnosticName=Пропущены пробелы слева или справа от операторов `+ - * / = % < > <> <= >=`, от ключевых слов, а так же справа от `,` и `;` quickFixMessage=Добавить пробел wordLeft=Слева wordRight=Справа wordLeftAndRight=Слева и справа -listForCheckLeft=Список символов для проверки слева (разделенные пробелом). Например: ) = -listForCheckRight=Список символов для проверки справа (разделенные пробелом). Например: ( = -listForCheckLeftAndRight=Список символов для проверки с обоих сторон (разделенные пробелом). Например: + - * / = % < > +listForCheckLeft=Список для проверки слева (разделенные пробелом). Например: ) = +listForCheckRight=Список для проверки справа (разделенные пробелом). Например: ( = +listForCheckLeftAndRight=Список для проверки с обоих сторон (разделенные пробелом). Например: + - * / = % < > checkSpaceToRightOfUnary=Проверять наличие пробела справа от унарных знаков (+ -) allowMultipleCommas=Разрешать несколько запятых подряд \ No newline at end of file diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/OrdinaryAppSupportDiagnostic_en.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/OrdinaryAppSupportDiagnostic_en.properties new file mode 100644 index 00000000000..8f32b76dd31 --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/OrdinaryAppSupportDiagnostic_en.properties @@ -0,0 +1,4 @@ +managedFormInOrdinaryApp=Set property "Use managed form in ordinary application" to True +ordinaryFormInManagedApp=Set property "Use ordinary form in managed application" to False +diagnosticMessage=Ordinary application support +diagnosticName=Ordinary application support diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/OrdinaryAppSupportDiagnostic_ru.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/OrdinaryAppSupportDiagnostic_ru.properties new file mode 100644 index 00000000000..4aa93ffa1c7 --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/OrdinaryAppSupportDiagnostic_ru.properties @@ -0,0 +1,4 @@ +managedFormInOrdinaryApp=Установите свойство "Использовать управляемые формы в обычном приложении" в Истина +ordinaryFormInManagedApp=Установите свойство "Использовать обычные формы в управляемом режиме" установить в Ложь +diagnosticMessage=Поддержка обычного приложения +diagnosticName=Поддержка обычного приложения diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/RedundantAccessToObjectDiagnostic_en.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/RedundantAccessToObjectDiagnostic_en.properties new file mode 100644 index 00000000000..e1ff5cf8c5d --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/RedundantAccessToObjectDiagnostic_en.properties @@ -0,0 +1,6 @@ +diagnosticMessage=Get rid of redundant calls within a module via its name or alias ThisObject +diagnosticName=Redundant access to an object + +checkObjectModule=Check object modules +checkFormModule=Check form modules +checkRecordSetModule=Check record set modules \ No newline at end of file diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/RedundantAccessToObjectDiagnostic_ru.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/RedundantAccessToObjectDiagnostic_ru.properties new file mode 100644 index 00000000000..b257e39cc33 --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/RedundantAccessToObjectDiagnostic_ru.properties @@ -0,0 +1,6 @@ +diagnosticMessage=Избавьтесь от избыточного обращения внутри модуля через его имя или псевдоним ЭтотОбъект +diagnosticName=Избыточное обращение к объекту + +checkObjectModule=Проверять модули объектов +checkFormModule=Проверять модули форм +checkRecordSetModule=Проверять модули наборов записей \ No newline at end of file diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/RefOveruseDiagnostic_en.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/RefOveruseDiagnostic_en.properties new file mode 100644 index 00000000000..7c0dc428320 --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/RefOveruseDiagnostic_en.properties @@ -0,0 +1,2 @@ +diagnosticMessage=Get rid of getting the "Reference" field in the query. +diagnosticName=Overuse "Reference" in a query diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/RefOveruseDiagnostic_ru.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/RefOveruseDiagnostic_ru.properties new file mode 100644 index 00000000000..b7311d9682c --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/RefOveruseDiagnostic_ru.properties @@ -0,0 +1,2 @@ +diagnosticMessage=Избавьтесь от получения поля "Ссылка" в запросе. +diagnosticName=Избыточное использование "Ссылка" в запросе diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic_en.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic_en.properties index 7c72bc94c95..9b511ea6574 100644 --- a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic_en.properties +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic_en.properties @@ -7,4 +7,4 @@ diagnosticExceptions=Str,Autotest,Infobase,Enums,Len,Desc,Asc,Overridable,GUID,E Sys,Saas,www,yyyy,xsl,src,deserialization,Params,Archiver,Serializer,xsi,ico,epf,cfu,txt,htm,rtf,ppt,vsd,mpp,mdb,msg,rar,exe,grs,geo,jpg,bmp,\ tif,gif,png,pdf,odt,odf,odp,odg,ods,erf,docx,xlsx,pptx,utf,xsd,SRVR,saas,wsdl,Apdex,APDEX,uid,XLS,XLSX,html,TXT,ODT,Addin,DIB minWordLength=Minimum length for checked words -userWordsToIgnore=Dictionary for excluding words (comma separated, without spaces) \ No newline at end of file +userWordsToIgnore=Dictionary for excluding words (comma separated) \ No newline at end of file diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic_ru.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic_ru.properties index 53e9da049f3..c8f1da4a329 100644 --- a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic_ru.properties +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic_ru.properties @@ -14,4 +14,4 @@ diagnosticExceptions=Автогенерируемых,Автогруппиров ,Сериализованный,Сис,Сконвертировать,Слеш,Слеша,Слеши,Стартован,Стикера,Стр,Студотряде,Субконто,Таб,Техподдержки\ ,Токене,Транслите,Тэги,Тэгов,Убыв,Физлица,Финализировать,Фич,Хэш,Штрихкодам,Штрихкодом,Штрихкоду,Мдд,Чммсс minWordLength=Минимальная длина проверяемых слов -userWordsToIgnore=Пользовательский словарь исключений (через запятую, без пробелов) \ No newline at end of file +userWordsToIgnore=Пользовательский словарь исключений (через запятую) \ No newline at end of file diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/UsingModalWindowsDiagnostic_en.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/UsingModalWindowsDiagnostic_en.properties index c4d412ed54e..f57c5b331fb 100644 --- a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/UsingModalWindowsDiagnostic_en.properties +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/UsingModalWindowsDiagnostic_en.properties @@ -1,2 +1,3 @@ diagnosticMessage=Instead of the modal method `%s`, use `%s` diagnosticName=Using modal windows +forceModalityMode=Ignore configurations modality mode diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/UsingModalWindowsDiagnostic_ru.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/UsingModalWindowsDiagnostic_ru.properties index 5b3c121810f..4c6ea99d831 100644 --- a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/UsingModalWindowsDiagnostic_ru.properties +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/UsingModalWindowsDiagnostic_ru.properties @@ -1,2 +1,3 @@ diagnosticMessage=Вместо модального метода `%s` необходимо использовать `%s` diagnosticName=Использование модальных окон +forceModalityMode=Игнорировать использование модальности конфигурации \ No newline at end of file diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/AutoServerInfoTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/AutoServerInfoTest.java new file mode 100644 index 00000000000..024cbe6f880 --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/AutoServerInfoTest.java @@ -0,0 +1,41 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest +class AutoServerInfoTest { + + @Autowired + private AutoServerInfo autoServerInfo; + + @Test + void testDataIsFilled() { + assertThat(autoServerInfo.getName()).isNotBlank(); + assertThat(autoServerInfo.getVersion()).isNotBlank(); + } +} \ No newline at end of file diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/BSLLSPLauncherTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/BSLLSPLauncherTest.java index 1e6b9056c9a..cfa1738ebb6 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/BSLLSPLauncherTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/BSLLSPLauncherTest.java @@ -135,7 +135,27 @@ void testAnalyzeError() { @ExpectSystemExitWithStatus(0) void testFormat() { // given - String[] args = "--format --srcDir ./src/test/resources/cli".split(" "); + String[] args = "--format --src ./src/test/resources/cli".split(" "); + + // when + try { + BSLLSPLauncher.main(args); + } catch (RuntimeException ignored) { + // catch prevented system.exit call + } + + // then + // main-method should runs without exceptions + assertThat(outContent.toString()).isEmpty(); + // assertThat(errContent.toString()).contains("100%"); + assertThat(errContent.toString()).doesNotContain("ERROR"); + } + + @Test + @ExpectSystemExitWithStatus(0) + void testFormatOneFile() { + // given + String[] args = "--format --src ./src/test/resources/cli/test.bsl.txt".split(" "); // when try { @@ -155,7 +175,7 @@ void testFormat() { @ExpectSystemExitWithStatus(0) void testFormatSilent() { // given - String[] args = "--format --srcDir ./src/test/resources/cli --silent".split(" "); + String[] args = "--format --src ./src/test/resources/cli --silent".split(" "); // when try { @@ -174,7 +194,7 @@ void testFormatSilent() { @ExpectSystemExitWithStatus(1) void testFormatError() { // given - String[] args = "--format --srcDir fake-dir".split(" "); + String[] args = "--format --src fake-dir".split(" "); // when try { diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/BSLTextDocumentServiceTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/BSLTextDocumentServiceTest.java index e5a0c9b503f..365e1e697d1 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/BSLTextDocumentServiceTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/BSLTextDocumentServiceTest.java @@ -247,7 +247,7 @@ void testDiagnosticsUnknownFile() throws ExecutionException, InterruptedExceptio var diagnostics = textDocumentService.diagnostics(params).get(); // then - assertThat(diagnostics).isEmpty(); + assertThat(diagnostics.getDiagnostics()).isEmpty(); } @Test @@ -262,7 +262,7 @@ void testDiagnosticsKnownFile() throws ExecutionException, InterruptedException, var diagnostics = textDocumentService.diagnostics(params).get(); // then - assertThat(diagnostics).isNotEmpty(); + assertThat(diagnostics.getDiagnostics()).isNotEmpty(); } @Test @@ -278,7 +278,7 @@ void testDiagnosticsKnownFileFilteredRange() throws ExecutionException, Interrup var diagnostics = textDocumentService.diagnostics(params).get(); // then - assertThat(diagnostics).hasSize(1); + assertThat(diagnostics.getDiagnostics()).hasSize(1); } private File getTestFile() { diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/cli/VersionCommandTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/cli/VersionCommandTest.java new file mode 100644 index 00000000000..042d8237bae --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/cli/VersionCommandTest.java @@ -0,0 +1,67 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.cli; + +import com.github._1c_syntax.bsl.languageserver.AutoServerInfo; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.annotation.DirtiesContext; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +@SpringBootTest +@DirtiesContext +class VersionCommandTest { + + @MockBean + private AutoServerInfo autoServerInfo; + + @Autowired + private VersionCommand command; + + @Test + void testFailedCall() { + // given + when(autoServerInfo.getVersion()).thenReturn(""); + + // when + var call = command.call(); + + // then + assertThat(call).isEqualTo(1); + } + + @Test + void testSuccessfulCall() { + // given + when(autoServerInfo.getVersion()).thenReturn("0.0.0"); + + // when + var call = command.call(); + + // then + assertThat(call).isZero(); + } +} \ No newline at end of file diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/codeactions/DisableDiagnosticTriggeringSupplierTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/codeactions/DisableDiagnosticTriggeringSupplierTest.java new file mode 100644 index 00000000000..2a808ea35bf --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/codeactions/DisableDiagnosticTriggeringSupplierTest.java @@ -0,0 +1,207 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.codeactions; + +import com.github._1c_syntax.bsl.languageserver.configuration.Language; +import com.github._1c_syntax.bsl.languageserver.configuration.LanguageServerConfiguration; +import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; +import com.github._1c_syntax.bsl.languageserver.providers.CodeActionProvider; +import com.github._1c_syntax.bsl.languageserver.util.TestUtils; +import com.github._1c_syntax.bsl.languageserver.utils.Ranges; +import org.eclipse.lsp4j.CodeAction; +import org.eclipse.lsp4j.CodeActionContext; +import org.eclipse.lsp4j.CodeActionParams; +import org.eclipse.lsp4j.Command; +import org.eclipse.lsp4j.Range; +import org.eclipse.lsp4j.TextDocumentIdentifier; +import org.eclipse.lsp4j.jsonrpc.messages.Either; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; + + +@SpringBootTest +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +class DisableDiagnosticTriggeringSupplierTest { + + private final CodeActionProvider codeActionProvider; + + public DisableDiagnosticTriggeringSupplierTest() { + + List codeActionSuppliers = new ArrayList<>(); + var configuration = new LanguageServerConfiguration(); + configuration.setLanguage(Language.EN); + codeActionSuppliers.add(new DisableDiagnosticTriggeringSupplier(configuration)); + codeActionProvider = new CodeActionProvider(codeActionSuppliers); + + } + + @Test + void testGetCodeActions() { + + DocumentContext documentContext = TestUtils.getDocumentContextFromFile( + "./src/test/resources/suppliers/disableDiagnosticTriggering.bsl" + ); + + TextDocumentIdentifier textDocumentIdentifier = new TextDocumentIdentifier(documentContext.getUri().toString()); + + CodeActionContext codeActionContext = new CodeActionContext(); + codeActionContext.setDiagnostics(documentContext.getDiagnostics()); + + CodeActionParams params = new CodeActionParams(); + params.setRange(new Range()); + params.setTextDocument(textDocumentIdentifier); + params.setContext(codeActionContext); + + List> codeActions = codeActionProvider.getCodeActions(params, documentContext); + + assertThat(codeActions) + .hasSize(10) + .extracting(Either::getRight) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable all diagnostic in file")) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable NumberOfValuesInStructureConstructor in file")) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable ExportVariables in file")) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable IfElseDuplicatedCondition in file")) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable CanonicalSpellingKeywords in file")) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable FunctionShouldHaveReturn in file")) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable IfElseIfEndsWithElse in file")) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable MagicNumber in file")) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable MissingSpace in file")) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable MissingVariablesDescription in file")) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable all diagnostic in file")); + } + + @Test + void testGetCodeActionsOneLine() { + + DocumentContext documentContext = TestUtils.getDocumentContextFromFile( + "./src/test/resources/suppliers/disableDiagnosticTriggering.bsl" + ); + + TextDocumentIdentifier textDocumentIdentifier = new TextDocumentIdentifier(documentContext.getUri().toString()); + + Range range = Ranges.create(53, 0, 53, 30); + + CodeActionContext codeActionContext = new CodeActionContext(); + codeActionContext.setDiagnostics( + documentContext + .getDiagnostics() + .stream() + .filter(diagnostic -> + Ranges.containsRange(range, diagnostic.getRange()) + ) + .collect(Collectors.toList()) + ); + + CodeActionParams params = new CodeActionParams(); + params.setRange(range); + params.setTextDocument(textDocumentIdentifier); + params.setContext(codeActionContext); + + List> codeActions = codeActionProvider.getCodeActions(params, documentContext); + + assertThat(codeActions) + .hasSize(6) + .extracting(Either::getRight) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable MagicNumber in line")) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable MissingSpace in line")) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable MagicNumber in file")) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable MissingSpace in file")) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable all diagnostic in line")) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable all diagnostic in file")); + + } + + @Test + void testGetCodeActionsRegion() { + + DocumentContext documentContext = TestUtils.getDocumentContextFromFile( + "./src/test/resources/suppliers/disableDiagnosticTriggering.bsl" + ); + + TextDocumentIdentifier textDocumentIdentifier = new TextDocumentIdentifier(documentContext.getUri().toString()); + + Range range = Ranges.create(53, 0, 56, 38); + + CodeActionContext codeActionContext = new CodeActionContext(); + codeActionContext.setDiagnostics( + documentContext + .getDiagnostics() + .stream() + .filter(diagnostic -> Ranges.containsRange(range, diagnostic.getRange())) + .collect(Collectors.toList()) + ); + + CodeActionParams params = new CodeActionParams(); + params.setRange(range); + params.setTextDocument(textDocumentIdentifier); + params.setContext(codeActionContext); + + List> codeActions = codeActionProvider.getCodeActions(params, documentContext); + + assertThat(codeActions) + .hasSize(8) + .extracting(Either::getRight) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable MagicNumber in range")) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable MissingSpace in range")) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable MagicNumber in file")) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable MissingSpace in file")) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable all diagnostic in range")) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable all diagnostic in file")) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable CanonicalSpellingKeywords in range")) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable CanonicalSpellingKeywords in file")); + + } + + @Test + void testGetCodeActionsEmptyFile() { + + DocumentContext documentContext = TestUtils.getDocumentContextFromFile( + "./src/test/resources/suppliers/disableDiagnosticTriggeringEmpty.bsl" + ); + + TextDocumentIdentifier textDocumentIdentifier = new TextDocumentIdentifier(documentContext.getUri().toString()); + + CodeActionContext codeActionContext = new CodeActionContext(); + codeActionContext.setDiagnostics(documentContext.getDiagnostics()); + + CodeActionParams params = new CodeActionParams(); + params.setRange(new Range()); + params.setTextDocument(textDocumentIdentifier); + params.setContext(codeActionContext); + + List> codeActions = codeActionProvider.getCodeActions(params, documentContext); + + assertThat(codeActions) + .hasSize(1) + .extracting(Either::getRight) + .anyMatch(codeAction -> codeAction.getTitle().equals("Disable all diagnostic in file")); + + } +} \ No newline at end of file diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/codeactions/GenerateStandardRegionsSupplierTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/codeactions/GenerateStandardRegionsSupplierTest.java index 9c63e6bbb68..de44288732c 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/codeactions/GenerateStandardRegionsSupplierTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/codeactions/GenerateStandardRegionsSupplierTest.java @@ -74,7 +74,7 @@ void testGetCodeActions() { System.out.println(codeActions.get(0).getRight().getEdit().getChanges()); assertThat(codeActions) - .hasSize(1) + .hasSize(2) .extracting(Either::getRight) .anyMatch(codeAction -> codeAction.getTitle().equals("Generate missing regions")); } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/configuration/LanguageServerConfigurationTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/configuration/LanguageServerConfigurationTest.java index 17ba056a7e8..8a8985aeaec 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/configuration/LanguageServerConfigurationTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/configuration/LanguageServerConfigurationTest.java @@ -71,6 +71,7 @@ void createDefault() { // then assertThat(configuration.getLanguage()).isEqualTo(Language.RU); assertThat(configuration.getDiagnosticsOptions().getParameters()).isEmpty(); + assertThat(configuration.getDiagnosticsOptions().isOrdinaryAppSupport()).isTrue(); } @Test @@ -105,6 +106,7 @@ void createFromFile() { assertThat(configurationRoot).isNotNull(); assertThat(configuration.getDocumentLinkOptions().isUseDevSite()).isTrue(); + assertThat(configuration.getDiagnosticsOptions().isOrdinaryAppSupport()).isFalse(); } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentContextTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentContextTest.java index 41c9d1d3baf..da266669395 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentContextTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentContextTest.java @@ -53,7 +53,7 @@ void testRebuild() throws IOException { File file = new File("./src/test/resources/context/DocumentContextRebuildSecondTest.bsl"); String fileContent = FileUtils.readFileToString(file, StandardCharsets.UTF_8); - documentContext.rebuild(fileContent); + documentContext.rebuild(fileContent, documentContext.getVersion() + 1); assertThat(documentContext.getTokens()).hasSize(16); } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/ServerContextTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/ServerContextTest.java index 16d58c7be3c..00dffb9ee63 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/ServerContextTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/ServerContextTest.java @@ -136,7 +136,7 @@ void testPopulateContext() { private DocumentContext addDocumentContext(ServerContext serverContext, String path) throws IOException { var file = new File(PATH_TO_METADATA, path); var uri = Absolute.uri(file); - return serverContext.addDocument(uri, FileUtils.readFileToString(file, StandardCharsets.UTF_8)); + return serverContext.addDocument(uri, FileUtils.readFileToString(file, StandardCharsets.UTF_8), 0); } } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/computer/MethodSymbolComputerTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/computer/MethodSymbolComputerTest.java index 04a2641d23c..aa0894ec4a7 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/computer/MethodSymbolComputerTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/computer/MethodSymbolComputerTest.java @@ -209,18 +209,22 @@ void testParameters() { assertThat(parameters.get(0).getName()).isEqualTo("Парам"); assertThat(parameters.get(0).isByValue()).isFalse(); assertThat(parameters.get(0).isOptional()).isFalse(); + assertThat(parameters.get(0).getRange()).isEqualTo(Ranges.create(14, 12, 17)); assertThat(parameters.get(1).getName()).isEqualTo("Парам2"); assertThat(parameters.get(1).isByValue()).isTrue(); assertThat(parameters.get(1).isOptional()).isFalse(); + assertThat(parameters.get(1).getRange()).isEqualTo(Ranges.create(14, 24, 30)); assertThat(parameters.get(2).getName()).isEqualTo("Парам3"); assertThat(parameters.get(2).isByValue()).isFalse(); assertThat(parameters.get(2).isOptional()).isTrue(); + assertThat(parameters.get(2).getRange()).isEqualTo(Ranges.create(14, 32, 38)); assertThat(parameters.get(3).getName()).isEqualTo("Парам4"); assertThat(parameters.get(3).isByValue()).isTrue(); assertThat(parameters.get(3).isOptional()).isTrue(); + assertThat(parameters.get(3).getRange()).isEqualTo(Ranges.create(14, 49, 55)); } @@ -249,8 +253,8 @@ void testMdoRef() throws IOException { var path = Absolute.path(PATH_TO_METADATA); serverContext.setConfigurationRoot(path); - checkModule(serverContext, PATH_TO_MODULE_FILE, "CommonModule.ПервыйОбщийМодуль", 5); - checkModule(serverContext, PATH_TO_CATALOG_FILE, "Catalog.Справочник1", 1); + checkModule(serverContext, PATH_TO_MODULE_FILE, "CommonModule.ПервыйОбщийМодуль", 7); + checkModule(serverContext, PATH_TO_CATALOG_FILE, "Catalog.Справочник1", 2); checkModule(serverContext, PATH_TO_CATALOG_MODULE_FILE, "Catalog.Справочник1", 1); } @@ -280,7 +284,7 @@ private void checkModule( ) throws IOException { var file = new File(PATH_TO_METADATA, path); var uri = Absolute.uri(file); - var documentContext = serverContext.addDocument(uri, FileUtils.readFileToString(file, StandardCharsets.UTF_8)); + var documentContext = serverContext.addDocument(uri, FileUtils.readFileToString(file, StandardCharsets.UTF_8), 0); List methods = documentContext.getSymbolTree().getMethods(); assertThat(methods.size()).isEqualTo(methodsCount); assertThat(methods.get(0).getName()).isEqualTo("Тест"); diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/computer/QueryComputerTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/computer/QueryComputerTest.java index 71f1537ed08..1366fe0496e 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/computer/QueryComputerTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/computer/QueryComputerTest.java @@ -43,6 +43,12 @@ void compute() { var queries = documentContext.getQueries(); //then - assertThat(queries).hasSize(6); + assertThat(queries).hasSize(10); + assertThat(queries.get(0).getTokens().get(1).getLine()).isEqualTo(3); + assertThat(queries.get(6).getTokens().get(2).getLine()).isEqualTo(30); + assertThat(queries.get(8).getTokens().get(1).getLine()).isEqualTo(45); + assertThat(queries.get(8).getTokens().get(31).getLine()).isEqualTo(50); + assertThat(queries.get(9).getTokens().get(9).getLine()).isEqualTo(59); + } } \ No newline at end of file diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/MethodDescriptionTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/MethodDescriptionTest.java new file mode 100644 index 00000000000..6f0a8859846 --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/context/symbol/MethodDescriptionTest.java @@ -0,0 +1,352 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.context.symbol; + +import com.github._1c_syntax.bsl.languageserver.util.TestUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +class MethodDescriptionTest { + + private List methodsWithDescription; + + @BeforeEach + void prepare() { + if (methodsWithDescription == null) { + var documentContext = TestUtils.getDocumentContextFromFile("./src/test/resources/context/symbol/MethodDescription.bsl"); + var methods = documentContext.getSymbolTree().getMethods(); + + assertThat(methods.size()).isEqualTo(11); + + methodsWithDescription = methods.stream() + .map(MethodSymbol::getDescription) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()); + + assertThat(methodsWithDescription.size()).isEqualTo(10); + } + } + + @Test + void testMethod10() { + var method = methodsWithDescription.get(9); + assertThat(method.getPurposeDescription()) + .isEqualTo("См. ОбщийМодуль.Метод()"); + assertThat(method.isDeprecated()).isFalse(); + assertThat(method.getDeprecationInfo()).isEmpty(); + assertThat(method.getExamples()).isEmpty(); + assertThat(method.getCallOptions()).isEmpty(); + assertThat(method.getParameters()).isEmpty(); + assertThat(method.getReturnedValue()).isEmpty(); + assertThat(method.getLink()).isEqualTo("ОбщийМодуль.Метод()"); + } + + @Test + void testMethod9() { + var method = methodsWithDescription.get(8); + assertThat(method.getPurposeDescription()) + .isEqualTo("Описание метода\n\n Несколько строк"); + assertThat(method.isDeprecated()).isFalse(); + assertThat(method.getDeprecationInfo()).isEmpty(); + assertThat(method.getExamples()).isEmpty(); + assertThat(method.getCallOptions()).isEmpty(); + assertThat(method.getParameters()).isEmpty(); + assertThat(method.getReturnedValue()).hasSize(1); + assertThat(method.getLink()).isEmpty(); + } + + @Test + void testMethod8() { + var method = methodsWithDescription.get(7); + assertThat(methodsWithDescription.get(7).getPurposeDescription()) + .isEqualTo("Описание метода\n\n Несколько строк"); + assertThat(method.isDeprecated()).isFalse(); + assertThat(method.getDeprecationInfo()).isEmpty(); + assertThat(method.getExamples()).isEmpty(); + assertThat(method.getCallOptions()).isEmpty(); + assertThat(method.getParameters()).hasSize(3); + assertThat(method.getReturnedValue()).hasSize(1); + assertThat(method.getLink()).isEmpty(); + } + + @Test + void testMethod7() { + var method = methodsWithDescription.get(6); + assertThat(method.getPurposeDescription()) + .isEqualTo("Описание метода\n\n Несколько строк"); + assertThat(method.isDeprecated()).isTrue(); + assertThat(method.getDeprecationInfo()) + .isEqualTo("Следует использовать новую см. ОбщегоНазначения.Метод()"); + assertThat(method.getExamples()).hasSize(2); + assertThat(method.getExamples().get(0)) + .isEqualTo("Пример0(Тип11, Тип21) - описание ..."); + assertThat(method.getCallOptions()).hasSize(2); + assertThat(method.getCallOptions().get(0)) + .isEqualTo("УниверсальнаяПроцедура(Тип11, Тип21) - описание ..."); + assertThat(method.getParameters()).hasSize(3); + assertThat(method.getReturnedValue()).hasSize(2); + assertThat(method.getLink()).isEmpty(); + } + + @Test + void testMethod6() { + var method = methodsWithDescription.get(5); + assertThat(method.getPurposeDescription()).isEmpty(); + assertThat(method.isDeprecated()).isTrue(); + assertThat(method.getDeprecationInfo()) + .isEqualTo("Следует использовать новую см. ОбщегоНазначения.Метод()"); + assertThat(method.getExamples()).isEmpty(); + assertThat(method.getCallOptions()).isEmpty(); + assertThat(method.getParameters()).isEmpty(); + assertThat(method.getReturnedValue()).isEmpty(); + assertThat(method.getLink()).isEmpty(); + } + + @Test + void testMethod5() { + var method = methodsWithDescription.get(4); + assertThat(method.getPurposeDescription()).isEmpty(); + assertThat(method.isDeprecated()).isFalse(); + assertThat(method.getDeprecationInfo()).isEmpty(); + assertThat(method.getExamples()).hasSize(2); + assertThat(method.getExamples().get(0)) + .isEqualTo("УниверсальнаяПроцедура(Тип11, Тип21) - описание ..."); + assertThat(method.getCallOptions()).isEmpty(); + assertThat(method.getParameters()).isEmpty(); + assertThat(method.getReturnedValue()).isEmpty(); + assertThat(method.getLink()).isEmpty(); + } + + @Test + void testMethod4() { + var method = methodsWithDescription.get(3); + assertThat(method.getPurposeDescription()).isEmpty(); + assertThat(method.isDeprecated()).isFalse(); + assertThat(method.getDeprecationInfo()).isEmpty(); + assertThat(method.getExamples()).isEmpty(); + assertThat(method.getCallOptions()).isEmpty(); + assertThat(method.getParameters()).isEmpty(); + assertThat(method.getReturnedValue()).hasSize(2); + assertThat(method.getLink()).isEmpty(); + var type = method.getReturnedValue().get(0); + assertThat(type.getDescription()).isEqualTo("ссылка на предопределенный элемент."); + assertThat(type.getName()).isEqualTo("ЛюбаяСсылка"); + assertThat(type.getParameters()).isEmpty(); + type = method.getReturnedValue().get(1); + assertThat(type.getDescription()).isEqualTo("если предопределенный элемент есть в метаданных, но не создан в ИБ."); + assertThat(type.getName()).isEqualTo("Неопределено"); + assertThat(type.getParameters()).isEmpty(); + } + + @Test + void testMethod3() { + var method = methodsWithDescription.get(2); + assertThat(method.getPurposeDescription()).isEmpty(); + assertThat(method.isDeprecated()).isFalse(); + assertThat(method.getDeprecationInfo()).isEmpty(); + assertThat(method.getExamples()).isEmpty(); + assertThat(method.getCallOptions()).hasSize(3); + assertThat(method.getCallOptions().get(0)) + .isEqualTo("УниверсальнаяПроцедура(Тип11, Тип21) - описание ..."); + assertThat(method.getParameters()).isEmpty(); + assertThat(method.getReturnedValue()).isEmpty(); + assertThat(method.getLink()).isEmpty(); + } + + @Test + void testMethod2() { + var method = methodsWithDescription.get(1); + assertThat(method.getPurposeDescription()).isEmpty(); + assertThat(method.isDeprecated()).isFalse(); + assertThat(method.getDeprecationInfo()).isEmpty(); + assertThat(method.getExamples()).isEmpty(); + assertThat(method.getCallOptions()).isEmpty(); + assertThat(method.getParameters()).hasSize(8); + assertThat(method.getLink()).isEmpty(); + var param = method.getParameters().get(0); + assertThat(param.getDescription()).isEmpty(); + assertThat(param.getName()).isEqualTo("ПараметрБезТипаИОписания"); + assertThat(param.getTypes()).isEmpty(); + + param = method.getParameters().get(1); + assertThat(param.getDescription()).isEmpty(); + assertThat(param.getName()).isEqualTo("ПараметрСТипом"); + assertThat(param.getTypes()).hasSize(1); + var type = param.getTypes().get(0); + assertThat(type.getDescription()).isEmpty(); + assertThat(type.getName()).isEqualTo("Произвольный"); + assertThat(type.getParameters()).isEmpty(); + + param = method.getParameters().get(2); + assertThat(param.getDescription()).isEmpty(); + assertThat(param.getName()).isEqualTo("ПараметрСОписаниемСсылкой"); + assertThat(param.getTypes()).hasSize(1); + type = param.getTypes().get(0); + assertThat(type.getDescription()).isEmpty(); + assertThat(type.getName()).isEqualTo("см. ПодключаемыеКомандыПереопределяемый.ПриОпределенииКомандПодключенныхКОбъекту.НастройкиФормы"); + assertThat(type.getParameters()).isEmpty(); + + param = method.getParameters().get(3); + assertThat(param.getDescription()).isEqualTo("описание параметра см. Справочник.Контрагенты."); + assertThat(param.getName()).isEqualTo("ПараметрСТипомИОписанием"); + assertThat(param.getTypes()).hasSize(1); + type = param.getTypes().get(0); + assertThat(type.getDescription()).isEqualTo("описание параметра см. Справочник.Контрагенты."); + assertThat(type.getName()).isEqualTo("Произвольный"); + assertThat(type.getParameters()).isEmpty(); + + param = method.getParameters().get(4); + assertThat(param.getDescription()).isEqualTo("простое описание параметра."); + assertThat(param.getName()).isEqualTo("ПараметрСТипамиИОписанием"); + assertThat(param.getTypes()).hasSize(1); + type = param.getTypes().get(0); + assertThat(type.getDescription()).isEqualTo("простое описание параметра."); + assertThat(type.getName()).isEqualTo("Произвольный, ДокументСсылка"); + assertThat(type.getParameters()).isEmpty(); + + param = method.getParameters().get(5); + assertThat(param.getDescription()).isEqualTo("многострочное\nописание параметра"); + assertThat(param.getName()).isEqualTo("ПараметрСТипамиИОписанием2"); + assertThat(param.getTypes()).hasSize(1); + type = param.getTypes().get(0); + assertThat(type.getDescription()).isEqualTo("многострочное\nописание параметра"); + assertThat(type.getName()).isEqualTo("Произвольный, ДокументСсылка"); + assertThat(type.getParameters()).isEmpty(); + + param = method.getParameters().get(6); + assertThat(param.getDescription()).isEmpty(); + assertThat(param.getName()).isEqualTo("ПараметрСТипамиИОписанием3"); + assertThat(param.getTypes()).hasSize(4); + type = param.getTypes().get(0); + assertThat(type.getDescription()).isEqualTo("описание произвольного типа"); + assertThat(type.getName()).isEqualTo("Произвольный"); + assertThat(type.getParameters()).isEmpty(); + type = param.getTypes().get(1); + assertThat(type.getDescription()).isEqualTo("какой-то документ\nименно\nссылка"); + assertThat(type.getName()).isEqualTo("ДокументСсылка"); + assertThat(type.getParameters()).isEmpty(); + type = param.getTypes().get(2); + assertThat(type.getDescription()).isEqualTo("многострочное\nописание числа"); + assertThat(type.getName()).isEqualTo("Число"); + assertThat(type.getParameters()).isEmpty(); + type = param.getTypes().get(3); + assertThat(type.getDescription()).isEmpty(); + assertThat(type.getName()).isEqualTo("Строка"); + assertThat(type.getParameters()).isEmpty(); + + param = method.getParameters().get(7); + assertThat(param.getDescription()).isEmpty(); + assertThat(param.getName()).isEqualTo("ПараметрМассив"); + assertThat(param.getTypes()).hasSize(1); + type = param.getTypes().get(0); + assertThat(type.getDescription()).isEmpty(); + assertThat(type.getName()).isEqualTo("Массив из Структура:"); + assertThat(type.getParameters()).hasSize(4); + param = type.getParameters().get(0); + assertThat(param.getDescription()).isEmpty(); + assertThat(param.getName()).isEqualTo("Элемент1"); + assertThat(param.getTypes()).hasSize(1); + var subtype = param.getTypes().get(0); + assertThat(subtype.getDescription()).isEmpty(); + assertThat(subtype.getName()).isEqualTo("Структура:"); + assertThat(subtype.getParameters()).hasSize(3); + var subparam = subtype.getParameters().get(0); + assertThat(subparam.getDescription()).isEqualTo("код региона (длина - 2)."); + assertThat(subparam.getName()).isEqualTo("СубЭлемент1"); + assertThat(subparam.getTypes()).hasSize(1); + subparam = subtype.getParameters().get(1); + assertThat(subparam.getDescription()).isEqualTo("код населенного пункта (длина - 3)."); + assertThat(subparam.getName()).isEqualTo("Субэлемент2"); + assertThat(subparam.getTypes()).hasSize(1); + subparam = subtype.getParameters().get(2); + assertThat(subparam.getDescription()).isEqualTo("код улицы (длина - 4)."); + assertThat(subparam.getName()).isEqualTo("СубЭлемент3"); + assertThat(subparam.getTypes()).hasSize(1); + param = type.getParameters().get(1); + assertThat(param.getDescription()).isEmpty(); + assertThat(param.getName()).isEqualTo("Элемент2"); + assertThat(param.getTypes()).hasSize(1); + param = type.getParameters().get(2); + assertThat(param.getDescription()).isEmpty(); + assertThat(param.getName()).isEqualTo("Элемент3"); + assertThat(param.getTypes()).hasSize(1); + param = type.getParameters().get(3); + assertThat(param.getDescription()).isEmpty(); + assertThat(param.getName()).isEqualTo("Жесть"); + assertThat(param.getTypes()).hasSize(1); + subtype = param.getTypes().get(0); + assertThat(subtype.getDescription()).isEmpty(); + assertThat(subtype.getName()).isEqualTo("Структура"); + assertThat(subtype.getParameters()).hasSize(1); + subparam = subtype.getParameters().get(0); + assertThat(subparam.getDescription()).isEmpty(); + assertThat(subparam.getName()).isEqualTo("Массив"); + assertThat(subparam.getTypes()).hasSize(1); + var subsubtype = subparam.getTypes().get(0); + assertThat(subsubtype.getDescription()).isEmpty(); + assertThat(subsubtype.getName()).isEqualTo("Массив из Структура:"); + assertThat(subsubtype.getParameters()).hasSize(2); + var subsubparam = subsubtype.getParameters().get(0); + assertThat(subsubparam.getDescription()).isEqualTo("описание"); + assertThat(subsubparam.getName()).isEqualTo("Элемент"); + assertThat(subsubparam.getTypes()).hasSize(1); + subsubparam = subsubtype.getParameters().get(1); + assertThat(subsubparam.getDescription()).isEmpty(); + assertThat(subsubparam.getName()).isEqualTo("Элемент4"); + assertThat(subsubparam.getTypes()).hasSize(1); + subsubtype = subsubparam.getTypes().get(0); + assertThat(subsubtype.getDescription()).isEmpty(); + assertThat(subsubtype.getName()).isEqualTo("строка"); + assertThat(subsubtype.getParameters()).hasSize(1); + subsubparam = subsubtype.getParameters().get(0); + assertThat(subsubparam.getDescription()).isEmpty(); + assertThat(subsubparam.getName()).isEqualTo("Элемент5"); + assertThat(subsubparam.getTypes()).hasSize(1); + assertThat(method.getReturnedValue()).isEmpty(); + } + + @Test + void testMethod1() { + var method = methodsWithDescription.get(0); + assertThat(method.getPurposeDescription()) + .isNotEmpty() + .isEqualTo("Описание метода"); + assertThat(method.isDeprecated()).isFalse(); + assertThat(method.getDeprecationInfo()).isEmpty(); + assertThat(method.getExamples()).isEmpty(); + assertThat(method.getCallOptions()).isEmpty(); + assertThat(method.getParameters()).isEmpty(); + assertThat(method.getReturnedValue()).isEmpty(); + assertThat(method.getLink()).isEmpty(); + } +} \ No newline at end of file diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeOutOfRegionDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeOutOfRegionDiagnosticTest.java index 4f68dee262d..9422905512f 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeOutOfRegionDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CodeOutOfRegionDiagnosticTest.java @@ -21,12 +21,16 @@ */ package com.github._1c_syntax.bsl.languageserver.diagnostics; +import com.github._1c_syntax.bsl.languageserver.util.TestUtils; +import com.github._1c_syntax.mdclasses.metadata.additional.ModuleType; 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; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; class CodeOutOfRegionDiagnosticTest extends AbstractDiagnosticTest { CodeOutOfRegionDiagnosticTest() { @@ -35,8 +39,7 @@ class CodeOutOfRegionDiagnosticTest extends AbstractDiagnosticTest diagnostics = getDiagnostics(); + var diagnostics = getDiagnostics("CodeOutOfRegionDiagnostic", ModuleType.ObjectModule); assertThat(diagnostics).hasSize(7); assertThat(diagnostics, true) @@ -49,21 +52,17 @@ void test() { .hasRange(57, 0, 7) .hasRange(59, 0, 69, 9) ; - } @Test void emptyTest() { - - List diagnostics = getDiagnostics("CodeOutOfRegionDiagnosticEmpty"); + var diagnostics = getDiagnostics("CodeOutOfRegionDiagnosticEmpty", ModuleType.ObjectModule); assertThat(diagnostics).isEmpty(); - } @Test void testNoRegions() { - - List diagnostics = getDiagnostics("CodeOutOfRegionDiagnosticNoRegions"); + var diagnostics = getDiagnostics("CodeOutOfRegionDiagnosticNoRegions", ModuleType.ObjectModule); assertThat(diagnostics).hasSize(1); assertThat(diagnostics, true) @@ -73,38 +72,49 @@ void testNoRegions() { .isNotNull() .isNotEmpty(); assertThat(diagnostics.get(0).getRelatedInformation().size()).isEqualTo(4); + } + + @Test + void testNoRegionsUnknown() { + var diagnostics = getDiagnostics("CodeOutOfRegionDiagnosticNoRegions", ModuleType.UNKNOWN); + assertThat(diagnostics).isEmpty(); + var configuration = diagnosticInstance.getInfo().getDefaultConfiguration(); + configuration.put("checkUnknownModuleType", true); + diagnosticInstance.configure(configuration); + + diagnostics = getDiagnostics("CodeOutOfRegionDiagnosticNoRegions", ModuleType.UNKNOWN); + assertThat(diagnostics).isNotEmpty(); } @Test void testCodeBlock() { - - List diagnostics = getDiagnostics("CodeOutOfRegionDiagnosticCodeBlock"); + var diagnostics = getDiagnostics("CodeOutOfRegionDiagnosticCodeBlock", ModuleType.ObjectModule); assertThat(diagnostics).hasSize(1); assertThat(diagnostics, true) .hasRange(0, 0, 0, 23); - } @Test void testEmptyFile() { - - List diagnostics = getDiagnostics("CodeOutOfRegionDiagnosticEmptyFile"); + var diagnostics = getDiagnostics("CodeOutOfRegionDiagnosticEmptyFile", ModuleType.ObjectModule); assertThat(diagnostics).isEmpty(); - } @Test void testExecute() { - - List diagnostics = getDiagnostics("CodeOutOfRegionDiagnosticExecute"); + var diagnostics = getDiagnostics("CodeOutOfRegionDiagnosticExecute", ModuleType.ObjectModule); assertThat(diagnostics).hasSize(1); assertThat(diagnostics, true) .hasRange(1, 10, 1, 19); - } + private List getDiagnostics(String fileName, ModuleType moduleType) { + var documentContext = spy(TestUtils.getDocumentContext(getText(fileName))); + doReturn(moduleType).when(documentContext).getModuleType(); + return getDiagnostics(documentContext); + } } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommandModuleExportMethodsDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommandModuleExportMethodsDiagnosticTest.java new file mode 100644 index 00000000000..b084ef7ea8b --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommandModuleExportMethodsDiagnosticTest.java @@ -0,0 +1,50 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.util.Assertions; +import org.eclipse.lsp4j.Diagnostic; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class CommandModuleExportMethodsDiagnosticTest extends AbstractDiagnosticTest { + + CommandModuleExportMethodsDiagnosticTest() { + super(CommandModuleExportMethodsDiagnostic.class); + } + + @Test + void test() { + + List diagnostics = getDiagnostics(); + + assertThat(diagnostics).hasSize(2); + + Assertions.assertThat(diagnostics, true) + .hasRange(0, 10, 0, 15) + .hasRange(6, 8, 6, 13); + + } +} \ No newline at end of file diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleInvalidTypeDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleInvalidTypeDiagnosticTest.java index 93cc0ba58e4..ed835bc1cb0 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleInvalidTypeDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleInvalidTypeDiagnosticTest.java @@ -74,7 +74,7 @@ void testUnknown() { //then assertThat(diagnostics).hasSize(1); assertThat(diagnostics, true) - .hasRange(5, 0, 1); + .hasRange(1, 0, 13); } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameCachedDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameCachedDiagnosticTest.java index 6f9887a71e1..167abc9bcaa 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameCachedDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameCachedDiagnosticTest.java @@ -72,7 +72,7 @@ void test() { //then assertThat(diagnostics).hasSize(1); assertThat(diagnostics, true) - .hasRange(5, 0, 1); + .hasRange(1, 0, 13); } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameClientDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameClientDiagnosticTest.java index bc67c70d742..b950e941173 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameClientDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameClientDiagnosticTest.java @@ -73,7 +73,7 @@ void test() { //then assertThat(diagnostics).hasSize(1); assertThat(diagnostics, true) - .hasRange(5, 0, 1); + .hasRange(1, 0, 13); } @@ -98,7 +98,7 @@ void testClient() { //then assertThat(diagnostics).hasSize(1); assertThat(diagnostics, true) - .hasRange(5, 0, 1); + .hasRange(1, 0, 13); } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameClientServerDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameClientServerDiagnosticTest.java index 1c1c6a7f820..eabbe097201 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameClientServerDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameClientServerDiagnosticTest.java @@ -74,7 +74,7 @@ void test() { //then assertThat(diagnostics).hasSize(1); assertThat(diagnostics, true) - .hasRange(5, 0, 1); + .hasRange(1, 0, 13); } @@ -99,7 +99,7 @@ void testClientServer() { //then assertThat(diagnostics).hasSize(1); assertThat(diagnostics, true) - .hasRange(5, 0, 1); + .hasRange(1, 0, 13); } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameFullAccessDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameFullAccessDiagnosticTest.java index 19fe8639ed8..dc33b08fe3a 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameFullAccessDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameFullAccessDiagnosticTest.java @@ -72,7 +72,7 @@ void test() { //then assertThat(diagnostics).hasSize(1); assertThat(diagnostics, true) - .hasRange(5, 0, 1); + .hasRange(1, 0, 13); } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameGlobalClientDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameGlobalClientDiagnosticTest.java index 135229d0eb7..b5e4f6c34c6 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameGlobalClientDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameGlobalClientDiagnosticTest.java @@ -75,7 +75,7 @@ void test() { //then assertThat(diagnostics).hasSize(1); assertThat(diagnostics, true) - .hasRange(5, 0, 1); + .hasRange(1, 0, 13); } @@ -100,7 +100,7 @@ void testEng() { //then assertThat(diagnostics).hasSize(1); assertThat(diagnostics, true) - .hasRange(5, 0, 1); + .hasRange(1, 0, 13); } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameGlobalDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameGlobalDiagnosticTest.java index b0a48d694c4..0759084203a 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameGlobalDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameGlobalDiagnosticTest.java @@ -71,7 +71,7 @@ void test() { //then assertThat(diagnostics).hasSize(1); assertThat(diagnostics, true) - .hasRange(5, 0, 1); + .hasRange(1, 0, 13); } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameServerCallDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameServerCallDiagnosticTest.java index 8e97df93c85..2a898e1fd3e 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameServerCallDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameServerCallDiagnosticTest.java @@ -73,7 +73,7 @@ void test() { //then assertThat(diagnostics).hasSize(1); assertThat(diagnostics, true) - .hasRange(5, 0, 1); + .hasRange(1, 0, 13); } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameWordsDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameWordsDiagnosticTest.java index de95fa9f225..665c35da71c 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameWordsDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/CommonModuleNameWordsDiagnosticTest.java @@ -70,7 +70,7 @@ void test() { //then assertThat(diagnostics).hasSize(1); assertThat(diagnostics, true) - .hasRange(5, 0, 1); + .hasRange(1, 0, 13); } @@ -111,7 +111,7 @@ void testConfigure() { //then assertThat(diagnostics).hasSize(1); assertThat(diagnostics, true) - .hasRange(5, 0, 1); + .hasRange(1, 0, 13); } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DiagnosticsTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DiagnosticsTest.java index 875ed279ac7..9dc5d4b5edc 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DiagnosticsTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DiagnosticsTest.java @@ -44,9 +44,9 @@ import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; @SpringBootTest class DiagnosticsTest { @@ -72,21 +72,21 @@ void testCompatibilityMode() { var serverContext = spy(context); var bslConfiguration = spy(serverContext.getConfiguration()); - when(documentContext.getServerContext()).thenReturn(serverContext); - when(serverContext.getConfiguration()).thenReturn(bslConfiguration); + doReturn(serverContext).when(documentContext).getServerContext(); + doReturn(bslConfiguration).when(serverContext).getConfiguration(); configuration.getDiagnosticsOptions().setMode(Mode.ON); // when-then pairs - when(bslConfiguration.getCompatibilityMode()).thenReturn(new CompatibilityMode(3, 10)); + doReturn(new CompatibilityMode(3, 10)).when(bslConfiguration).getCompatibilityMode(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .anyMatch(diagnostic -> diagnostic instanceof DeprecatedFindDiagnostic); - when(bslConfiguration.getCompatibilityMode()).thenReturn(new CompatibilityMode(3, 6)); + doReturn(new CompatibilityMode(3, 6)).when(bslConfiguration).getCompatibilityMode(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .anyMatch(diagnostic -> diagnostic instanceof DeprecatedFindDiagnostic); - when(bslConfiguration.getCompatibilityMode()).thenReturn(new CompatibilityMode(2, 16)); + doReturn(new CompatibilityMode(2, 16)).when(bslConfiguration).getCompatibilityMode(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .noneMatch(diagnostic -> diagnostic instanceof DeprecatedFindDiagnostic); } @@ -97,19 +97,19 @@ void testModuleType() { documentContext = spy(TestUtils.getDocumentContext("")); // when-then pairs - when(documentContext.getModuleType()).thenReturn(ModuleType.CommandModule); + doReturn(ModuleType.CommandModule).when(documentContext).getModuleType(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .anyMatch(diagnostic -> diagnostic instanceof CompilationDirectiveLostDiagnostic); - when(documentContext.getModuleType()).thenReturn(ModuleType.FormModule); + doReturn(ModuleType.FormModule).when(documentContext).getModuleType(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .anyMatch(diagnostic -> diagnostic instanceof CompilationDirectiveLostDiagnostic); - when(documentContext.getModuleType()).thenReturn(ModuleType.CommonModule); + doReturn(ModuleType.CommonModule).when(documentContext).getModuleType(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .noneMatch(diagnostic -> diagnostic instanceof CompilationDirectiveLostDiagnostic); - when(documentContext.getModuleType()).thenReturn(ModuleType.UNKNOWN); + doReturn(ModuleType.UNKNOWN).when(documentContext).getModuleType(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .noneMatch(diagnostic -> diagnostic instanceof CompilationDirectiveLostDiagnostic); } @@ -120,18 +120,18 @@ void testAllScope() { documentContext = spy(TestUtils.getDocumentContext("")); // when-then pairs - when(documentContext.getModuleType()).thenReturn(ModuleType.CommonModule); - when(documentContext.getFileType()).thenReturn(FileType.BSL); + doReturn(ModuleType.CommonModule).when(documentContext).getModuleType(); + doReturn(FileType.BSL).when(documentContext).getFileType(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .anyMatch(diagnostic -> diagnostic instanceof UnusedLocalMethodDiagnostic); - when(documentContext.getModuleType()).thenReturn(ModuleType.UNKNOWN); - when(documentContext.getFileType()).thenReturn(FileType.BSL); + doReturn(ModuleType.UNKNOWN).when(documentContext).getModuleType(); + doReturn(FileType.BSL).when(documentContext).getFileType(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .noneMatch(diagnostic -> diagnostic instanceof UnusedLocalMethodDiagnostic); - when(documentContext.getModuleType()).thenReturn(ModuleType.UNKNOWN); - when(documentContext.getFileType()).thenReturn(FileType.OS); + doReturn(ModuleType.UNKNOWN).when(documentContext).getModuleType(); + doReturn(FileType.OS).when(documentContext).getFileType(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .anyMatch(diagnostic -> diagnostic instanceof UnusedLocalMethodDiagnostic); } @@ -145,67 +145,67 @@ void testSkipSupport() { // when-then pairs ComputeDiagnosticsSkipSupport.NEVER configuration.getDiagnosticsOptions().setSkipSupport(SkipSupport.NEVER); - when(documentContext.getSupportVariants()).thenReturn(Collections.emptyMap()); + doReturn(Collections.emptyMap()).when(documentContext).getSupportVariants(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .isNotEmpty(); - when(documentContext.getSupportVariants()).thenReturn(Map.of(supportConfiguration, SupportVariant.NONE)); + doReturn(Map.of(supportConfiguration, SupportVariant.NONE)).when(documentContext).getSupportVariants(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .isNotEmpty(); - when(documentContext.getSupportVariants()).thenReturn(Map.of(supportConfiguration, SupportVariant.NOT_SUPPORTED)); + doReturn(Map.of(supportConfiguration, SupportVariant.NOT_SUPPORTED)).when(documentContext).getSupportVariants(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .isNotEmpty(); - when(documentContext.getSupportVariants()).thenReturn(Map.of(supportConfiguration, SupportVariant.EDITABLE_SUPPORT_ENABLED)); + doReturn(Map.of(supportConfiguration, SupportVariant.EDITABLE_SUPPORT_ENABLED)).when(documentContext).getSupportVariants(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .isNotEmpty(); - when(documentContext.getSupportVariants()).thenReturn(Map.of(supportConfiguration, SupportVariant.NOT_EDITABLE)); + doReturn(Map.of(supportConfiguration, SupportVariant.NOT_EDITABLE)).when(documentContext).getSupportVariants(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .isNotEmpty(); // when-then pairs ComputeDiagnosticsSkipSupport.WITHSUPPORTLOCKED configuration.getDiagnosticsOptions().setSkipSupport(SkipSupport.WITH_SUPPORT_LOCKED); - when(documentContext.getSupportVariants()).thenReturn(Collections.emptyMap()); + doReturn(Collections.emptyMap()).when(documentContext).getSupportVariants(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .isNotEmpty(); - when(documentContext.getSupportVariants()).thenReturn(Map.of(supportConfiguration, SupportVariant.NONE)); + doReturn(Map.of(supportConfiguration, SupportVariant.NONE)).when(documentContext).getSupportVariants(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .isNotEmpty(); - when(documentContext.getSupportVariants()).thenReturn(Map.of(supportConfiguration, SupportVariant.NOT_SUPPORTED)); + doReturn(Map.of(supportConfiguration, SupportVariant.NOT_SUPPORTED)).when(documentContext).getSupportVariants(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .isNotEmpty(); - when(documentContext.getSupportVariants()).thenReturn(Map.of(supportConfiguration, SupportVariant.EDITABLE_SUPPORT_ENABLED)); + doReturn(Map.of(supportConfiguration, SupportVariant.EDITABLE_SUPPORT_ENABLED)).when(documentContext).getSupportVariants(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .isNotEmpty(); - when(documentContext.getSupportVariants()).thenReturn(Map.of(supportConfiguration, SupportVariant.NOT_EDITABLE)); + doReturn(Map.of(supportConfiguration, SupportVariant.NOT_EDITABLE)).when(documentContext).getSupportVariants(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .isEmpty(); // when-then pairs ComputeDiagnosticsSkipSupport.WITHSUPPORT configuration.getDiagnosticsOptions().setSkipSupport(SkipSupport.WITH_SUPPORT); - when(documentContext.getSupportVariants()).thenReturn(Collections.emptyMap()); + doReturn(Collections.emptyMap()).when(documentContext).getSupportVariants(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .isNotEmpty(); - when(documentContext.getSupportVariants()).thenReturn(Map.of(supportConfiguration, SupportVariant.NONE)); + doReturn(Map.of(supportConfiguration, SupportVariant.NONE)).when(documentContext).getSupportVariants(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .isNotEmpty(); - when(documentContext.getSupportVariants()).thenReturn(Map.of(supportConfiguration, SupportVariant.NOT_SUPPORTED)); + doReturn(Map.of(supportConfiguration, SupportVariant.NOT_SUPPORTED)).when(documentContext).getSupportVariants(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .isEmpty(); - when(documentContext.getSupportVariants()).thenReturn(Map.of(supportConfiguration, SupportVariant.EDITABLE_SUPPORT_ENABLED)); + doReturn(Map.of(supportConfiguration, SupportVariant.EDITABLE_SUPPORT_ENABLED)).when(documentContext).getSupportVariants(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .isEmpty(); - when(documentContext.getSupportVariants()).thenReturn(Map.of(supportConfiguration, SupportVariant.NOT_EDITABLE)); + doReturn(Map.of(supportConfiguration, SupportVariant.NOT_EDITABLE)).when(documentContext).getSupportVariants(); assertThat(diagnosticsConfiguration.diagnostics(documentContext)) .isEmpty(); } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/FunctionOutParameterDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/FunctionOutParameterDiagnosticTest.java new file mode 100644 index 00000000000..d3e8a67a491 --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/FunctionOutParameterDiagnosticTest.java @@ -0,0 +1,46 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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 FunctionOutParameterDiagnosticTest extends AbstractDiagnosticTest { + FunctionOutParameterDiagnosticTest() { + super(FunctionOutParameterDiagnostic.class); + } + + @Test + void testSimple() { + + List diagnostics = getDiagnostics(); + + assertThat(diagnostics).hasSize(1); + assertThat(diagnostics, true) + .hasRange(5, 4, 5); + + } +} diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/GlobalContextMethodCollision8312DiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/GlobalContextMethodCollision8312DiagnosticTest.java new file mode 100644 index 00000000000..6de2cb60852 --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/GlobalContextMethodCollision8312DiagnosticTest.java @@ -0,0 +1,65 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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 GlobalContextMethodCollision8312DiagnosticTest extends AbstractDiagnosticTest { + GlobalContextMethodCollision8312DiagnosticTest() { + super(GlobalContextMethodCollision8312Diagnostic.class); + } + + @Test + void test8312() { + + List diagnostics = getDiagnostics(); + + assertThat(diagnostics).hasSize(20); + assertThat(diagnostics, true) + .hasRange(0, 8, 20) + .hasRange(3, 8, 31) + .hasRange(6, 8, 21) + .hasRange(9, 8, 18) + .hasRange(12, 8, 20) + .hasRange(15, 8, 19) + .hasRange(18, 8, 20) + .hasRange(21, 8, 34) + .hasRange(24, 8, 27) + .hasRange(27, 8, 28) + .hasRange(30, 8, 16) + .hasRange(33, 8, 22) + .hasRange(36, 8, 14) + .hasRange(39, 8, 18) + .hasRange(42, 8, 17) + .hasRange(45, 8, 18) + .hasRange(48, 8, 21) + .hasRange(51, 8, 18) + .hasRange(54, 8, 24) + .hasRange(57, 8, 25) + ; + } +} diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/LatinAndCyrillicSymbolInWordDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/LatinAndCyrillicSymbolInWordDiagnosticTest.java new file mode 100644 index 00000000000..599b81f2142 --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/LatinAndCyrillicSymbolInWordDiagnosticTest.java @@ -0,0 +1,94 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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 java.util.Map; + +import static com.github._1c_syntax.bsl.languageserver.util.Assertions.assertThat; + +class LatinAndCyrillicSymbolInWordDiagnosticTest extends AbstractDiagnosticTest { + LatinAndCyrillicSymbolInWordDiagnosticTest() { + super(LatinAndCyrillicSymbolInWordDiagnostic.class); + } + + @Test + void test() { + + List diagnostics = getDiagnostics(); + + assertThat(diagnostics).hasSize(14); + assertThat(diagnostics, true) + // методы + .hasRange(2, 10, 23) + .hasRange(9, 8, 21) + .hasRange(30, 17, 26) + .hasRange(30, 33, 39) + // переменные + .hasRange(0, 6, 10) + .hasRange(5, 20, 23) + .hasRange(12, 10, 12) + .hasRange(13, 10, 15) + .hasRange(15, 4, 14) + .hasRange(16, 4, 23) + // аннотации + .hasRange(19, 1, 10) + .hasRange(23, 11, 19) + // остальное + .hasRange(27, 9, 15) + .hasRange(31, 13, 19) + ; + } + + @Test + void testConfigure() { + + Map configuration = diagnosticInstance.info.getDefaultConfiguration(); + configuration.put("excludeWords", "Namе, ВИмениEnglish, ComОбъект2"); + diagnosticInstance.configure(configuration); + + List diagnostics = getDiagnostics(); + + assertThat(diagnostics).hasSize(11); + assertThat(diagnostics, true) + // методы + .hasRange(9, 8, 21) + .hasRange(30, 17, 26) + .hasRange(30, 33, 39) + // переменные + .hasRange(5, 20, 23) + .hasRange(12, 10, 12) + .hasRange(13, 10, 15) + .hasRange(16, 4, 23) + // аннотации + .hasRange(19, 1, 10) + .hasRange(23, 11, 19) + // остальное + .hasRange(27, 9, 15) + .hasRange(31, 13, 19) + ; + + } +} diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnosticTest.java new file mode 100644 index 00000000000..03e8bee451e --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MagicDateDiagnosticTest.java @@ -0,0 +1,68 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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 java.util.Map; + +import static com.github._1c_syntax.bsl.languageserver.util.Assertions.assertThat; + +class MagicDateDiagnosticTest extends AbstractDiagnosticTest { + MagicDateDiagnosticTest() { + super(MagicDateDiagnostic.class); + } + + @Test + void test() { + + List diagnostics = getDiagnostics(); + + assertThat(diagnostics).hasSize(5); + assertThat(diagnostics, true) + .hasRange(1, 12, 1, 22) + .hasRange(2, 12, 2, 28) + .hasRange(3, 7, 3, 17) + .hasRange(4, 14, 4, 24) + .hasRange(13, 7, 13, 26); + + } + + @Test + void testConfigure() { + + Map configuration = diagnosticInstance.getInfo().getDefaultConfiguration(); + configuration.put("authorizedDates", "12340101, 00020101 ,,"); + diagnosticInstance.configure(configuration); + + List diagnostics = getDiagnostics(); + + assertThat(diagnostics).hasSize(3); + assertThat(diagnostics, true) + .hasRange(2, 12, 2, 28) + .hasRange(3, 7, 3, 17) + .hasRange(13, 7, 13, 26); + + } +} diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MetadataObjectNameLengthDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MetadataObjectNameLengthDiagnosticTest.java index c67ac5fb9fd..c0e71538b30 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MetadataObjectNameLengthDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MetadataObjectNameLengthDiagnosticTest.java @@ -62,7 +62,7 @@ void testConfigure() { configuration.put("maxMetadataObjectNameLength", 10); diagnosticInstance.configure(configuration); - getDocumentContextFromFile("CommonModules/ПервыйОбщийМодуль/Ext/Module.bsl", " "); + getDocumentContextFromFile("CommonModules/ПервыйОбщийМодуль/Ext/Module.bsl", "A"); // when List diagnostics = diagnosticInstance.getDiagnostics(documentContext); @@ -115,7 +115,7 @@ void testNotEmptyModule(String content, int count) { }) void test(String modulePath) { - getDocumentContextFromFile(modulePath, " "); + getDocumentContextFromFile(modulePath, "A"); // given when(module.getName()).thenReturn(LONG_NAME); @@ -132,7 +132,7 @@ void test(String modulePath) { @Test void testNegative() { - getDocumentContextFromFile("CommonModules/ПервыйОбщийМодуль/Ext/Module.bsl", " "); + getDocumentContextFromFile("CommonModules/ПервыйОбщийМодуль/Ext/Module.bsl", "A"); // given when(module.getName()).thenReturn("Short"); @@ -156,9 +156,14 @@ void getDocumentContextFromFile(String modulePath, String content) { static Stream contentProvider() { return Stream.of( Arguments.of("", 0), - Arguments.of("\n", 1), + Arguments.of("\n", 0), Arguments.of("//", 1), - Arguments.of(" ", 1) + Arguments.of(" ", 0), + Arguments.of("FF", 1), + Arguments.of("\nA", 1), + Arguments.of("#\n", 1), + Arguments.of("\n#", 1), + Arguments.of("&", 1) ); } } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingEventSubscriptionHandlerDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingEventSubscriptionHandlerDiagnosticTest.java new file mode 100644 index 00000000000..0fd2e011cf0 --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingEventSubscriptionHandlerDiagnosticTest.java @@ -0,0 +1,70 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.utils.Ranges; +import com.github._1c_syntax.mdclasses.metadata.additional.ModuleType; +import com.github._1c_syntax.utils.Absolute; +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; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +class MissingEventSubscriptionHandlerDiagnosticTest extends AbstractDiagnosticTest { + MissingEventSubscriptionHandlerDiagnosticTest() { + super(MissingEventSubscriptionHandlerDiagnostic.class); + } + + private static final String PATH_TO_METADATA = "src/test/resources/metadata"; + + @Test + void test() { + + initServerContext(Absolute.path(PATH_TO_METADATA)); + var documentContext = spy(getDocumentContext()); + when(documentContext.getModuleType()).thenReturn(ModuleType.SessionModule); + List diagnostics = getDiagnostics(documentContext); + + assertThat(diagnostics) + .hasSize(6) + .allMatch( + diagnostic -> diagnostic.getRange().equals(Ranges.create(0, 0, 7))) + .anyMatch(diagnostic -> diagnostic.getMessage() + .equals("Создайте модуль \"ОбщийПодпискиНаСобытия\" или исправьте некорректный обработчик подписки на событие \"ПриЗаписиСправочника\"")) + .anyMatch(diagnostic -> diagnostic.getMessage() + .equals("Исправьте некорректный обработчик \"CommonModule.ОбщийПодпискиНаСобытия\" у подписки на событие \"ПриЗаписиДокумента\"")) + .anyMatch(diagnostic -> diagnostic.getMessage() + .equals("Добавьте \"Сервер\" модулю \"КлиентскийОбщийМодуль\" или исправьте некорректный обработчик подписки на событие \"ПередЗаписьюДокумента\"")) + .anyMatch(diagnostic -> diagnostic.getMessage() + .equals("Заполните обработчик подписки на событие \"ПередЗаписьюКонстанты\"")) + .anyMatch(diagnostic -> diagnostic.getMessage() + .equals("Создайте процедуру \"ПервыйОбщийМодуль.ПодпискаНаСобытиеПриУстановкеНовогоКода\" или исправьте некорректный обработчик подписки на событие \"ПриУстановкеНовогоКода\"")) + .anyMatch(diagnostic -> diagnostic.getMessage() + .equals("Добавьте \"Экспорт\" процедуре \"ПервыйОбщийМодуль.РегистрацияИзмененийПередУдалением\" или исправьте некорректный обработчик подписки на событие \"РегистрацияИзмененийПередУдалением\"")) + + ; + } +} diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingParameterDescriptionDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingParameterDescriptionDiagnosticTest.java new file mode 100644 index 00000000000..1cbfc183b61 --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingParameterDescriptionDiagnosticTest.java @@ -0,0 +1,69 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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 MissingParameterDescriptionDiagnosticTest extends AbstractDiagnosticTest { + MissingParameterDescriptionDiagnosticTest() { + super(MissingParameterDescriptionDiagnostic.class); + } + + @Test + void test() { + + List diagnostics = getDiagnostics(); + + assertThat(diagnostics).hasSize(12); + assertThat(diagnostics, true) + .hasMessageOnRange("Необходимо добавить описание всех параметров метода", + 7, 8, 15) + .hasMessageOnRange("Необходимо удалить описания параметров \"Параметр1, Параметр2\", отсутствующих в сигнатуре метода", + 14, 8, 15) + .hasMessageOnRange("Необходимо удалить описания параметров \"Параметр2\", отсутствующих в сигнатуре метода", + 21, 8, 15) + .hasMessageOnRange("Необходимо удалить описания параметров \"Параметр1\", отсутствующих в сигнатуре метода", + 28, 8, 15) + .hasMessageOnRange("Необходимо добавить описание параметра \"Параметр3\"", + 28, 27, 36) + .hasMessageOnRange("Необходимо исправить порядок описаний параметров", + 35, 8, 15) + .hasMessageOnRange("Необходимо добавить описание типа параметра \"Параметр2\"", + 42, 27, 36) + .hasMessageOnRange("Необходимо удалить описания параметров \"Параметр2\", отсутствующих в сигнатуре метода", + 50, 8, 15) + .hasMessageOnRange("Необходимо добавить описание параметра \"Параметр1\"", + 58, 16, 25) + .hasMessageOnRange("Необходимо добавить описание параметра \"Параметр2\"", + 58, 27, 36) + .hasMessageOnRange("Необходимо удалить описания параметров \"Параметр3, Параметр4\", отсутствующих в сигнатуре метода", + 58, 8, 15) + .hasMessageOnRange("Необходимо удалить описания параметров \"Параметр2, Параметр3, Параметр5\", отсутствующих в сигнатуре метода", + 68, 8, 15) + ; + } +} diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingReturnedValueDescriptionDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingReturnedValueDescriptionDiagnosticTest.java new file mode 100644 index 00000000000..ad897ed27c6 --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingReturnedValueDescriptionDiagnosticTest.java @@ -0,0 +1,55 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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 MissingReturnedValueDescriptionDiagnosticTest extends AbstractDiagnosticTest { + MissingReturnedValueDescriptionDiagnosticTest() { + super(MissingReturnedValueDescriptionDiagnostic.class); + } + + @Test + void test() { + + List diagnostics = getDiagnostics(); + + assertThat(diagnostics).hasSize(5); + assertThat(diagnostics, true) + .hasMessageOnRange("Добавьте описание возвращаемого значения функции", + 4, 8, 15) + .hasMessageOnRange("Добавьте описание возвращаемого значения функции", + 9, 8, 15) + .hasMessageOnRange("Удалите описание возвращаемого значения для процедуры", + 21, 10, 17) + .hasMessageOnRange("Необходимо добавить описание типов \"Строка\" возвращаемого значения", + 31, 8, 15) + .hasMessageOnRange("Необходимо добавить описание типов \"Строка, булево\" возвращаемого значения", + 39, 8, 15) + ; + } +} diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingSpaceDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingSpaceDiagnosticTest.java index 389945a84ac..9f8e8f72fdf 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingSpaceDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/MissingSpaceDiagnosticTest.java @@ -91,7 +91,24 @@ void test() { .hasRange(43, 19, 20) .hasRange(43, 14, 15) - .hasSize(29) + // кейворды + .hasRange(48, 17, 24) + .hasRange(50, 0, 3) + .hasRange(50, 11, 13) + .hasRange(50, 16, 20) + .hasRange(53, 4, 11) + .hasRange(53, 17, 19) + .hasRange(53, 30, 34) + .hasRange(56, 0, 4) + .hasRange(56, 12, 15) + .hasRange(56, 21, 22) + .hasRange(56, 30, 35) + .hasRange(57, 0, 9) + .hasRange(57, 17, 20) + .hasRange(57, 21, 23) + .hasRange(57, 30, 35) + + .hasSize(44) ; } @@ -150,8 +167,10 @@ void testConfigure() { .hasRange(43, 25, 43, 26) .hasRange(43, 32, 43, 33) .hasRange(45, 8, 45, 9) - .hasRange(45, 22, 45, 23); - assertThat(diagnostics).hasSize(18); + .hasRange(45, 22, 45, 23) + .hasRange(48, 15, 16) + + .hasSize(55); configuration = diagnosticInstance.getInfo().getDefaultConfiguration(); configuration.put("listForCheckLeft", ""); @@ -165,8 +184,24 @@ void testConfigure() { assertThat(diagnostics, true) .hasRange(8, 12, 8, 13) .hasRange(27, 10, 27, 11) - .hasRange(41, 46, 41, 47); - assertThat(diagnostics).hasSize(3); + .hasRange(41, 46, 41, 47) + // кейворды + .hasRange(48, 17, 24) + .hasRange(50, 0, 3) + .hasRange(50, 11, 13) + .hasRange(50, 16, 20) + .hasRange(53, 4, 11) + .hasRange(53, 17, 19) + .hasRange(53, 30, 34) + .hasRange(56, 0, 4) + .hasRange(56, 12, 15) + .hasRange(56, 21, 22) + .hasRange(56, 30, 35) + .hasRange(57, 0, 9) + .hasRange(57, 17, 20) + .hasRange(57, 21, 23) + .hasRange(57, 30, 35) + .hasSize(18); configuration = diagnosticInstance.getInfo().getDefaultConfiguration(); @@ -181,7 +216,23 @@ void testConfigure() { .hasRange(4, 9, 4, 10) .hasRange(17, 18, 17, 19) .hasRange(31, 9, 31, 10) - .hasRange(31, 28, 31, 29); - assertThat(diagnostics).hasSize(4); + .hasRange(31, 28, 31, 29) + // кейворды + .hasRange(48, 17, 24) + .hasRange(50, 0, 3) + .hasRange(50, 11, 13) + .hasRange(50, 16, 20) + .hasRange(53, 4, 11) + .hasRange(53, 17, 19) + .hasRange(53, 30, 34) + .hasRange(56, 0, 4) + .hasRange(56, 12, 15) + .hasRange(56, 21, 22) + .hasRange(56, 30, 35) + .hasRange(57, 0, 9) + .hasRange(57, 17, 20) + .hasRange(57, 21, 23) + .hasRange(57, 30, 35) + .hasSize(19); } } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/NonStandardRegionDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/NonStandardRegionDiagnosticTest.java index be7d583c591..cea0560c08f 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/NonStandardRegionDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/NonStandardRegionDiagnosticTest.java @@ -56,9 +56,9 @@ class NonStandardRegionDiagnosticTest extends AbstractDiagnosticTest diagnostics = getDiagnostics(getFixtureDocumentContextByModuleType(ModuleType.WEBServiceModule)); + + assertThat(diagnostics).hasSize(1); + assertThat(diagnostics, true) + .hasRange(16, 1, 22) + ; + } + private DocumentContext getFixtureDocumentContextByModuleType(ModuleType moduleType) throws IOException { Path tempFile = Paths.get(CONFIGURATION_PATH.toString(), pathByModuleType.getOrDefault(moduleType, "Module.bsl") diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/OrdinaryAppSupportDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/OrdinaryAppSupportDiagnosticTest.java new file mode 100644 index 00000000000..8230737cf1d --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/OrdinaryAppSupportDiagnosticTest.java @@ -0,0 +1,74 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.utils.Ranges; +import com.github._1c_syntax.mdclasses.metadata.additional.ModuleType; +import com.github._1c_syntax.utils.Absolute; +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; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +class OrdinaryAppSupportDiagnosticTest extends AbstractDiagnosticTest { + OrdinaryAppSupportDiagnosticTest() { + super(OrdinaryAppSupportDiagnostic.class); + } + + private static final String PATH_TO_METADATA = "src/test/resources/metadata"; + + @Test + void testSimple() { + + initServerContext(Absolute.path(PATH_TO_METADATA)); + var documentContext = spy(getDocumentContext()); + when(documentContext.getModuleType()).thenReturn(ModuleType.SessionModule); + List diagnostics = getDiagnostics(documentContext); + + assertThat(diagnostics) + .hasSize(2) + .allMatch( + diagnostic -> diagnostic.getRange().equals(Ranges.create(1, 0, 9))) + .anyMatch(diagnostic -> diagnostic.getMessage() + .equals("Установите свойство \"Использовать обычные формы в управляемом режиме\" установить в Ложь")) + .anyMatch(diagnostic -> diagnostic.getMessage() + .equals("Установите свойство \"Использовать управляемые формы в обычном приложении\" в Истина")) + ; + } + + @Test + void testDisable() { + + initServerContext(Absolute.path(PATH_TO_METADATA)); + var documentContext = spy(getDocumentContext()); + configuration.getDiagnosticsOptions().setOrdinaryAppSupport(false); + when(documentContext.getModuleType()).thenReturn(ModuleType.SessionModule); + List diagnostics = getDiagnostics(documentContext); + + assertThat(diagnostics) + .isEmpty(); + } +} diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/RedundantAccessToObjectDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/RedundantAccessToObjectDiagnosticTest.java new file mode 100644 index 00000000000..d1675a90872 --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/RedundantAccessToObjectDiagnosticTest.java @@ -0,0 +1,186 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.context.DocumentContext; +import com.github._1c_syntax.bsl.languageserver.util.TestUtils; +import com.github._1c_syntax.utils.Absolute; +import lombok.SneakyThrows; +import org.apache.commons.io.FileUtils; +import org.eclipse.lsp4j.Diagnostic; +import org.junit.jupiter.api.Test; + +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.Map; + +import static com.github._1c_syntax.bsl.languageserver.util.Assertions.assertThat; +import static org.mockito.Mockito.spy; + +class RedundantAccessToObjectDiagnosticTest extends AbstractDiagnosticTest { + RedundantAccessToObjectDiagnosticTest() { + super(RedundantAccessToObjectDiagnostic.class); + } + + @Test + void test() { + + List diagnostics = getDiagnostics(); + + assertThat(diagnostics).hasSize(10); + assertThat(diagnostics, true) + .hasRange(2, 4, 2, 14) + .hasRange(3, 4, 3, 14) + .hasRange(6, 18, 6, 28) + .hasRange(7, 18, 7, 28) + .hasRange(8, 18, 8, 28) + .hasRange(10, 4, 10, 14) + .hasRange(16, 4, 16, 14) + .hasRange(17, 4, 17, 14) + .hasRange(20, 15, 20, 25) + .hasRange(22, 4, 22, 14); + + } + + @Test + void testCommonModule() { + var documentContext = createDocumentContextFromFile( + "src/test/resources/metadata/CommonModules/ПервыйОбщийМодуль/Ext/Module.bsl" + ); + List diagnostics = diagnosticInstance.getDiagnostics(documentContext); + assertThat(diagnostics).hasSize(1); + assertThat(diagnostics, true) + .hasRange(75, 4, 75, 21); + } + + @SneakyThrows + DocumentContext createDocumentContextFromFile(String pathToFile) { + Path path = Absolute.path("src/test/resources/metadata"); + Path testFile = Paths.get(pathToFile).toAbsolutePath(); + + initServerContext(path); + return spy(TestUtils.getDocumentContext( + testFile.toUri(), + FileUtils.readFileToString(testFile.toFile(), StandardCharsets.UTF_8), + context + )); + } + + @Test + void testCatalogsManagerModule() { + var documentContext = createDocumentContextFromFile( + "src/test/resources/metadata/Catalogs/Справочник1/Ext/ManagerModule.bsl" + ); + List diagnostics = diagnosticInstance.getDiagnostics(documentContext); + assertThat(diagnostics).hasSize(1); + assertThat(diagnostics, true) + .hasRange(19, 4, 19, 15); + } + + @Test + void testCatalogsObjectModule() { + var documentContext = createDocumentContextFromFile( + "src/test/resources/metadata/Catalogs/Справочник1/Ext/ObjectModule.bsl" + ); + List diagnostics = diagnosticInstance.getDiagnostics(documentContext); + assertThat(diagnostics).hasSize(1); + assertThat(diagnostics, true) + .hasRange(56, 0, 10); + } + + @Test + void testCatalogsObjectModuleWithConfig() { + var documentContext = createDocumentContextFromFile( + "src/test/resources/metadata/Catalogs/Справочник1/Ext/ObjectModule.bsl" + ); + + Map configuration = diagnosticInstance.getInfo().getDefaultConfiguration(); + configuration.put("checkObjectModule", false); + diagnosticInstance.configure(configuration); + + List diagnostics = diagnosticInstance.getDiagnostics(documentContext); + assertThat(diagnostics).hasSize(0); + } + + @Test + void testCatalogsFormModule() { + var documentContext = createDocumentContextFromFile( + "src/test/resources/metadata/Catalogs/Справочник1/Forms/ФормаЭлемента/Ext/Form/Module.bsl" + ); + List diagnostics = diagnosticInstance.getDiagnostics(documentContext); + assertThat(diagnostics).hasSize(1); + assertThat(diagnostics, true) + .hasRange(64, 0, 10); + } + + @Test + void testCatalogsFormModuleWithConfig() { + var documentContext = createDocumentContextFromFile( + "src/test/resources/metadata/Catalogs/Справочник1/Forms/ФормаЭлемента/Ext/Form/Module.bsl" + ); + + Map configuration = diagnosticInstance.getInfo().getDefaultConfiguration(); + configuration.put("checkFormModule", false); + diagnosticInstance.configure(configuration); + + List diagnostics = diagnosticInstance.getDiagnostics(documentContext); + assertThat(diagnostics).hasSize(0); + } + + @Test + void testInformationRegistersManagerModule() { + var documentContext = createDocumentContextFromFile( + "src/test/resources/metadata/InformationRegisters/РегистрСведений1/Ext/ManagerModule.bsl" + ); + List diagnostics = diagnosticInstance.getDiagnostics(documentContext); + assertThat(diagnostics).hasSize(1); + assertThat(diagnostics, true) + .hasRange(18, 4, 18, 20); + } + + @Test + void testInformationRegistersRecordSetModule() { + var documentContext = createDocumentContextFromFile( + "src/test/resources/metadata/InformationRegisters/РегистрСведений1/Ext/RecordSetModule.bsl" + ); + List diagnostics = diagnosticInstance.getDiagnostics(documentContext); + assertThat(diagnostics).hasSize(1); + assertThat(diagnostics, true) + .hasRange(56, 0, 10); + } + + @Test + void testInformationRegistersRecordSetModuleWithConfig() { + var documentContext = createDocumentContextFromFile( + "src/test/resources/metadata/InformationRegisters/РегистрСведений1/Ext/RecordSetModule.bsl" + ); + + Map configuration = diagnosticInstance.getInfo().getDefaultConfiguration(); + configuration.put("checkRecordSetModule", false); + diagnosticInstance.configure(configuration); + + List diagnostics = diagnosticInstance.getDiagnostics(documentContext); + assertThat(diagnostics).hasSize(0); + } +} diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/RefOveruseDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/RefOveruseDiagnosticTest.java new file mode 100644 index 00000000000..2f3d5b08af0 --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/RefOveruseDiagnosticTest.java @@ -0,0 +1,53 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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 RefOveruseDiagnosticTest extends AbstractDiagnosticTest { + RefOveruseDiagnosticTest() { + super(RefOveruseDiagnostic.class); + } + + @Test + void test() { + + List diagnostics = getDiagnostics(); + + assertThat(diagnostics).hasSize(8); + assertThat(diagnostics, true) + .hasRange(3, 28, 3, 45) + .hasRange(13, 8, 13, 34) + .hasRange(14, 8, 14, 38) + .hasRange(25, 8, 25, 21) + .hasRange(37, 8, 37, 29) + .hasRange(38, 8, 38, 35) + .hasRange(56, 37, 56, 43) + .hasRange(57, 42, 57, 48); + + } +} diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/SmokyTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/SmokyTest.java index 64ca334c80b..3670e58a5f2 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/SmokyTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/SmokyTest.java @@ -27,6 +27,7 @@ import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticInfo; import com.github._1c_syntax.bsl.languageserver.util.TestUtils; import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; import org.eclipse.lsp4j.Diagnostic; import org.eclipse.lsp4j.jsonrpc.messages.Either; @@ -48,6 +49,7 @@ @SpringBootTest @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +@Slf4j class SmokyTest { @Autowired @@ -77,6 +79,7 @@ void testIdenticalRanges() { List diagnostics = new ArrayList<>(); FileUtils.listFiles(Paths.get(srcDir).toAbsolutePath().toFile(), new String[]{"bsl", "os"}, true) .forEach(filePath -> { + LOGGER.info(filePath.toString()); var documentContext = TestUtils.getDocumentContextFromFile(filePath.toString()); documentContext.getDiagnostics().stream() .filter(diagnostic -> diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnosticTest.java index ae5b0950691..a1f73b4614d 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnosticTest.java @@ -22,23 +22,34 @@ package com.github._1c_syntax.bsl.languageserver.diagnostics; import org.eclipse.lsp4j.Diagnostic; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; import java.util.List; import java.util.Map; import static com.github._1c_syntax.bsl.languageserver.util.Assertions.assertThat; +@SpringBootTest +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) class TypoDiagnosticTest extends AbstractDiagnosticTest { + TypoDiagnosticTest() { super(TypoDiagnostic.class); } + @BeforeEach + void resetJLanguageToolPool() { + var lang = diagnosticInstance.getInfo().getResourceString("diagnosticLanguage"); + diagnosticInstance.acquireLanguageTool(lang).getLanguageTool("Ы"); + } + @Test void test() { Map configuration = diagnosticInstance.getInfo().getDefaultConfiguration(); diagnosticInstance.configure(configuration); - List diagnostics = getDiagnostics(); assertThat(diagnostics).hasSize(3); @@ -78,4 +89,18 @@ void testConfigureUserWordsToIgnore() { .hasRange(1, 13, 1, 21) .hasRange(8, 13, 8, 18); } + + @Test + void testConfigureUserWordsToIgnoreWithSpaces() { + + Map configuration = diagnosticInstance.getInfo().getDefaultConfiguration(); + configuration.put("userWordsToIgnore", "Варинаты, Атмена"); + diagnosticInstance.configure(configuration); + + List diagnostics = getDiagnostics(); + + assertThat(diagnostics).hasSize(1); + assertThat(diagnostics, true) + .hasRange(8, 13, 8, 18); + } } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UsingModalWindowsDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UsingModalWindowsDiagnosticTest.java index c46ae7550bc..ad9506ce3a4 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UsingModalWindowsDiagnosticTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UsingModalWindowsDiagnosticTest.java @@ -32,6 +32,7 @@ import java.nio.file.Paths; import java.util.List; +import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.spy; @@ -53,6 +54,33 @@ void testDontUse() { var documentContext = getDocumentContextWithUseFlag(UseMode.DONT_USE); List diagnostics = getDiagnostics(documentContext); + assertDiagnosticList(diagnostics); + + } + + @Test + void testUse() { + + DocumentContext documentContext = getDocumentContextWithUseFlag(UseMode.USE); + List diagnostics = getDiagnostics(documentContext); + assertThat(diagnostics).isEmpty(); + } + + @Test + void testUseWithForce() { + + DocumentContext documentContext = getDocumentContextWithUseFlag(UseMode.USE); + + Map configuration = diagnosticInstance.getInfo().getDefaultConfiguration(); + configuration.put("forceModalityMode", true); + diagnosticInstance.configure(configuration); + + List diagnostics = getDiagnostics(documentContext); + assertDiagnosticList(diagnostics); + + } + + private void assertDiagnosticList(List diagnostics) { assertThat(diagnostics).hasSize(12) .anyMatch(diagnostic -> diagnostic.getRange().equals(Ranges.create(2, 12, 3, 57)) @@ -79,14 +107,7 @@ void testDontUse() { && diagnostic.getMessage().matches(".*(модального|modal).*УстановитьРасширениеРаботыСКриптографией.*НачатьУстановкуРасширенияРаботыСКриптографией.*")) .anyMatch(diagnostic -> diagnostic.getRange().equals(Ranges.create(186, 4, 186, 88)) && diagnostic.getMessage().matches(".*(модального|modal).*ПоместитьФайл.*НачатьПомещениеФайла.*")); - } - @Test - void testUse() { - - DocumentContext documentContext = getDocumentContextWithUseFlag(UseMode.USE); - List diagnostics = getDiagnostics(documentContext); - assertThat(diagnostics).isEmpty(); } private DocumentContext getDocumentContextWithUseFlag(UseMode useMode) { @@ -98,7 +119,7 @@ private DocumentContext getDocumentContextWithUseFlag(UseMode useMode) { when(configuration.getModalityUseMode()).thenReturn(useMode); when(context.getConfiguration()).thenReturn(configuration); - return context.addDocument(testFile.toUri(), getText()); + return context.addDocument(testFile.toUri(), getText(), 1); } } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/metadata/DiagnosticInfoTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/metadata/DiagnosticInfoTest.java index d25e2e5daaf..7d2c201bb7a 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/metadata/DiagnosticInfoTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/metadata/DiagnosticInfoTest.java @@ -23,9 +23,12 @@ import com.github._1c_syntax.bsl.languageserver.configuration.Language; import com.github._1c_syntax.bsl.languageserver.configuration.LanguageServerConfiguration; +import com.github._1c_syntax.bsl.languageserver.diagnostics.DeprecatedAttributes8312Diagnostic; import com.github._1c_syntax.bsl.languageserver.diagnostics.EmptyCodeBlockDiagnostic; import com.github._1c_syntax.bsl.languageserver.diagnostics.MultilingualStringHasAllDeclaredLanguagesDiagnostic; +import com.github._1c_syntax.bsl.languageserver.diagnostics.UnusedLocalMethodDiagnostic; import org.assertj.core.api.Assertions; +import org.eclipse.lsp4j.DiagnosticTag; import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -59,6 +62,7 @@ void testParameter() { Assertions.assertThat(diagnosticInfo.getMinutesToFix()).isEqualTo(5); Assertions.assertThat(diagnosticInfo.isActivatedByDefault()).isTrue(); Assertions.assertThat(diagnosticInfo.getTags().size()).isPositive(); + Assertions.assertThat(diagnosticInfo.getLSPTags()).isEmpty(); Assertions.assertThat(diagnosticInfo.getDefaultConfiguration().size()).isPositive(); @@ -79,6 +83,20 @@ void testParameter() { assertThat(maybeFakeParameter).isEmpty(); } + @Test + void testLSPTags() { + // given + var diagnosticInfo = new DiagnosticInfo(UnusedLocalMethodDiagnostic.class, configuration); + + // then + assertThat(diagnosticInfo.getLSPTags()).contains(DiagnosticTag.Unnecessary); + + // given + diagnosticInfo = new DiagnosticInfo(DeprecatedAttributes8312Diagnostic.class, configuration); + + // then + assertThat(diagnosticInfo.getLSPTags()).contains(DiagnosticTag.Deprecated); + } @Test void testParameterSuper() { diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/folding/QueryCommentFoldingRangeSupplierTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/folding/QueryCommentFoldingRangeSupplierTest.java new file mode 100644 index 00000000000..cb3857b67ac --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/folding/QueryCommentFoldingRangeSupplierTest.java @@ -0,0 +1,59 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.folding; + +import com.github._1c_syntax.bsl.languageserver.util.TestUtils; +import org.eclipse.lsp4j.FoldingRange; +import org.eclipse.lsp4j.FoldingRangeKind; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; + +import java.util.List; + +import static com.github._1c_syntax.bsl.languageserver.util.Assertions.assertThatFoldingRanges; +import static org.junit.jupiter.api.Assertions.*; + +@SpringBootTest +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +class QueryCommentFoldingRangeSupplierTest { + + @Autowired + private QueryCommentFoldingRangeSupplier supplier; + + @Test + void getFoldingRanges() { + // given + var documentContext = TestUtils.getDocumentContextFromFile("./src/test/resources/folding/QueryCommentFoldingRangeSupplier.bsl"); + + // when + List foldingRanges = supplier.getFoldingRanges(documentContext); + + // then + assertThatFoldingRanges(foldingRanges) + .hasSize(2) + .hasKindAndRange(FoldingRangeKind.Comment, 2, 4) + .hasKindAndRange(FoldingRangeKind.Comment, 6, 7) + ; + } +} \ No newline at end of file diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/folding/QueryPackageFoldingRangeSupplierTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/folding/QueryPackageFoldingRangeSupplierTest.java new file mode 100644 index 00000000000..3c087a147a7 --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/folding/QueryPackageFoldingRangeSupplierTest.java @@ -0,0 +1,60 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.folding; + +import com.github._1c_syntax.bsl.languageserver.util.TestUtils; +import org.eclipse.lsp4j.FoldingRange; +import org.eclipse.lsp4j.FoldingRangeKind; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; + +import java.util.List; + +import static com.github._1c_syntax.bsl.languageserver.util.Assertions.assertThatFoldingRanges; + +@SpringBootTest +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +class QueryPackageFoldingRangeSupplierTest { + + @Autowired + private QueryPackageFoldingRangeSupplier supplier; + + @Test + void getFoldingRanges() { + // given + var documentContext = TestUtils.getDocumentContextFromFile("./src/test/resources/folding/QueryPackageFoldingRangeSupplier.bsl"); + + // when + List foldingRanges = supplier.getFoldingRanges(documentContext); + + // then + assertThatFoldingRanges(foldingRanges) + .hasSize(3) + .hasKindAndRange(FoldingRangeKind.Region, 2, 5) + .hasKindAndRange(FoldingRangeKind.Region, 9, 10) + .hasKindAndRange(FoldingRangeKind.Region, 14, 17) + ; + } + +} diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/providers/CodeActionProviderTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/providers/CodeActionProviderTest.java index 489423afe0f..36ae7ae92a9 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/providers/CodeActionProviderTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/providers/CodeActionProviderTest.java @@ -36,11 +36,13 @@ import org.eclipse.lsp4j.Range; import org.eclipse.lsp4j.TextDocumentIdentifier; import org.eclipse.lsp4j.jsonrpc.messages.Either; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.annotation.DirtiesContext; +import javax.annotation.CheckForNull; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @@ -56,22 +58,28 @@ class CodeActionProviderTest { @Autowired private LanguageServerConfiguration configuration; + private DocumentContext documentContext; + + @BeforeEach + void init() { + String filePath = "./src/test/resources/providers/codeAction.bsl"; + documentContext = TestUtils.getDocumentContextFromFile(filePath); + } + @Test void testGetCodeActions() { // given - String filePath = "./src/test/resources/providers/codeAction.bsl"; - DocumentContext documentContext = TestUtils.getDocumentContextFromFile(filePath); + DiagnosticInfo diagnosticInfo = new DiagnosticInfo( + CanonicalSpellingKeywordsDiagnostic.class, + configuration + ); + DiagnosticCode diagnosticCode = diagnosticInfo.getCode(); List diagnostics = documentContext.getDiagnostics().stream() - .filter(diagnostic -> { - DiagnosticInfo diagnosticInfo = new DiagnosticInfo( - CanonicalSpellingKeywordsDiagnostic.class, - configuration - ); - DiagnosticCode diagnosticCode = diagnosticInfo.getCode(); - return diagnostic.getCode().equals(diagnosticCode); - }) + .filter(diagnostic -> diagnostic.getCode().equals(diagnosticCode)) + // clean diagnostic tags array to emulate clear of tags property from the client + .peek(diagnostic -> diagnostic.setTags(null)) .collect(Collectors.toList()); CodeActionParams params = new CodeActionParams(); @@ -95,15 +103,13 @@ void testGetCodeActions() { .anyMatch(codeAction -> codeAction.getDiagnostics().contains(diagnostics.get(0))) .anyMatch(codeAction -> codeAction.getDiagnostics().contains(diagnostics.get(1))) .anyMatch(codeAction -> codeAction.getKind().equals(CodeActionKind.QuickFix)) + .allMatch(codeAction -> (codeAction.getDiagnostics().size() == 1) == toBoolean(codeAction.getIsPreferred())) ; } @Test void testEmptyDiagnosticList() { // given - String filePath = "./src/test/resources/providers/codeAction.bsl"; - DocumentContext documentContext = TestUtils.getDocumentContextFromFile(filePath); - CodeActionParams params = new CodeActionParams(); TextDocumentIdentifier textDocumentIdentifier = new TextDocumentIdentifier(documentContext.getUri().toString()); @@ -123,4 +129,47 @@ void testEmptyDiagnosticList() { .filteredOn(codeAction -> codeAction.getRight().getKind().equals(CodeActionKind.QuickFix)) .isEmpty(); } + + @Test + void testOnly() { + // given + CodeActionParams params = new CodeActionParams(); + TextDocumentIdentifier textDocumentIdentifier = new TextDocumentIdentifier(documentContext.getUri().toString()); + + DiagnosticInfo diagnosticInfo = new DiagnosticInfo( + CanonicalSpellingKeywordsDiagnostic.class, + configuration + ); + DiagnosticCode diagnosticCode = diagnosticInfo.getCode(); + + List diagnostics = documentContext.getDiagnostics().stream() + .filter(diagnostic -> diagnostic.getCode().equals(diagnosticCode)) + .collect(Collectors.toList()); + + CodeActionContext codeActionContext = new CodeActionContext(); + + codeActionContext.setOnly(List.of(CodeActionKind.Refactor)); + codeActionContext.setDiagnostics(diagnostics); + + params.setRange(new Range()); + params.setTextDocument(textDocumentIdentifier); + params.setContext(codeActionContext); + + // when + List> codeActions = codeActionProvider.getCodeActions(params, documentContext); + + // then + assertThat(codeActions) + .extracting(Either::getRight) + .extracting(CodeAction::getKind) + .containsOnly(CodeActionKind.Refactor) + ; + } + + private static boolean toBoolean(@CheckForNull Boolean value) { + if (value == null) { + return false; + } + return value; + } } \ No newline at end of file diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/providers/DocumentLinkProviderTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/providers/DocumentLinkProviderTest.java index 63bf3f448d3..3cc19165a69 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/providers/DocumentLinkProviderTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/providers/DocumentLinkProviderTest.java @@ -58,11 +58,11 @@ void testGetDocumentLinks() { // then assertThat(documentLinks) .isNotEmpty() - .hasSize(7) + .hasSize(6) .allMatch(documentLink -> documentLink.getTarget() .startsWith(SITE_URL)) .filteredOn(documentLink -> !documentLink.getTarget().endsWith(DIAGNOSTIC_CODE)) - .hasSize(3); + .hasSize(2); } @Test @@ -80,11 +80,11 @@ void testGetDocumentLinksEn() { // then assertThat(documentLinks) .isNotEmpty() - .hasSize(7) + .hasSize(6) .allMatch(documentLink -> documentLink.getTarget() .startsWith(SITE_EN_URL)) .filteredOn(documentLink -> !documentLink.getTarget().endsWith(DIAGNOSTIC_CODE)) - .hasSize(3); + .hasSize(2); } @Test diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/providers/FormatProviderTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/providers/FormatProviderTest.java index 32d37f08891..5873b57d798 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/providers/FormatProviderTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/providers/FormatProviderTest.java @@ -54,7 +54,7 @@ class FormatProviderTest { void testRangeFormat() throws IOException { // given int startLine = 4; - int endLine = 24; + int endLine = 25; DocumentRangeFormattingParams params = new DocumentRangeFormattingParams(); params.setTextDocument(getTextDocumentIdentifier()); @@ -115,6 +115,31 @@ void testFormat() throws IOException { } + @Test + void testFormatUnaryMinus() { + + // given + DocumentFormattingParams params = new DocumentFormattingParams(); + params.setTextDocument(getTextDocumentIdentifier()); + params.setOptions(new FormattingOptions(4, true)); + + String fileContent = "Возврат-1>-2"; + DocumentContext documentContext = TestUtils.getDocumentContext( + URI.create(params.getTextDocument().getUri()), + fileContent + ); + + // when + List textEdits = formatProvider.getFormatting(params, documentContext); + + // then + assertThat(textEdits).hasSize(1); + + TextEdit textEdit = textEdits.get(0); + assertThat(textEdits.get(0).getNewText()).isEqualTo("Возврат -1 > -2"); + + } + private File getTestFile() { return new File("./src/test/resources/providers/format.bsl"); } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/Assertions.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/Assertions.java index 0a2495420cb..344daab6413 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/Assertions.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/Assertions.java @@ -24,8 +24,11 @@ import com.github._1c_syntax.bsl.languageserver.util.assertions.CodeActionAssert; import com.github._1c_syntax.bsl.languageserver.util.assertions.DiagnosticAssert; import com.github._1c_syntax.bsl.languageserver.util.assertions.DiagnosticsAssert; +import com.github._1c_syntax.bsl.languageserver.util.assertions.FoldingRangeAssert; +import com.github._1c_syntax.bsl.languageserver.util.assertions.FoldingRangesAssert; import org.eclipse.lsp4j.CodeAction; import org.eclipse.lsp4j.Diagnostic; +import org.eclipse.lsp4j.FoldingRange; import java.util.List; @@ -39,7 +42,15 @@ public static CodeActionAssert assertThat(CodeAction actual) { return new CodeActionAssert(actual); } + public static FoldingRangeAssert assertThat(FoldingRange actual) { + return new FoldingRangeAssert(actual); + } + public static DiagnosticsAssert assertThat(List actual, Object ignored) { return new DiagnosticsAssert(actual); } + + public static FoldingRangesAssert assertThatFoldingRanges(List actual) { + return new FoldingRangesAssert(actual); + } } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/TestApplicationContext.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/TestApplicationContext.java index f838b3cac61..740a36b6482 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/TestApplicationContext.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/TestApplicationContext.java @@ -21,6 +21,7 @@ */ package com.github._1c_syntax.bsl.languageserver.util; +import org.jetbrains.annotations.NotNull; import org.springframework.beans.BeansException; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; @@ -31,7 +32,7 @@ public class TestApplicationContext implements ApplicationContextAware { private static ApplicationContext CONTEXT; @Override - public void setApplicationContext(ApplicationContext context) throws BeansException { + public void setApplicationContext(@NotNull ApplicationContext context) throws BeansException { CONTEXT = context; } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/TestUtils.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/TestUtils.java index 63264704d48..94e8158c2d5 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/TestUtils.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/TestUtils.java @@ -69,6 +69,6 @@ public static DocumentContext getDocumentContext(String fileContent, @Nullable S } public static DocumentContext getDocumentContext(URI uri, String fileContent, ServerContext context) { - return context.addDocument(uri, fileContent); + return context.addDocument(uri, fileContent, 0); } } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/assertions/CodeActionAssert.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/assertions/CodeActionAssert.java index 5006d35a951..a729f5dd3d7 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/assertions/CodeActionAssert.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/assertions/CodeActionAssert.java @@ -97,7 +97,7 @@ public CodeActionAssert fixes(Diagnostic diagnostic) { // TODO: does not work for several textedits changing content length (missed semicolon ie.) String content = startText + newText + endText; - documentContext.rebuild(content); + documentContext.rebuild(content, documentContext.getVersion() + 1); }); // get diagnostics from fixed document @@ -108,7 +108,7 @@ public CodeActionAssert fixes(Diagnostic diagnostic) { ; // returning to original state - documentContext.rebuild(cachedContent); + documentContext.rebuild(cachedContent, documentContext.getVersion() + 1); return this; } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/assertions/DiagnosticAssert.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/assertions/DiagnosticAssert.java index 16f867794f9..16179380ff2 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/assertions/DiagnosticAssert.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/assertions/DiagnosticAssert.java @@ -52,4 +52,33 @@ public DiagnosticAssert hasRange(int startLine, int startChar, int endLine, int // return the current assertion for method chaining return this; } + + /** + * Проверка на совпадение сообщения диагностики и диапазона текста, где она обнаружена + * + * @param message Сообщение диагностики + * @param startLine Первая строка диапазона + * @param startChar Первый символ диапазона + * @param endLine Последняя строка диапазона + * @param endChar Последний символ диапазона + * @return Ссылка на объект для текучести + */ + public DiagnosticAssert hasMessageOnRange(String message, int startLine, int startChar, int endLine, int endChar) { + // check that actual TolkienCharacter we want to make assertions on is not null. + isNotNull(); + + // check condition + Range expectedRange = Ranges.create(startLine, startChar, endLine, endChar); + Range actualRange = actual.getRange(); + if (!Objects.equals(actualRange, expectedRange)) { + failWithMessage("Expected diagnostic's range to be <%s> but was <%s>", expectedRange.toString(), actualRange.toString()); + } + + if (!Objects.equals(message, actual.getMessage())) { + failWithMessage("Expected diagnostic's message to be <%s> but was <%s>", message, actual.getMessage()); + } + + // return the current assertion for method chaining + return this; + } } diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/assertions/DiagnosticsAssert.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/assertions/DiagnosticsAssert.java index b21431f3f4d..7961a4e3cf7 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/assertions/DiagnosticsAssert.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/assertions/DiagnosticsAssert.java @@ -51,6 +51,37 @@ public DiagnosticsAssert hasRange(int startLine, int startChar, int endChar) { } + /** + * Ассерт для проверки совпадения диапазона и сообщения + * + * @param message Сообщение диагностики + * @param startLine Первая строка диапазона + * @param startChar Первый символ диапазона + * @param endLine Последняя строка диапазона + * @param endChar Последний символ диапазона + * @return Ссылка на объект для текучести + */ + public DiagnosticsAssert hasMessageOnRange(String message, int startLine, int startChar, int endLine, int endChar) { + return anySatisfy(diagnostic -> + assertFactory.createAssert(diagnostic).hasMessageOnRange(message, startLine, startChar, endLine, endChar) + ); + } + + /** + * Ассерт для проверки совпадения диапазона-строки и сообщения + * + * @param message Сообщение диагностики + * @param lineNo Номер строки диапазона + * @param startChar Первый символ диапазона + * @param endChar Последний символ диапазона + * @return Ссылка на объект для текучести + */ + public DiagnosticsAssert hasMessageOnRange(String message, int lineNo, int startChar, int endChar) { + return anySatisfy(diagnostic -> + assertFactory.createAssert(diagnostic).hasMessageOnRange(message, lineNo, startChar, lineNo, endChar) + ); + } + @Override protected DiagnosticAssert toAssert(Diagnostic value, String description) { return assertFactory.createAssert(value); diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/assertions/FoldingRangeAssert.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/assertions/FoldingRangeAssert.java new file mode 100644 index 00000000000..5bb46a13958 --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/assertions/FoldingRangeAssert.java @@ -0,0 +1,76 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.util.assertions; + +import org.assertj.core.api.AbstractAssert; +import org.eclipse.lsp4j.FoldingRange; + +public class FoldingRangeAssert extends AbstractAssert { + + public FoldingRangeAssert(FoldingRange actual) { + super(actual, FoldingRangeAssert.class); + } + + public static FoldingRangeAssert assertThat(FoldingRange actual) { + return new FoldingRangeAssert(actual); + } + + public FoldingRangeAssert hasRange(int startLine, int endLine) { + // check that actual TolkienCharacter we want to make assertions on is not null. + isNotNull(); + + // check condition + if (!(actual.getStartLine() == startLine && actual.getEndLine() == endLine)) { + failWithMessage( + "Expected folding range to be <%d,%d> but was <%d,%d>", + startLine, + endLine, + actual.getStartLine(), + actual.getEndLine() + ); + } + + // return the current assertion for method chaining + return this; + } + + public FoldingRangeAssert hasKind(String kind) { + // check that actual TolkienCharacter we want to make assertions on is not null. + isNotNull(); + + // check condition + if (!actual.getKind().equals(kind)) { + failWithMessage( + "Expected folding kind to be <%s> but was <%s>", + kind, + actual.getKind() + ); + } + + // return the current assertion for method chaining + return this; + } + + public FoldingRangeAssert hasKindAndRange(String kind, int startLine, int endLine) { + return hasKind(kind).hasRange(startLine, endLine); + } +} diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/assertions/FoldingRangeAssertFactory.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/assertions/FoldingRangeAssertFactory.java new file mode 100644 index 00000000000..c2bbd741b35 --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/assertions/FoldingRangeAssertFactory.java @@ -0,0 +1,34 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.util.assertions; + +import org.assertj.core.api.AssertFactory; +import org.eclipse.lsp4j.FoldingRange; + +public class FoldingRangeAssertFactory implements AssertFactory { + + @Override + public FoldingRangeAssert createAssert(FoldingRange actual) { + return new FoldingRangeAssert(actual); + } + +} diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/assertions/FoldingRangesAssert.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/assertions/FoldingRangesAssert.java new file mode 100644 index 00000000000..90d555823e1 --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/util/assertions/FoldingRangesAssert.java @@ -0,0 +1,69 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright © 2018-2020 + * 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.util.assertions; + +import org.assertj.core.api.AbstractListAssert; +import org.assertj.core.util.Lists; +import org.eclipse.lsp4j.FoldingRange; + +import java.util.List; + +public class FoldingRangesAssert extends AbstractListAssert, FoldingRange, FoldingRangeAssert> { + + private final FoldingRangeAssertFactory assertFactory = new FoldingRangeAssertFactory(); + + public FoldingRangesAssert(List actual) { + super(actual, FoldingRangesAssert.class); + } + + public FoldingRangesAssert hasRange(int startLine, int endLine) { + + return anySatisfy(foldingRange -> + assertFactory.createAssert(foldingRange).hasRange(startLine, endLine) + ); + + } + + /** + * Ассерт для проверки совпадения диапазона и сообщения + * + * @param kind Тип области сворачивания (см. {@link org.eclipse.lsp4j.FoldingRangeKind} + * @param startLine Первая строка диапазона + * @param endLine Последняя строка диапазона + * @return Ссылка на объект для текучести + */ + public FoldingRangesAssert hasKindAndRange(String kind, int startLine, int endLine) { + return anySatisfy(diagnostic -> + assertFactory.createAssert(diagnostic).hasKindAndRange(kind, startLine, endLine) + ); + } + + @Override + protected FoldingRangeAssert toAssert(FoldingRange value, String description) { + return assertFactory.createAssert(value); + } + + @Override + protected FoldingRangesAssert newAbstractIterableAssert(Iterable iterable) { + return new FoldingRangesAssert(Lists.newArrayList(iterable)); + } +} diff --git a/src/test/resources/.bsl-language-server.json b/src/test/resources/.bsl-language-server.json index 20d02460c0f..7441523e779 100644 --- a/src/test/resources/.bsl-language-server.json +++ b/src/test/resources/.bsl-language-server.json @@ -7,6 +7,7 @@ "diagnostics": { "computeTrigger": "onType", "skipSupport": "withSupportLocked", + "ordinaryAppSupport": false, "mode": "only", "parameters": { "LineLength": { diff --git a/src/test/resources/cli/test.bsl.txt b/src/test/resources/cli/test.bsl.txt new file mode 100644 index 00000000000..013e3b93341 --- /dev/null +++ b/src/test/resources/cli/test.bsl.txt @@ -0,0 +1 @@ +Сообщить("Привет, мир!"); \ No newline at end of file diff --git a/src/test/resources/context/computer/MethodSymbolComputerTest.bsl b/src/test/resources/context/computer/MethodSymbolComputerTest.bsl index 4ccf4afbf0f..527840535e9 100644 --- a/src/test/resources/context/computer/MethodSymbolComputerTest.bsl +++ b/src/test/resources/context/computer/MethodSymbolComputerTest.bsl @@ -23,8 +23,8 @@ Функция Четыре() КонецФункции -// Описание // Устарела. См. функцию Три() +// Описание // Функция Пять() КонецФункции diff --git a/src/test/resources/context/computer/QueryComputerTest.bsl b/src/test/resources/context/computer/QueryComputerTest.bsl index 491ab048715..7d5860d5424 100644 --- a/src/test/resources/context/computer/QueryComputerTest.bsl +++ b/src/test/resources/context/computer/QueryComputerTest.bsl @@ -23,4 +23,42 @@ |Уничтожить ВТ; |Выбрать Поле1, Поле2 Из ВТ1"; +КонецФункции + +Функция Тест4() + + F = Новый Запрос( "" "Выбрать" "Валюты.Код, + | Валюты.Ссылка, " " Валюты.Наценка + | ИЗ Справочник.Валюты КАК Валюты" +); + +КонецФункции + +Функция Тест5() + + F = "" "Выбрать" " " "Валюты.Код, " "Валюты.Ссылка, " " Валюты.Наценка ИЗ Справочник.Валюты КАК Валюты" + +КонецФункции + +Функция Тест6() + + F = "ВЫБРАТЬ + | Валюты.Код КАК Код, + | Валюты.ВерсияДанных КАК ВерсияДанных, + | ""D"" КАК Поле1 + |ИЗ + | Справочник.Валюты КАК Валюты + |ГДЕ + | Валюты.Код = ""D""" + +КонецФункции + +Функция Тест7() + +А = "ВЫБРАТЬ РАЗРЕШЕННЫЕ Поле.Один +|КАК +| Один, 2 +| КАК Два ИЗ Справочник.Поле +|АВТОУПОРЯДОЧИВАНИЕ;"; + КонецФункции \ No newline at end of file diff --git a/src/test/resources/context/symbol/MethodDescription.bsl b/src/test/resources/context/symbol/MethodDescription.bsl new file mode 100644 index 00000000000..08a193f0d10 --- /dev/null +++ b/src/test/resources/context/symbol/MethodDescription.bsl @@ -0,0 +1,108 @@ +Процедура БезЛписания() +КонецПроцедуры + +// Описание метода +Процедура ТолькоСОписанием() +КонецПроцедуры + +// Параметры: +// ПараметрБезТипаИОписания +// ПараметрСТипом – Произвольный +// ПараметрСОписаниемСсылкой - см. ПодключаемыеКомандыПереопределяемый.ПриОпределенииКомандПодключенныхКОбъекту.НастройкиФормы +// ПараметрСТипомИОписанием - Произвольный - описание параметра см. Справочник.Контрагенты. +// ПараметрСТипамиИОписанием - Произвольный, ДокументСсылка - простое описание параметра. +// ПараметрСТипамиИОписанием2 - Произвольный, ДокументСсылка - многострочное +// описание параметра +// ПараметрСТипамиИОписанием3 - Произвольный - описание произвольного типа +// - ДокументСсылка - какой-то документ +// именно +// ссылка +// - Число - многострочное +// описание числа +// - Строка +// ПараметрМассив - Массив из Структура: +// * Элемент1 - Структура: +// ** СубЭлемент1 - Число - код региона (длина - 2). +// ** Субэлемент2 - Число - код населенного пункта (длина - 3). +// ** СубЭлемент3 - Число - код улицы (длина - 4). +// * Элемент2 - Строка +// * Элемент3 - Булево +// * Жесть - Структура +// ** Массив - Массив из Структура: +// *** Элемент - Число - описание +// *** Элемент4 - строка +// **** Элемент5 - См. ОбщийМодуль.ОбщийМетод() +Процедура ТолькоСПараметрами() +КонецПроцедуры + +// Варианты вызова: +// УниверсальнаяПроцедура(Тип11, Тип21) - описание ... +// УниверсальнаяПроцедура(Тип12, Тип22) - описание ... +// УниверсальнаяПроцедура(Тип11, Тип23) - описание ... +Процедура ТолькоСВариантамиВызовов() +КонецПроцедуры + +// Возвращаемое значение: +// - ЛюбаяСсылка - ссылка на предопределенный элемент. +// - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ. +Функция ТолькоСВозвращаемымЗначение() +КонецФункции + +// Пример: +// УниверсальнаяПроцедура(Тип11, Тип21) - описание ... +// +// УниверсальнаяПроцедура(Тип11, Тип23) - описание ... +Процедура ТолькоСПримерами() +КонецПроцедуры + +// Устарела. Следует использовать новую см. ОбщегоНазначения.Метод() +Процедура ТолькоУстарела() +КонецПроцедуры + +// Устарела. Следует использовать новую см. ОбщегоНазначения.Метод() +// Описание метода +// Несколько строк +// Параметры: +// ПараметрБезТипаИОписания +// ПараметрСТипамиИОписанием2 - Произвольный, ДокументСсылка - многострочное +// описание параметра +// ПараметрМассив - Массив из Структура: +// * Элемент1 - Структура: +// ** СубЭлемент1 - Число - код региона (длина - 2). +// ** Субэлемент2 - Число - код населенного пункта (длина - 3). +// ** СубЭлемент3 - Число - код улицы (длина - 4). +// * Элемент2 - Строка +// Варианты вызова: +// УниверсальнаяПроцедура(Тип11, Тип21) - описание ... +// УниверсальнаяПроцедура(Тип12, Тип22) - описание ... +// Возвращаемое значение: +// - ЛюбаяСсылка - ссылка на предопределенный элемент. +// - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ. +// Пример: +// Пример0(Тип11, Тип21) - описание ... +// Пример1(Тип12, Тип22) - описание ... +Функция Полная() +КонецФункции + +// Описание метода +// Несколько строк +// Параметры: +// ПараметрБезТипаИОписания +// ПараметрСТипамиИОписанием2 - Произвольный, ДокументСсылка - многострочное +// описание параметра +// ПараметрМассив - Массив из Структура: +// Возвращаемое значение: +// ЛюбаяСсылка - ссылка на предопределенный элемент. +Функция Частая() +КонецФункции + +// Описание метода +// Несколько строк +// Возвращаемое значение: +// ЛюбаяСсылка - ссылка на предопределенный элемент. +Функция БезПараметров() +КонецФункции + +// См. ОбщийМодуль.Метод() +Функция ОписаниеСсылкой(Параметр1, Знач Параметр2 = 3) +КонецФункции diff --git a/src/test/resources/diagnostics/CommandModuleExportMethodsDiagnostic.bsl b/src/test/resources/diagnostics/CommandModuleExportMethodsDiagnostic.bsl new file mode 100644 index 00000000000..4eab0c8a7e1 --- /dev/null +++ b/src/test/resources/diagnostics/CommandModuleExportMethodsDiagnostic.bsl @@ -0,0 +1,11 @@ +Процедура Тест1() Экспорт +КонецПроцедуры + +Процедура Тест2() +КонецПроцедуры + +Функция Тест3() Экспорт +КонецФункции + +Функция Тест4() +КонецФункции \ No newline at end of file diff --git a/src/test/resources/diagnostics/FunctionOutParameterDiagnostic.bsl b/src/test/resources/diagnostics/FunctionOutParameterDiagnostic.bsl new file mode 100644 index 00000000000..1b75c8a6598 --- /dev/null +++ b/src/test/resources/diagnostics/FunctionOutParameterDiagnostic.bsl @@ -0,0 +1,13 @@ +Процедура А(А, Знач Б) + А = 1; +КонецПроцедуры + +Функция А(А, Знач Б) + а = 1; + + Если А = 1 Тогда + КонецЕсли; + + Б = 2; + +КонецФункции diff --git a/src/test/resources/diagnostics/GlobalContextMethodCollision8312Diagnostic.bsl b/src/test/resources/diagnostics/GlobalContextMethodCollision8312Diagnostic.bsl new file mode 100644 index 00000000000..ad169022119 --- /dev/null +++ b/src/test/resources/diagnostics/GlobalContextMethodCollision8312Diagnostic.bsl @@ -0,0 +1,68 @@ +Функция ПроверитьБит() +КонецФункции + +Функция ПроверитьПоБитовойМаске() +КонецФункции + +Функция УстановитьБит() +КонецФункции + +Функция ПобитовоеИ() +КонецФункции + +Функция ПобитовоеИли() +КонецФункции + +Функция ПобитовоеНе() +КонецФункции + +Функция ПобитовоеИНе() +КонецФункции + +Функция ПобитовоеИсключительноеИли() +КонецФункции + +Функция ПобитовыйСдвигВлево() +КонецФункции + +Функция ПобитовыйСдвигВправо() +КонецФункции + +Функция CheckBit() +КонецФункции + +Функция CheckByBitMask() +КонецФункции + +Функция SetBit() +КонецФункции + +Функция BitwiseAnd() +КонецФункции + +Функция BitwiseOr() +КонецФункции + +Функция BitwiseNot() +КонецФункции + +Функция BitwiseAndNot() +КонецФункции + +Функция BitwiseXor() +КонецФункции + +Функция BitwiseShiftLeft() +КонецФункции + +Функция BitwiseShiftRight() +КонецФункции + +Функция _ПроверитьБит() +КонецФункции + +Функция ПроверитьПоБитовойМаске_() +КонецФункции + +Функция БИТУстановитьБит() +КонецФункции diff --git a/src/test/resources/diagnostics/LatinAndCyrillicSymbolInWordDiagnostic.bsl b/src/test/resources/diagnostics/LatinAndCyrillicSymbolInWordDiagnostic.bsl new file mode 100644 index 00000000000..89b96aa3ae8 --- /dev/null +++ b/src/test/resources/diagnostics/LatinAndCyrillicSymbolInWordDiagnostic.bsl @@ -0,0 +1,33 @@ +Перем Namе; // <- ошибка + +Процедура ВИмениEnglish() // <- ошибка + Перем а; + Перем ии, вв; + перем ССС, ccc, сcс; // <- ошибка в последнем имени + Переменная = 1; +КонецПроцедуры + +Функция InNameРусский() // <- ошибка + Перем тьфу; + Перем name; + перем Аg; // <- ошибка + перем _Аg09; // <- ошибка + Переменная = "engру"; // <- ошибки нет + ComОбъект2 = _Аg09; // <- ошибка + _3C_omRRRО_5__бъект = 1;// <- ошибка +КонецФункции + +&Аnotation // <- ошибка +Функция __t1est() // <- ошибки нет +КонецФункции + +&Аннотация(Парaметр = 1) // <- ошибка в параметре +Функция _тест12() // <- ошибки нет +КонецФункции + +#Область Regiоn // <- ошибка +#КонецОбласти + +Процедура Тест12(ПараметрY, Знач ParamЫ) // <- ошибка в именах параметров + Перейти ~Lаbell; // <- ошибка +КонецПроцедуры \ No newline at end of file diff --git a/src/test/resources/diagnostics/MagicDateDiagnostic.bsl b/src/test/resources/diagnostics/MagicDateDiagnostic.bsl new file mode 100644 index 00000000000..044f4133257 --- /dev/null +++ b/src/test/resources/diagnostics/MagicDateDiagnostic.bsl @@ -0,0 +1,14 @@ +День = Дата("00020101"); +День = Дата("00020101") + Шаг; // ошибка +День = Дата("00020101121314") + Шаг; // ошибка +День = '00010102' + Шаг; // ошибка +Пока Сейчас < '12340101' Цикл // ошибка + Сейчас = Сейчас + Шаг; +КонецЦикла; +Конец = '12340101'; +Пока Сейчас < Конец Цикл + Сейчас = Сейчас + Шаг; +КонецЦикла; +День = Дата("00010101") + Шаг; // исключение +День = '0001-01why not?01' + Шаг; // исключение +День = '0001-01why not?02' + Шаг; // ошибка \ No newline at end of file diff --git a/src/test/resources/diagnostics/MissingEventSubscriptionHandlerDiagnostic.bsl b/src/test/resources/diagnostics/MissingEventSubscriptionHandlerDiagnostic.bsl new file mode 100644 index 00000000000..50bcc22d9db --- /dev/null +++ b/src/test/resources/diagnostics/MissingEventSubscriptionHandlerDiagnostic.bsl @@ -0,0 +1,2 @@ +Функция Маркер() +КонецФункции diff --git a/src/test/resources/diagnostics/MissingParameterDescriptionDiagnostic.bsl b/src/test/resources/diagnostics/MissingParameterDescriptionDiagnostic.bsl new file mode 100644 index 00000000000..5c2a88e4c63 --- /dev/null +++ b/src/test/resources/diagnostics/MissingParameterDescriptionDiagnostic.bsl @@ -0,0 +1,81 @@ +Функция БезПараметровИОписания() +КонецФункции + +Функция БезОписания(Параметр1, Параметр2) +КонецФункции + +// Описание есть, но нет параметров +Функция Пример1(Параметр1, Параметр2) +КонецФункции + +// Описание есть, +// Параметры: +// Параметр1 - Строка - Описание параметра 1 +// Параметр2 - Строка - Описание параметра 2 +Функция Пример2() +КонецФункции + +// Описание есть, +// Параметры: +// Параметр1 - Строка - Описание параметра 1 +// Параметр2 - Строка - Описание параметра 2 +Функция Пример3(Параметр1) +КонецФункции + +// Описание есть, +// Параметры: +// Параметр1 - Строка - Описание параметра 1 +// Параметр2 - Строка - Описание параметра 2 +Функция Пример4(Параметр2, Параметр3) +КонецФункции + +// Описание есть, +// Параметры: +// Параметр2 - Строка - Описание параметра 2 +// Параметр1 - Строка - Описание параметра 1 +Функция Пример5(Параметр1, Параметр2) +КонецФункции + +// Описание есть, +// Параметры: +// Параметр1 - Строка +// Параметр2 +Функция Пример6(Параметр1, Параметр2) +КонецФункции + +// Описание есть, +// Параметры: +// Параметр1 - Строка - Описание параметра 1 +// Параметр2 - Строка - Описание параметра 2 +// Параметр2 - Строка - Описание параметра 2 +Функция Пример7(Параметр1, Параметр2) +КонецФункции + +// Описание есть, +// Параметры: +// Параметр3 - Строка - Описание параметра 3 +// Параметр4 - Строка - Описание параметра 4 +// Параметр5 +Функция Пример8(Параметр1, Параметр2) +КонецФункции + +// Описание есть, +// Параметры: +// Параметр1 - Строка - Описание параметра 1 +// Параметр2 - Строка - Описание параметра 2 +// Параметр3 - Строка - Описание параметра 3 +// Параметр4 - Строка - Описание параметра 4 +// Параметр5 - тип +Функция Пример9(Параметр1, Знач Параметр4) +КонецФункции + +// Описание есть, +// Параметры: +// Параметр1 - Строка - Описание параметра 1 +// Параметр2 - Строка - Описание параметра 2 +Функция Пример10(параметр1, ПаРамЕтр2) +КонецФункции + +// См. Пример10() +Функция Пример11(параметр1, ПаРамЕтр2) +КонецФункции diff --git a/src/test/resources/diagnostics/MissingReturnedValueDescriptionDiagnostic.bsl b/src/test/resources/diagnostics/MissingReturnedValueDescriptionDiagnostic.bsl new file mode 100644 index 00000000000..0ba2b6d9ce8 --- /dev/null +++ b/src/test/resources/diagnostics/MissingReturnedValueDescriptionDiagnostic.bsl @@ -0,0 +1,76 @@ +Функция Пример() +КонецФункции + +// Описание вроде +Функция Пример1() +КонецФункции + +// Описание вроде +// Возвращаемое значение: +Функция Пример2() +КонецФункции + +// Описание вроде +// Возвращаемое значение: +// Строка - строка типа +Функция Пример3() +КонецФункции + +// Описание вроде +// Возвращаемое значение: +// Строка - строка типа +Процедура Пример4() +КонецПроцедуры + +// Описание вроде +Процедура Пример5() +КонецПроцедуры + +// Описание вроде +// Возвращаемое значение: +// Строка +Функция Пример6() +КонецФункции + +// Описание вроде +// Возвращаемое значение: +// - Строка +// - булево +// - Неопределено - если неизвестно +Функция Пример7() +КонецФункции + +// Параметры подключения к администрируемой информационной базе кластера. +// +// Возвращаемое значение: +// Структура: +// * ИмяВКластере - Строка - имя администрируемой информационной базы в кластере серверов, +// * ИмяАдминистратораИнформационнойБазы - Строка - имя пользователя информационной базы с правами +// администратора (если для информационной базы не задан список пользователей ИБ - используется +// пустая строка), +// * ПарольАдминистратораИнформационнойБазы - Строка - пароль пользователя информационной базы +// с правами администратора (если для информационной базы не задан список пользователей ИБ или +// для пользователя ИБ не установлен пароль - используется пустая строка). +// +Функция ПараметрыАдминистрированияИнформационнойБазыКластера() Экспорт + + Результат = Новый Структура(); + + Результат.Вставить("ИмяВКластере", ""); + Результат.Вставить("ИмяАдминистратораИнформационнойБазы", ""); + Результат.Вставить("ПарольАдминистратораИнформационнойБазы", ""); + + Возврат Результат; + +КонецФункции + +// См. Пример7() +Функция Пример8() +КонецФункции + +// См. Пример7() +// +// +// +Функция Пример9() +КонецФункции diff --git a/src/test/resources/diagnostics/MissingSpaceDiagnostic.bsl b/src/test/resources/diagnostics/MissingSpaceDiagnostic.bsl index 4ec34a9f392..456a7e064bb 100644 --- a/src/test/resources/diagnostics/MissingSpaceDiagnostic.bsl +++ b/src/test/resources/diagnostics/MissingSpaceDiagnostic.bsl @@ -28,7 +28,7 @@ Рез = -А; // 1 Рез = - Б; // 0 КонецПроцедуры - +Процедура Тест() Метод1(60,24);Метод2(24, 60,,60); // 3 Метод2(60, 60, 60); // 0 @@ -43,4 +43,19 @@ Представление =" " +СокрЛ(Объект); // после равно и после плюса -Сообщить(Представление); \ No newline at end of file +Сообщить(Представление); +КонецПроцедуры + +Процедура Тест2()Экспорт // 1 + +ДЛЯ(ит = 1)по(7)Цикл // 3 +КонецЦикла; + +Для каждого(поле)из(коллекция)Цикл // 3 +КонецЦикла; + +Если(ИСТИНА)ИЛИ(ЛОЖЬ)И(ИСТИНА)Тогда // 4 +ИначеЕсли(ИСТИНА)ИЛИ(НЕ(ЛОЖЬ))Тогда // 4 +КонецЕсли; + +КонецПроцедуры \ No newline at end of file diff --git a/src/test/resources/diagnostics/OrdinaryAppSupportDiagnostic.bsl b/src/test/resources/diagnostics/OrdinaryAppSupportDiagnostic.bsl new file mode 100644 index 00000000000..7c39cc6cd87 --- /dev/null +++ b/src/test/resources/diagnostics/OrdinaryAppSupportDiagnostic.bsl @@ -0,0 +1,4 @@ + +Процедура ПриОпределенииПараметровСеанса() + +КонецПроцедуры diff --git a/src/test/resources/diagnostics/RedundantAccessToObjectDiagnostic.bsl b/src/test/resources/diagnostics/RedundantAccessToObjectDiagnostic.bsl new file mode 100644 index 00000000000..0c8f4ff6d88 --- /dev/null +++ b/src/test/resources/diagnostics/RedundantAccessToObjectDiagnostic.bsl @@ -0,0 +1,25 @@ +Процедура Тест(Данные) + + ЭтотОбъект.Контрагент = Данные.Контрагент; // Ошибка + ЭтотОбъект.Договор = Данные.Договор; // Ошибка + ЭтотОбъект["ПолеКонтактнойИнформации"] = Данные.Телефон; // Тут ошибки быть не должно + + Переменная = ЭтотОбъект.Значенние; // Ошибка + Переменная2 = ЭтотОбъект["Значенние"]; // Ошибка + Переменная3 = ЭтотОбъект.Значенние(); // Ошибка + + ЭтотОбъект.ВыполнитьЗаполнениеПоСтруктуре(Данные); // Ошибка + +КонецПроцедуры + +Procedure Test(Data) + + ThisObject.Counterparty = Data.Counterparty; // Error + ThisObject.Contract = Data.Contract; // Error + ThisObject["ContactInformationField"] = Data.Phone; + + Variable = ThisObject.Value; // Error + + ThisObject.RunFillByStructure(Data); // Error + +EndProcedure diff --git a/src/test/resources/diagnostics/RefOveruseDiagnostic.bsl b/src/test/resources/diagnostics/RefOveruseDiagnostic.bsl new file mode 100644 index 00000000000..e9ea6850c66 --- /dev/null +++ b/src/test/resources/diagnostics/RefOveruseDiagnostic.bsl @@ -0,0 +1,97 @@ +Процедура Тест() + + Запрос = Новый Запрос; + Запрос.Текст = "ВЫБРАТЬ Файлы.Файл.Ссылка, // ошибка + | Файлы.Файл + | ИЗ + | СлужебныеФайлы КАК Файлы"; +КонецПроцедуры + +Процедура Тест2() + Запрос = Новый Запрос; + Запрос.Текст = + "ВЫБРАТЬ РАЗРЕШЕННЫЕ + | СлужебныеФайлы.Файл.Ссылка КАК Ссылка, // ошибка + | СлужебныеФайлы.Владелец.Ссылка КАК Владелец // ошибка + |ИЗ + | РегистрСведений.СлужебныеФайлы КАК СлужебныеФайлы + |ГДЕ + | СлужебныеФайлы.Отношение = ЗНАЧЕНИЕ(Перечисление.ОтношенияСлужебныхФайлов.ВизуализацияЭП)"; +КонецПроцедуры + +Процедура Тест3() + Запрос = Новый Запрос; + Запрос.Текст = + "ВЫБРАТЬ РАЗРЕШЕННЫЕ + | Ссылка.Ссылка КАК Ссылка, // ошибка + | СлужебныеФайлы.Владелец КАК Владелец + |ИЗ + | РегистрСведений.СлужебныеФайлы КАК СлужебныеФайлы + |ГДЕ + | СлужебныеФайлы.Отношение = ЗНАЧЕНИЕ(Перечисление.ОтношенияСлужебныхФайлов.ВизуализацияЭП)"; +КонецПроцедуры + +Процедура Тест4() + Запрос = Новый Запрос; + Запрос.Текст = + "ВЫБРАТЬ + | Документ1.Файл.Ссылка КАК Ссылка, // ошибка + | Документ2.Контрагент.Ссылка КАК Контрагент // ошибка + |ИЗ + | Документ.Документ1 КАК Документ1 + | ЛЕВОЕ СОЕДИНЕНИЕ Документ.Документ2 КАК Документ2 + | ПО Документ1.Ссылка = Документ2.Ссылка"; +КонецПроцедуры + +Процедура Тест5() + Запрос = Новый Запрос; + Запрос.Текст = + "ВЫБРАТЬ * + |ИЗ + | Документ.Документ1 КАК Документ1"; +КонецПроцедуры + +Процедура Тест6() + Запрос = Новый Запрос; + Запрос.Текст = + "ВЫБРАТЬ Документ.Документ1.Файл.Ссылка, // ошибка + | Справочник.Справочник1.Файл.Ссылка"; // ошибка +КонецПроцедуры + +Процедура Тест7() + Запрос = Новый Запрос; + Запрос.Текст = + "ВЫБРАТь + | Таблица.Ссылка + |ИЗ + | &Таблица КАК Таблица" +КонецПроцедуры + +Процедура Тест8() + Запрос = Новый Запрос; + Запрос.Текст = + "ВЫБРАТь + | Таблица.Ссылка + |ИЗ + | Справочник." + ИмяСправочника + " КАК Таблица" +КонецПроцедуры + +Процедура Тест9() + Запрос = Новый Запрос; + Запрос.Текст = + "ВЫБРАТь + | Таблица.Ссылка.Ссылка + |ИЗ + | %1 КАК Таблица" +КонецПроцедуры + +Процедура Тест10() + Запрос = Новый Запрос; + Запрос.Текст = + "ВЫБРАТь + | Таблица.Ссылка, + | Таблица.Ссылка.Ссылка // ошибка + |ПОМЕСТИТЬ ВТ + |ИЗ + | &Таблица КАК Таблица" +КонецПроцедуры diff --git a/src/test/resources/folding/QueryCommentFoldingRangeSupplier.bsl b/src/test/resources/folding/QueryCommentFoldingRangeSupplier.bsl new file mode 100644 index 00000000000..e49f1934d11 --- /dev/null +++ b/src/test/resources/folding/QueryCommentFoldingRangeSupplier.bsl @@ -0,0 +1,16 @@ +Запрос = Новый Запрос; +Запрос.Текст = +"// Коммент +|// Еще коммент +|// И еще +|ВЫБРАТЬ ПЕРВЫЕ 1 +|// Истина +|// Коммент +|ИЗ +| Справочник.ИмяСправочника +|; +|// +| +|УНИЧТОЖИТЬ +| Таблица +|;"; diff --git a/src/test/resources/folding/QueryPackageFoldingRangeSupplier.bsl b/src/test/resources/folding/QueryPackageFoldingRangeSupplier.bsl new file mode 100644 index 00000000000..aee67e42cf9 --- /dev/null +++ b/src/test/resources/folding/QueryPackageFoldingRangeSupplier.bsl @@ -0,0 +1,23 @@ +Запрос = Новый Запрос; +Запрос.Текст = +"ВЫБРАТЬ ПЕРВЫЕ 1 +| Истина +|ИЗ +| Справочник.ИмяСправочника +|; +|// +| +|УНИЧТОЖИТЬ +| Таблица +|; +|// +| +|ВЫБРАТЬ РАЗЛИЧНЫЕ +| ИмяСправочника.Поле Как Поле +|ИЗ +| Справочник.ИмяСправочника КАК ИмяСправочника +|; +|// +| +|УНИЧТОЖИТЬ Таблица +|;"; diff --git "a/src/test/resources/metadata/Catalogs/\320\241\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\270\320\2721/Ext/ManagerModule.bsl" "b/src/test/resources/metadata/Catalogs/\320\241\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\270\320\2721/Ext/ManagerModule.bsl" index 9e86853259e..08e42ff4c47 100644 --- "a/src/test/resources/metadata/Catalogs/\320\241\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\270\320\2721/Ext/ManagerModule.bsl" +++ "b/src/test/resources/metadata/Catalogs/\320\241\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\270\320\2721/Ext/ManagerModule.bsl" @@ -6,7 +6,7 @@ #КонецОбласти #Область ПрограммныйИнтерфейс -// Код процедур и функций + #КонецОбласти #Область СлужебныйПрограммныйИнтерфейс @@ -14,7 +14,18 @@ #КонецОбласти #Область СлужебныеПроцедурыИФункции -Процедура Тест() КонецПроцедуры + +Процедура Тест() + + Справочники.Справочник1.ТестЭкспортная(); // Ошибка: Обращение через менеджер избыточно + ТестЭкспортная(); + +КонецПроцедуры + +Процедура ТестЭкспортная() Экспорт + +КонецПроцедуры + #КонецОбласти diff --git "a/src/test/resources/metadata/Catalogs/\320\241\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\270\320\2721/Ext/ObjectModule.bsl" "b/src/test/resources/metadata/Catalogs/\320\241\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\270\320\2721/Ext/ObjectModule.bsl" index ccb85c7239d..61f4bd8024a 100644 --- "a/src/test/resources/metadata/Catalogs/\320\241\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\270\320\2721/Ext/ObjectModule.bsl" +++ "b/src/test/resources/metadata/Catalogs/\320\241\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\270\320\2721/Ext/ObjectModule.bsl" @@ -54,5 +54,6 @@ Function Тест() EndFunction SupportEmail = "v8@1c.ru"; Ctor(); +ThisObject.Ctor(); #EndRegion \ No newline at end of file diff --git "a/src/test/resources/metadata/Catalogs/\320\241\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\270\320\2721/Forms/\320\244\320\276\321\200\320\274\320\260\320\255\320\273\320\265\320\274\320\265\320\275\321\202\320\260/Ext/Form/Module.bsl" "b/src/test/resources/metadata/Catalogs/\320\241\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\270\320\2721/Forms/\320\244\320\276\321\200\320\274\320\260\320\255\320\273\320\265\320\274\320\265\320\275\321\202\320\260/Ext/Form/Module.bsl" index 6fed0ff7bc1..6abe31c53e6 100644 --- "a/src/test/resources/metadata/Catalogs/\320\241\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\270\320\2721/Forms/\320\244\320\276\321\200\320\274\320\260\320\255\320\273\320\265\320\274\320\265\320\275\321\202\320\260/Ext/Form/Module.bsl" +++ "b/src/test/resources/metadata/Catalogs/\320\241\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\270\320\2721/Forms/\320\244\320\276\321\200\320\274\320\260\320\255\320\273\320\265\320\274\320\265\320\275\321\202\320\260/Ext/Form/Module.bsl" @@ -62,5 +62,6 @@ SupportEmail = "v8@1c.ru"; Ctor(); +ThisObject.Ctor(); #EndRegion diff --git "a/src/test/resources/metadata/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202\321\201\320\272\320\270\320\271\320\236\320\261\321\211\320\270\320\271\320\234\320\276\320\264\321\203\320\273\321\214.xml" "b/src/test/resources/metadata/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202\321\201\320\272\320\270\320\271\320\236\320\261\321\211\320\270\320\271\320\234\320\276\320\264\321\203\320\273\321\214.xml" new file mode 100644 index 00000000000..34c01643523 --- /dev/null +++ "b/src/test/resources/metadata/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202\321\201\320\272\320\270\320\271\320\236\320\261\321\211\320\270\320\271\320\234\320\276\320\264\321\203\320\273\321\214.xml" @@ -0,0 +1,23 @@ + + + + + КлиентскийОбщийМодуль + + + ru + Клиентский общий модуль + + + + false + true + false + false + true + false + false + DontUse + + + \ No newline at end of file diff --git "a/src/test/resources/metadata/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202\321\201\320\272\320\270\320\271\320\236\320\261\321\211\320\270\320\271\320\234\320\276\320\264\321\203\320\273\321\214/Ext/Module.bsl" "b/src/test/resources/metadata/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202\321\201\320\272\320\270\320\271\320\236\320\261\321\211\320\270\320\271\320\234\320\276\320\264\321\203\320\273\321\214/Ext/Module.bsl" new file mode 100644 index 00000000000..500656489a8 --- /dev/null +++ "b/src/test/resources/metadata/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202\321\201\320\272\320\270\320\271\320\236\320\261\321\211\320\270\320\271\320\234\320\276\320\264\321\203\320\273\321\214/Ext/Module.bsl" @@ -0,0 +1,3 @@ +Процедура ПередЗаписьюДокумента(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт + +КонецПроцедуры diff --git "a/src/test/resources/metadata/CommonModules/\320\237\320\265\321\200\320\262\321\213\320\271\320\236\320\261\321\211\320\270\320\271\320\234\320\276\320\264\321\203\320\273\321\214/Ext/Module.bsl" "b/src/test/resources/metadata/CommonModules/\320\237\320\265\321\200\320\262\321\213\320\271\320\236\320\261\321\211\320\270\320\271\320\234\320\276\320\264\321\203\320\273\321\214/Ext/Module.bsl" index ff08e73dab6..812b9db5a04 100644 --- "a/src/test/resources/metadata/CommonModules/\320\237\320\265\321\200\320\262\321\213\320\271\320\236\320\261\321\211\320\270\320\271\320\234\320\276\320\264\321\203\320\273\321\214/Ext/Module.bsl" +++ "b/src/test/resources/metadata/CommonModules/\320\237\320\265\321\200\320\262\321\213\320\271\320\236\320\261\321\211\320\270\320\271\320\234\320\276\320\264\321\203\320\273\321\214/Ext/Module.bsl" @@ -59,8 +59,8 @@ КонецПроцедуры -// Процедура - Устаревшая процедура // Устарела. См. НеУстаревшаяПроцедура. +// Процедура - Устаревшая процедура Процедура УстаревшаяПроцедура() Экспорт КонецПроцедуры @@ -69,12 +69,23 @@ КонецФункции -// Функция - Устаревшая функция // Устарела. См. НеУстаревшаяФункция. +// Функция - Устаревшая функция Функция УстаревшаяФункция() Экспорт + ПервыйОбщийМодуль.НеУстаревшаяФункция(); + НеУстаревшаяФункция(); + КонецФункции +Процедура ВерсионированиеПриЗаписи(Источник, Отказ) Экспорт + +КонецПроцедуры + +Процедура РегистрацияИзмененийПередУдалением(Источник, Отказ) + +КонецПроцедуры + #Region Initialize // SupportEmail = "v8@1c.ru"; diff --git a/src/test/resources/metadata/Configuration.xml b/src/test/resources/metadata/Configuration.xml index 657dee5c111..2854ada044a 100644 --- a/src/test/resources/metadata/Configuration.xml +++ b/src/test/resources/metadata/Configuration.xml @@ -1,4 +1,4 @@ - + @@ -48,7 +48,7 @@ false false - false + true @@ -184,10 +184,19 @@ Русский ПервыйОбщийМодуль + КлиентскийОбщийМодуль + WebСервис1 HTTPСервис1 ГруппаКоманд1 Справочник1 РегистрСведений1 + ВерсионированиеПриЗаписи + ПередЗаписьюДокумента + ПередЗаписьюКонстанты + ПриЗаписиДокумента + ПриЗаписиСправочника + ПриУстановкеНовогоКода + РегистрацияИзмененийПередУдалением \ No newline at end of file diff --git "a/src/test/resources/metadata/EventSubscriptions/\320\222\320\265\321\200\321\201\320\270\320\276\320\275\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265\320\237\321\200\320\270\320\227\320\260\320\277\320\270\321\201\320\270.xml" "b/src/test/resources/metadata/EventSubscriptions/\320\222\320\265\321\200\321\201\320\270\320\276\320\275\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265\320\237\321\200\320\270\320\227\320\260\320\277\320\270\321\201\320\270.xml" new file mode 100644 index 00000000000..3ff2de8c881 --- /dev/null +++ "b/src/test/resources/metadata/EventSubscriptions/\320\222\320\265\321\200\321\201\320\270\320\276\320\275\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265\320\237\321\200\320\270\320\227\320\260\320\277\320\270\321\201\320\270.xml" @@ -0,0 +1,25 @@ + + + + + ВерсионированиеПриЗаписи + + + ru + Версионирование при записи + + + + + cfg:CatalogObject.Фотографии + cfg:CatalogObject.Телефоны + cfg:CatalogObject.Банки + cfg:CatalogObject.Пункты + cfg:CatalogObject.Маяки + cfg:DocumentObject + + OnWrite + CommonModule.ПервыйОбщийМодуль.ВерсионированиеПриЗаписи + + + \ No newline at end of file diff --git "a/src/test/resources/metadata/EventSubscriptions/\320\237\320\265\321\200\320\265\320\264\320\227\320\260\320\277\320\270\321\201\321\214\321\216\320\224\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\260.xml" "b/src/test/resources/metadata/EventSubscriptions/\320\237\320\265\321\200\320\265\320\264\320\227\320\260\320\277\320\270\321\201\321\214\321\216\320\224\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\260.xml" new file mode 100644 index 00000000000..ce2138543b3 --- /dev/null +++ "b/src/test/resources/metadata/EventSubscriptions/\320\237\320\265\321\200\320\265\320\264\320\227\320\260\320\277\320\270\321\201\321\214\321\216\320\224\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\260.xml" @@ -0,0 +1,20 @@ + + + + + ПередЗаписьюДокумента + + + ru + Перед записью документа + + + + + cfg:DocumentObject + + BeforeWrite + CommonModule.КлиентскийОбщийМодуль.ПередЗаписьюДокумента + + + \ No newline at end of file diff --git "a/src/test/resources/metadata/EventSubscriptions/\320\237\320\265\321\200\320\265\320\264\320\227\320\260\320\277\320\270\321\201\321\214\321\216\320\232\320\276\320\275\321\201\321\202\320\260\320\275\321\202\321\213.xml" "b/src/test/resources/metadata/EventSubscriptions/\320\237\320\265\321\200\320\265\320\264\320\227\320\260\320\277\320\270\321\201\321\214\321\216\320\232\320\276\320\275\321\201\321\202\320\260\320\275\321\202\321\213.xml" new file mode 100644 index 00000000000..b179ce59e1a --- /dev/null +++ "b/src/test/resources/metadata/EventSubscriptions/\320\237\320\265\321\200\320\265\320\264\320\227\320\260\320\277\320\270\321\201\321\214\321\216\320\232\320\276\320\275\321\201\321\202\320\260\320\275\321\202\321\213.xml" @@ -0,0 +1,20 @@ + + + + + ПередЗаписьюКонстанты + + + ru + Перед записью константы + + + + + cfg:ConstantValueManager + + BeforeWrite + + + + \ No newline at end of file diff --git "a/src/test/resources/metadata/EventSubscriptions/\320\237\321\200\320\270\320\227\320\260\320\277\320\270\321\201\320\270\320\224\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\260.xml" "b/src/test/resources/metadata/EventSubscriptions/\320\237\321\200\320\270\320\227\320\260\320\277\320\270\321\201\320\270\320\224\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\260.xml" new file mode 100644 index 00000000000..91e8f555a71 --- /dev/null +++ "b/src/test/resources/metadata/EventSubscriptions/\320\237\321\200\320\270\320\227\320\260\320\277\320\270\321\201\320\270\320\224\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\260.xml" @@ -0,0 +1,20 @@ + + + + + ПриЗаписиДокумента + + + ru + При записи документа + + + + + cfg:DocumentObject + + OnWrite + CommonModule.ОбщийПодпискиНаСобытия + + + \ No newline at end of file diff --git "a/src/test/resources/metadata/EventSubscriptions/\320\237\321\200\320\270\320\227\320\260\320\277\320\270\321\201\320\270\320\241\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\270\320\272\320\260.xml" "b/src/test/resources/metadata/EventSubscriptions/\320\237\321\200\320\270\320\227\320\260\320\277\320\270\321\201\320\270\320\241\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\270\320\272\320\260.xml" new file mode 100644 index 00000000000..52843ad9f13 --- /dev/null +++ "b/src/test/resources/metadata/EventSubscriptions/\320\237\321\200\320\270\320\227\320\260\320\277\320\270\321\201\320\270\320\241\320\277\321\200\320\260\320\262\320\276\321\207\320\275\320\270\320\272\320\260.xml" @@ -0,0 +1,26 @@ + + + + + ПриЗаписиСправочника + + + ru + При записи справочника + + + + + cfg:CatalogObject.ТелефонныеОператоры + cfg:CatalogObject.Дома + cfg:CatalogObject.Проекты + cfg:CatalogObject.Звенья + cfg:CatalogObject.Судьи + cfg:CatalogObject.Акции + cfg:CatalogObject.КассовыеТерминалы + + OnWrite + CommonModule.ОбщийПодпискиНаСобытия.ПриЗаписиСправочника + + + \ No newline at end of file diff --git "a/src/test/resources/metadata/EventSubscriptions/\320\237\321\200\320\270\320\243\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\265\320\235\320\276\320\262\320\276\320\263\320\276\320\232\320\276\320\264\320\260.xml" "b/src/test/resources/metadata/EventSubscriptions/\320\237\321\200\320\270\320\243\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\265\320\235\320\276\320\262\320\276\320\263\320\276\320\232\320\276\320\264\320\260.xml" new file mode 100644 index 00000000000..06b0bb94349 --- /dev/null +++ "b/src/test/resources/metadata/EventSubscriptions/\320\237\321\200\320\270\320\243\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\265\320\235\320\276\320\262\320\276\320\263\320\276\320\232\320\276\320\264\320\260.xml" @@ -0,0 +1,23 @@ + + + + + ПриУстановкеНовогоКода + + + ru + При установке нового кода + + + + + cfg:CatalogObject.Склады + cfg:CatalogObject.Сотрудники + cfg:CatalogObject.Подразделения + cfg:CatalogObject.Должности + + OnSetNewCode + CommonModule.ПервыйОбщийМодуль.ПодпискаНаСобытиеПриУстановкеНовогоКода + + + \ No newline at end of file diff --git "a/src/test/resources/metadata/EventSubscriptions/\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\260\321\206\320\270\321\217\320\230\320\267\320\274\320\265\320\275\320\265\320\275\320\270\320\271\320\237\320\265\321\200\320\265\320\264\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265\320\274.xml" "b/src/test/resources/metadata/EventSubscriptions/\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\260\321\206\320\270\321\217\320\230\320\267\320\274\320\265\320\275\320\265\320\275\320\270\320\271\320\237\320\265\321\200\320\265\320\264\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265\320\274.xml" new file mode 100644 index 00000000000..e9a97670d82 --- /dev/null +++ "b/src/test/resources/metadata/EventSubscriptions/\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\260\321\206\320\270\321\217\320\230\320\267\320\274\320\265\320\275\320\265\320\275\320\270\320\271\320\237\320\265\321\200\320\265\320\264\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265\320\274.xml" @@ -0,0 +1,20 @@ + + + + + РегистрацияИзмененийПередУдалением + + + ru + Регистрация изменений перед удалением + + + + + cfg:CatalogObject.Судьи + + BeforeDelete + CommonModule.ПервыйОбщийМодуль.РегистрацияИзмененийПередУдалением + + + \ No newline at end of file diff --git "a/src/test/resources/metadata/InformationRegisters/\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\241\320\262\320\265\320\264\320\265\320\275\320\270\320\2711/Ext/ManagerModule.bsl" "b/src/test/resources/metadata/InformationRegisters/\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\241\320\262\320\265\320\264\320\265\320\275\320\270\320\2711/Ext/ManagerModule.bsl" index b9286474110..b16027fff5d 100644 --- "a/src/test/resources/metadata/InformationRegisters/\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\241\320\262\320\265\320\264\320\265\320\275\320\270\320\2711/Ext/ManagerModule.bsl" +++ "b/src/test/resources/metadata/InformationRegisters/\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\241\320\262\320\265\320\264\320\265\320\275\320\270\320\2711/Ext/ManagerModule.bsl" @@ -2,8 +2,8 @@ КонецПроцедуры -// Процедура - Устаревшая процедура // Устарела. См. НеУстаревшаяПроцедура. +// Процедура - Устаревшая процедура Процедура УстаревшаяПроцедура() Экспорт КонецПроцедуры @@ -12,8 +12,11 @@ КонецФункции -// Функция - Устаревшая функция // Устарела. См. НеУстаревшаяФункция. +// Функция - Устаревшая функция Функция УстаревшаяФункция() Экспорт + РегистрыСведений.РегистрСведений1.НеУстаревшаяПроцедура(); + НеУстаревшаяПроцедура(); + КонецФункции diff --git "a/src/test/resources/metadata/InformationRegisters/\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\241\320\262\320\265\320\264\320\265\320\275\320\270\320\2711/Ext/RecordSetModule.bsl" "b/src/test/resources/metadata/InformationRegisters/\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\241\320\262\320\265\320\264\320\265\320\275\320\270\320\2711/Ext/RecordSetModule.bsl" index 5336dff9ef1..a944c36c3f9 100644 --- "a/src/test/resources/metadata/InformationRegisters/\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\241\320\262\320\265\320\264\320\265\320\275\320\270\320\2711/Ext/RecordSetModule.bsl" +++ "b/src/test/resources/metadata/InformationRegisters/\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\241\320\262\320\265\320\264\320\265\320\275\320\270\320\2711/Ext/RecordSetModule.bsl" @@ -54,5 +54,6 @@ SupportEmail = "v8@1c.ru"; Ctor(); +ThisObject.Ctor(); #EndRegion \ No newline at end of file diff --git "a/src/test/resources/metadata/WebServices/Web\320\241\320\265\321\200\320\262\320\270\321\2011.xml" "b/src/test/resources/metadata/WebServices/Web\320\241\320\265\321\200\320\262\320\270\321\2011.xml" new file mode 100644 index 00000000000..7bee6685e2f --- /dev/null +++ "b/src/test/resources/metadata/WebServices/Web\320\241\320\265\321\200\320\262\320\270\321\2011.xml" @@ -0,0 +1,30 @@ + + + + + WebСервис1 + + + test.com + + ws1.1cws + AutoUse + 20 + + + + + Операция1 + + + xs:string + false + false + Операция1 + Managed + + + + + + \ No newline at end of file diff --git "a/src/test/resources/metadata/WebServices/Web\320\241\320\265\321\200\320\262\320\270\321\2011/Ext/Module.bsl" "b/src/test/resources/metadata/WebServices/Web\320\241\320\265\321\200\320\262\320\270\321\2011/Ext/Module.bsl" new file mode 100644 index 00000000000..07f4b13dc06 --- /dev/null +++ "b/src/test/resources/metadata/WebServices/Web\320\241\320\265\321\200\320\262\320\270\321\2011/Ext/Module.bsl" @@ -0,0 +1,23 @@ +#Область ОбработчикиСобытий + +Функция Операция1() + // Вставить содержимое обработчика. +КонецФункции + +#КонецОбласти + +#Область СлужебныеПроцедурыИФункции + +Функция Метод1() + // Вставить содержимое обработчика. +КонецФункции + +#КонецОбласти + +#Область ПростоОбласть + +Функция Метод2() + // Вставить содержимое обработчика. +КонецФункции + +#КонецОбласти diff --git a/src/test/resources/providers/format.bsl b/src/test/resources/providers/format.bsl index 6f5e71b52b3..d8e3b690ee5 100644 --- a/src/test/resources/providers/format.bsl +++ b/src/test/resources/providers/format.bsl @@ -19,6 +19,7 @@ Пока Истина Цикл А=А-1; + F=-1; КонецЦикла; КонецПроцедуры diff --git a/src/test/resources/providers/format_formatted.bsl b/src/test/resources/providers/format_formatted.bsl index 27cb8a69477..818662c4883 100644 --- a/src/test/resources/providers/format_formatted.bsl +++ b/src/test/resources/providers/format_formatted.bsl @@ -19,6 +19,7 @@ Пока Истина Цикл А = А - 1; + F = -1; КонецЦикла; КонецПроцедуры diff --git a/src/test/resources/suppliers/disableDiagnosticTriggering.bsl b/src/test/resources/suppliers/disableDiagnosticTriggering.bsl new file mode 100644 index 00000000000..06af581c49c --- /dev/null +++ b/src/test/resources/suppliers/disableDiagnosticTriggering.bsl @@ -0,0 +1,57 @@ +Перем А Экспорт; + +Функция Б() Экспорт + + С = Новый Структура("А,Б,В,Г", 0, 0, 0, 0); + +КонецФункции + +Функция В(Условие) + + Если Условие = "1" Тогда + + Результат = 1; + + ИначеЕсли Условие = "2" Тогда + + Результат = 2; + + ИначеЕсли Условие = "1" Тогда + + Результат = 3; + + Иначе + + Результат = 4; + + КонецЕсли; + + Возврат Результат; + +КонецФункции + +Функция Д(Условие) + + Если Условие = "1" Тогда + + Результат = 1; + + ИначеЕсли Условие = "2" Тогда + + Результат = 2; + + ИначеЕсли Условие = "3" Тогда + + Результат = 3; + + КонецЕсли; + + Возврат Результат; + +КонецФункции + +// В строке несколько срабатываний одной диагностики, код экшен должен быть один +СложениеБезОтступов=1+2+3+4+5; + +// В строке несколько срабатываний разных диагностик +СложениеБезОтступов = (1=2) или (3=4); // Тут уже есть какой-то комментарий \ No newline at end of file diff --git a/src/test/resources/suppliers/disableDiagnosticTriggeringEmpty.bsl b/src/test/resources/suppliers/disableDiagnosticTriggeringEmpty.bsl new file mode 100644 index 00000000000..e69de29bb2d