diff --git a/docs/diagnostics/UselessTernaryOperator.md b/docs/diagnostics/UselessTernaryOperator.md
new file mode 100644
index 00000000000..3bd335b8982
--- /dev/null
+++ b/docs/diagnostics/UselessTernaryOperator.md
@@ -0,0 +1,47 @@
+# Бесполезный тернарный оператор (UselessTernaryOperator)
+
+| Тип | Поддерживаются
языки | Важность | Включена
по умолчанию | Время на
исправление (мин) | Теги |
+|:-------------:|:-----------------------------:|:----------------:|:------------------------------:|:-----------------------------------:|:-----------------------------------:|
+| `Дефект кода` | `BSL` | `Информационный` | `Да` | `1` | `badpractice`
`suspicious` |
+
+
+## Описание диагностики
+Размещение в тернарном операторе булевых констант "Истина" или "Ложь" указывает на плохую продуманность кода.
+
+## Примеры
+Бессмысленные операторы
+
+```Bsl
+А = ?(Истина, 1, 0);
+```
+```Bsl
+А = ?(Б = 1, Истина, Ложь);
+```
+```Bsl
+А = ?(Б = 0, False, True);
+```
+
+Подозрительные операторы
+
+```Bsl
+А = ?(Б = 1, True, Истина);
+```
+```Bsl
+А = ?(Б = 0, 0, False);
+```
+
+## Сниппеты
+
+
+### Экранирование кода
+
+```bsl
+// BSLLS:UselessTernaryOperator-off
+// BSLLS:UselessTernaryOperator-on
+```
+
+### Параметр конфигурационного файла
+
+```json
+"UselessTernaryOperator": false
+```
diff --git a/docs/en/diagnostics/UselessTernaryOperator.md b/docs/en/diagnostics/UselessTernaryOperator.md
new file mode 100644
index 00000000000..37d47671a28
--- /dev/null
+++ b/docs/en/diagnostics/UselessTernaryOperator.md
@@ -0,0 +1,47 @@
+# Useless ternary operator (UselessTernaryOperator)
+
+| Type | Scope | Severity | Activated
by default | Minutes
to fix | Tags |
+|:------------:|:-----:|:--------:|:-----------------------------:|:-----------------------:|:-----------------------------------:|
+| `Code smell` | `BSL` | `Info` | `Yes` | `1` | `badpractice`
`suspicious` |
+
+
+## Description
+The placement of Boolean constants "True" or "False" in the ternary operator indicates poor code thoughtfulness.
+
+## Examples
+Useless operators
+
+```Bsl
+A = ?(True, 1, 0);
+```
+```Bsl
+A = ?(B = 1, True, False);
+```
+```Bsl
+A = ?(B = 0, False, True);
+```
+
+Suspicious operators
+
+```Bsl
+A = ?(B = 1, True, True);
+```
+```Bsl
+A = ?(B = 0, 0, False);
+```
+
+## Snippets
+
+
+### Diagnostic ignorance in code
+
+```bsl
+// BSLLS:UselessTernaryOperator-off
+// BSLLS:UselessTernaryOperator-on
+```
+
+### Parameter for config
+
+```json
+"UselessTernaryOperator": false
+```
diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic.java
new file mode 100644
index 00000000000..3cbdacdc18b
--- /dev/null
+++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic.java
@@ -0,0 +1,131 @@
+/*
+ * This file is a part of BSL Language Server.
+ *
+ * Copyright (c) 2018-2021
+ * Alexey Sosnoviy , Nikita Gryzlov and contributors
+ *
+ * SPDX-License-Identifier: LGPL-3.0-or-later
+ *
+ * BSL Language Server is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * BSL Language Server is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with BSL Language Server.
+ */
+package com.github._1c_syntax.bsl.languageserver.diagnostics;
+
+import com.github._1c_syntax.bsl.languageserver.context.DocumentContext;
+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.providers.CodeActionProvider;
+import com.github._1c_syntax.bsl.parser.BSLParser;
+import com.github._1c_syntax.mdclasses.mdo.MDLanguage;
+import org.antlr.v4.runtime.tree.ParseTree;
+import org.eclipse.lsp4j.CodeAction;
+import org.eclipse.lsp4j.CodeActionParams;
+import org.eclipse.lsp4j.Diagnostic;
+import org.eclipse.lsp4j.TextEdit;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+@DiagnosticMetadata(
+ type = DiagnosticType.CODE_SMELL,
+ severity = DiagnosticSeverity.INFO,
+ scope = DiagnosticScope.BSL,
+ minutesToFix = 1,
+ tags = {
+ DiagnosticTag.BADPRACTICE,
+ DiagnosticTag.SUSPICIOUS
+ }
+
+)
+public class UselessTernaryOperatorDiagnostic extends AbstractVisitorDiagnostic implements QuickFixProvider {
+
+ private static final int SKIPPED_RULE_INDEX = 0;
+
+ @Override
+ public ParseTree visitTernaryOperator(BSLParser.TernaryOperatorContext ctx){
+
+ var exp = ctx.expression();
+ var condition = getBooleanToken(exp.get(0));
+ var trueBranch = getBooleanToken(exp.get(1));
+ var falseBranch = getBooleanToken(exp.get(2));
+
+ if (condition != SKIPPED_RULE_INDEX) {
+ diagnosticStorage.addDiagnostic(ctx);
+ } else if (trueBranch == BSLParser.TRUE && falseBranch == BSLParser.FALSE){
+ var dgs = diagnosticStorage.addDiagnostic(ctx);
+ dgs.ifPresent(diagnostic -> diagnostic.setData(exp.get(0).getText()));
+ } else if (trueBranch == BSLParser.FALSE && falseBranch == BSLParser.TRUE){
+ var dgs = diagnosticStorage.addDiagnostic(ctx);
+ dgs.ifPresent(diagnostic -> diagnostic.setData(getAdaptedText(exp.get(0).getText())));
+ } else if (trueBranch != SKIPPED_RULE_INDEX || falseBranch != SKIPPED_RULE_INDEX){
+ diagnosticStorage.addDiagnostic(ctx);
+ }
+
+ return super.visitTernaryOperator(ctx);
+ }
+
+ @Override
+ public List getQuickFixes(
+ List diagnostics,
+ CodeActionParams params,
+ DocumentContext documentContext
+ ) {
+
+ List textEdits = new ArrayList<>();
+
+ diagnostics.forEach((Diagnostic diagnostic) -> {
+ var range = diagnostic.getRange();
+ var textEdit = new TextEdit(range, (String) diagnostic.getData());
+ textEdits.add(textEdit);
+ });
+
+ return CodeActionProvider.createCodeActions(
+ textEdits,
+ info.getResourceString("quickFixMessage"),
+ documentContext.getUri(),
+ diagnostics
+ );
+
+ }
+
+ private String getAdaptedText(String text) {
+ if(documentContext.getServerContext().getConfiguration().getDefaultLanguage() == MDLanguage.ENGLISH) {
+ return "NOT (" + text + ")";
+ } else {
+ return "НЕ (" + text + ")";
+ }
+ }
+
+ private int getBooleanToken(BSLParser.ExpressionContext expCtx){
+
+ var tmpCtx = Optional.of(expCtx)
+ .filter(ctx -> ctx.children.size() == 1)
+ .map(ctx -> (BSLParser.MemberContext) ctx.getChild(0))
+ .map(ctx -> ctx.getChild(0))
+ .filter(BSLParser.ConstValueContext.class::isInstance)
+ .map(BSLParser.ConstValueContext.class::cast);
+
+ return tmpCtx
+ .map(ctx -> ctx.getToken(BSLParser.TRUE, 0))
+ .map(ctx -> BSLParser.TRUE)
+ .or(() -> tmpCtx
+ .map(ctx -> ctx.getToken(BSLParser.FALSE, 0))
+ .map(ctx -> BSLParser.FALSE)
+ )
+ .orElse(SKIPPED_RULE_INDEX);
+ }
+}
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 2935ffe44cf..98a0e6477a7 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
@@ -1810,6 +1810,16 @@
"title": "Useless collection iteration",
"$id": "#/definitions/UseLessForEach"
},
+ "UselessTernaryOperator": {
+ "description": "Useless ternary operator",
+ "default": true,
+ "type": [
+ "boolean",
+ "object"
+ ],
+ "title": "Useless ternary operator",
+ "$id": "#/definitions/UselessTernaryOperator"
+ },
"UsingCancelParameter": {
"description": "Using parameter \"Cancel\"",
"default": true,
diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/configuration/schema.json b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/configuration/schema.json
index 89715626336..da86fd4819d 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
@@ -413,6 +413,9 @@
"UseLessForEach": {
"$ref": "parameters-schema.json#/definitions/UseLessForEach"
},
+ "UselessTernaryOperator": {
+ "$ref": "parameters-schema.json#/definitions/UselessTernaryOperator"
+ },
"UsingCancelParameter": {
"$ref": "parameters-schema.json#/definitions/UsingCancelParameter"
},
diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic_en.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic_en.properties
new file mode 100644
index 00000000000..28d413d8b06
--- /dev/null
+++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic_en.properties
@@ -0,0 +1,3 @@
+diagnosticMessage=Useless ternary operator
+diagnosticName=Useless ternary operator
+quickFixMessage=Fix some useless ternary operators
\ No newline at end of file
diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic_ru.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic_ru.properties
new file mode 100644
index 00000000000..250bcee805a
--- /dev/null
+++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic_ru.properties
@@ -0,0 +1,3 @@
+diagnosticMessage=Бесполезный тернарный оператор
+diagnosticName=Бесполезный тернарный оператор
+quickFixMessage=Исправить некоторые бесполезные тернарные операторы
\ No newline at end of file
diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnosticTest.java
new file mode 100644
index 00000000000..7680c07b506
--- /dev/null
+++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnosticTest.java
@@ -0,0 +1,86 @@
+/*
+ * This file is a part of BSL Language Server.
+ *
+ * Copyright (c) 2018-2021
+ * Alexey Sosnoviy , Nikita Gryzlov and contributors
+ *
+ * SPDX-License-Identifier: LGPL-3.0-or-later
+ *
+ * BSL Language Server is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * BSL Language Server is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with BSL Language Server.
+ */
+package com.github._1c_syntax.bsl.languageserver.diagnostics;
+
+import com.github._1c_syntax.bsl.languageserver.context.DocumentContext;
+import org.eclipse.lsp4j.CodeAction;
+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 UselessTernaryOperatorDiagnosticTest extends AbstractDiagnosticTest {
+
+ UselessTernaryOperatorDiagnosticTest() {
+ super(UselessTernaryOperatorDiagnostic.class);
+ }
+
+ @Test
+ void test() {
+
+ List diagnostics = getDiagnostics();
+
+ assertThat(diagnostics).hasSize(8);
+ assertThat(diagnostics, true)
+ .hasRange(1, 4, 1, 26)
+ .hasRange(2, 4, 2, 25)
+ .hasRange(3, 4, 3, 26)
+ .hasRange(4, 4, 4, 25)
+ .hasRange(5, 4, 5, 21)
+ .hasRange(6, 4, 6, 22)
+ .hasRange(7, 4, 7, 19)
+ .hasRange(8, 4, 8, 18);
+
+ }
+
+ @Test
+ void testQuickFix() {
+
+ final DocumentContext documentContext = getDocumentContext();
+ List diagnostics = getDiagnostics();
+
+ final Diagnostic directDiagnostic = diagnostics.get(0);
+ List directQuickFixes = getQuickFixes(directDiagnostic);
+ assertThat(directQuickFixes).hasSize(1);
+ final CodeAction directQuickFix = directQuickFixes.get(0);
+ assertThat(directQuickFix)
+ .of(diagnosticInstance)
+ .in(documentContext)
+ .fixes(directDiagnostic)
+ .hasChanges(1)
+ .hasNewText("Б=1");
+
+ final Diagnostic reversDiagnostic = diagnostics.get(1);
+ List reversQuickFixes = getQuickFixes(reversDiagnostic);
+ assertThat(reversQuickFixes).hasSize(1);
+ final CodeAction reversQuickFix = reversQuickFixes.get(0);
+ assertThat(reversQuickFix)
+ .of(diagnosticInstance)
+ .in(documentContext)
+ .fixes(reversDiagnostic)
+ .hasChanges(1)
+ .hasNewText("NOT (Б=0)");
+ }
+
+}
diff --git a/src/test/resources/diagnostics/UselessTernaryOperatorDiagnostic.bsl b/src/test/resources/diagnostics/UselessTernaryOperatorDiagnostic.bsl
new file mode 100644
index 00000000000..21c447838b3
--- /dev/null
+++ b/src/test/resources/diagnostics/UselessTernaryOperatorDiagnostic.bsl
@@ -0,0 +1,14 @@
+// Бессмысленные тернарники
+А = ?(Б = 1, Истина, Ложь);// прямой, фиксится в А = Б = 1;
+А = ?(Б = 0, False, True);// обратный, фиксится в А = НЕ (Б = 0);
+А = ?(Б = 1, True, Истина);
+А = ?(Б = 0, Ложь, False);
+А = ?(Б = 1, True, 1);
+А = ?(Б = 0, 0, False);
+А = ?(истина, 1, 0);
+А = ?(false, 0, 1);
+
+// валидный
+ОбластьМакета.Параметры.ДебетСубСчета = ОбластьМакета.Параметры.ДебетСубСчета
+ + ?(ПустаяСтрока(ОбластьМакета.Параметры.ДебетСубСчета), "", ", ")
+ + СчетДт;