-
Notifications
You must be signed in to change notification settings - Fork 121
Диагностика бессмысленного тернарного оператора #3629
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
53eac60
49a686a
bc42f49
8a3d6de
dd18c58
46783cd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| # Бесполезный тернарный оператор (UselessTernaryOperator) | ||
|
|
||
| <!-- Блоки выше заполняются автоматически, не трогать --> | ||
| ## Описание диагностики | ||
| Размещение в тернарном операторе булевых констант "Истина" или "Ложь" указывает на плохую продуманность кода. | ||
|
|
||
| ## Примеры | ||
| Бессмысленные операторы | ||
|
|
||
| ```Bsl | ||
| А = ?(Б = 1, Истина, Ложь); | ||
| ``` | ||
| ```BslUselessTernaryOperator | ||
| А = ?(Б = 0, False, True); | ||
| ``` | ||
|
|
||
| Подозрительные операторы | ||
|
|
||
| ```Bsl | ||
| А = ?(Б = 1, True, Истина); | ||
| ``` | ||
| ```Bsl | ||
| А = ?(Б = 0, 0, False); | ||
| ``` | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| # Useless ternary operator (UselessTernaryOperator) | ||
|
|
||
| <!-- Блоки выше заполняются автоматически, не трогать --> | ||
| ## Description | ||
| The placement of Boolean constants "True" or "False" in the ternary operator indicates poor code thoughtfulness. | ||
|
|
||
| ## Examples | ||
| Useless operators | ||
|
|
||
| ```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); | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,129 @@ | ||
| /* | ||
| * This file is a part of BSL Language Server. | ||
| * | ||
| * Copyright (c) 2018-2025 | ||
| * Alexey Sosnoviy <labotamy@gmail.com>, Nikita Fedkin <nixel2007@gmail.com> 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 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(); | ||
|
|
||
| if (exp != null && exp.size() >= 3) { | ||
|
Check warning on line 60 in src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic.java
|
||
| var condition = getBooleanToken(exp.get(0)); | ||
| var trueBranch = getBooleanToken(exp.get(1)); | ||
| var falseBranch = getBooleanToken(exp.get(2)); | ||
|
Check warning on line 63 in src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic.java
|
||
|
|
||
| if (condition != SKIPPED_RULE_INDEX) { | ||
| diagnosticStorage.addDiagnostic(ctx); | ||
| } else if (trueBranch == BSLParser.TRUE && falseBranch == BSLParser.FALSE) { | ||
| diagnosticStorage.addDiagnostic(ctx, DiagnosticStorage.createAdditionalData(exp.get(0).getText())); | ||
| } else if (trueBranch == BSLParser.FALSE && falseBranch == BSLParser.TRUE) { | ||
| diagnosticStorage.addDiagnostic(ctx, | ||
| DiagnosticStorage.createAdditionalData(getAdaptedText(exp.get(0).getText()))); | ||
| } else if (trueBranch != SKIPPED_RULE_INDEX || falseBranch != SKIPPED_RULE_INDEX) { | ||
|
Check failure on line 72 in src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic.java
|
||
| diagnosticStorage.addDiagnostic(ctx); | ||
| } | ||
| } | ||
|
|
||
| return super.visitTernaryOperator(ctx); | ||
| } | ||
|
|
||
| @Override | ||
| public List<CodeAction> getQuickFixes( | ||
| List<Diagnostic> diagnostics, | ||
| CodeActionParams params, | ||
| DocumentContext documentContext | ||
| ) { | ||
|
|
||
| List<TextEdit> textEdits = new ArrayList<>(); | ||
|
|
||
| diagnostics.forEach((Diagnostic diagnostic) -> { | ||
| var range = diagnostic.getRange(); | ||
| var data = diagnostic.getData(); | ||
| if (data instanceof DiagnosticStorage.DiagnosticAdditionalData additionalData) { | ||
| var textEdit = new TextEdit(range, additionalData.string()); | ||
| textEdits.add(textEdit); | ||
| } | ||
| }); | ||
|
|
||
| return CodeActionProvider.createCodeActions( | ||
| textEdits, | ||
| info.getResourceString("quickFixMessage"), | ||
| documentContext.getUri(), | ||
| diagnostics | ||
| ); | ||
|
|
||
| } | ||
|
|
||
| private String getAdaptedText(String text) { | ||
| return info.getResourceString("quickFixAdaptedText", text); | ||
| } | ||
|
|
||
| private int getBooleanToken(BSLParser.ExpressionContext expCtx) { | ||
|
Check warning on line 111 in src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic.java
|
||
|
|
||
| var tmpCtx = Optional.of(expCtx) | ||
| .filter(ctx -> ctx.children.size() == 1) | ||
| .map(ctx -> ctx.member(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); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| diagnosticMessage=Useless ternary operator | ||
| diagnosticName=Useless ternary operator | ||
| quickFixMessage=Fix some useless ternary operators | ||
| quickFixAdaptedText=NOT (%s) |
Uh oh!
There was an error while loading. Please reload this page.