From 4dab90486175eabf5e0c45b1f9d60a1bad89a4b7 Mon Sep 17 00:00:00 2001 From: beratagaca_9a91 Date: Thu, 14 Aug 2025 16:03:30 +0300 Subject: [PATCH] [LSPAPI]CodeFix_FixUnreachableCode Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICSPV9 Signed-off-by: beratagaca_9a91 --- ets2panda/lsp/BUILD.gn | 1 + ets2panda/lsp/CMakeLists.txt | 1 + .../register_code_fix/fix_unreachable_code.h | 39 ++ .../fix_unreachable_code.cpp | 147 +++++++ ets2panda/test/unit/lsp/CMakeLists.txt | 4 + .../unit/lsp/fix_unreachable_code_test.cpp | 394 ++++++++++++++++++ ets2panda/util/diagnostic/warning.yaml | 1 + 7 files changed, 587 insertions(+) create mode 100644 ets2panda/lsp/include/register_code_fix/fix_unreachable_code.h create mode 100644 ets2panda/lsp/src/register_code_fix/fix_unreachable_code.cpp create mode 100644 ets2panda/test/unit/lsp/fix_unreachable_code_test.cpp diff --git a/ets2panda/lsp/BUILD.gn b/ets2panda/lsp/BUILD.gn index 121f05f97d..0586ea4634 100644 --- a/ets2panda/lsp/BUILD.gn +++ b/ets2panda/lsp/BUILD.gn @@ -104,6 +104,7 @@ ohos_source_set("libes2panda_lsp_static") { "src/register_code_fix/fix_remove_override_modifier.cpp", "src/register_code_fix/fix_return_type_in_async_function.cpp", "src/register_code_fix/fix_spelling.cpp", + "src/register_code_fix/fix_unreachable_code.cpp", "src/register_code_fix/forgotten_this_property_access.cpp", "src/register_code_fix/import_fixes.cpp", "src/register_code_fix/remove_accidental_call_parentheses.cpp", diff --git a/ets2panda/lsp/CMakeLists.txt b/ets2panda/lsp/CMakeLists.txt index 384341c5a6..7f1a0ab759 100644 --- a/ets2panda/lsp/CMakeLists.txt +++ b/ets2panda/lsp/CMakeLists.txt @@ -131,6 +131,7 @@ set(ES2PANDA_LSP_SRC ./src/register_code_fix/fix_spelling.cpp ./src/register_code_fix/fix_class_incorrectly_implements_interface.cpp ./src/get_signature.cpp + ./src/register_code_fix/fix_unreachable_code.cpp ./src/get_name_or_dotted_name_span.cpp ./src/get_node.cpp ) diff --git a/ets2panda/lsp/include/register_code_fix/fix_unreachable_code.h b/ets2panda/lsp/include/register_code_fix/fix_unreachable_code.h new file mode 100644 index 0000000000..aa13f0f035 --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/fix_unreachable_code.h @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FIX_UNREACHABLE_CODE_H +#define FIX_UNREACHABLE_CODE_H + +#include + +#include "lsp/include/code_fixes/code_fix_types.h" +#include "lsp/include/services/text_change/change_tracker.h" +#include "lsp/include/types.h" + +namespace ark::es2panda::lsp { + +class FixUnreachableCode : public CodeFixRegistration { +public: + FixUnreachableCode(); + std::vector GetCodeActions(const CodeFixContext &context) override; + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; + +private: + void MakeChangeForUnreachableCode(ChangeTracker &changeTracker, es2panda_Context *context, size_t pos); + std::vector GetCodeActionsToRemoveUnreachableCode(const CodeFixContext &context); +}; + +} // namespace ark::es2panda::lsp +#endif diff --git a/ets2panda/lsp/src/register_code_fix/fix_unreachable_code.cpp b/ets2panda/lsp/src/register_code_fix/fix_unreachable_code.cpp new file mode 100644 index 0000000000..140abb0fd4 --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/fix_unreachable_code.cpp @@ -0,0 +1,147 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lsp/include/register_code_fix/fix_unreachable_code.h" +#include "generated/code_fix_register.h" +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/internal_api.h" + +namespace ark::es2panda::lsp { + +using codefixes::FIX_UNREACHABLE_CODE; + +FixUnreachableCode::FixUnreachableCode() +{ + auto errorCodes = FIX_UNREACHABLE_CODE.GetSupportedCodeNumbers(); + SetErrorCodes({errorCodes.begin(), errorCodes.end()}); + SetFixIds({FIX_UNREACHABLE_CODE.GetFixId().data()}); +} + +TextRange HandleUnreachableWhileOrIfStatement(ir::AstNode *statement) +{ + if (statement == nullptr) { + return {0, 0}; + } + + while (statement != nullptr) { + if (statement->IsWhileStatement() || statement->IsIfStatement()) { + break; + } + statement = statement->Parent(); + } + + if (statement == nullptr) { + return {0, 0}; + } + + if (!statement->IsWhileStatement() && !statement->IsIfStatement()) { + return {0, 0}; + } + + ir::Expression *expr = nullptr; + if (statement->IsWhileStatement()) { + expr = statement->AsWhileStatement()->Test(); + } else if (statement->IsIfStatement()) { + expr = statement->AsIfStatement()->Test(); + } + + if (expr == nullptr) { + return {0, 0}; + } + + if (expr->IsBooleanLiteral()) { + auto boolLiteral = expr->AsBooleanLiteral(); + if (!boolLiteral->Value()) { + return {statement->Start().index, statement->End().index}; + } + } else if (expr->IsNumberLiteral()) { + auto *numberLiteral = expr->AsNumberLiteral(); + if (numberLiteral->Number().IsZero()) { + return {statement->Start().index, statement->End().index}; + } + } + + return {0, 0}; +} + +void FixUnreachableCode::MakeChangeForUnreachableCode(ChangeTracker &changeTracker, es2panda_Context *context, + size_t pos) +{ + auto *token = GetTouchingToken(context, pos, false); + if (token == nullptr) { + return; + } + + while (token != nullptr && !token->IsStatement()) { + token = token->Parent(); + } + + if (token == nullptr) { + return; + } + + TextRange range = HandleUnreachableWhileOrIfStatement(token); + if (range.pos != range.end) { + auto ctx = reinterpret_cast(context); + changeTracker.DeleteRange(ctx->sourceFile, {range.pos, range.end}); + return; + } + + auto ctx = reinterpret_cast(context); + changeTracker.DeleteRange(ctx->sourceFile, {token->Start().index, token->End().index}); +} + +std::vector FixUnreachableCode::GetCodeActionsToRemoveUnreachableCode(const CodeFixContext &context) +{ + TextChangesContext textChangesContext = {context.host, context.formatContext, context.preferences}; + return ChangeTracker::With(textChangesContext, [&](ChangeTracker &tracker) { + MakeChangeForUnreachableCode(tracker, context.context, context.span.start); + }); +} + +std::vector FixUnreachableCode::GetCodeActions(const CodeFixContext &context) +{ + std::vector actions; + auto changes = GetCodeActionsToRemoveUnreachableCode(context); + if (!changes.empty()) { + CodeFixAction fix; + fix.fixName = FIX_UNREACHABLE_CODE.GetFixId().data(); + fix.description = "Remove unreachable code"; + fix.fixAllDescription = "Remove all unreachable code"; + fix.changes = changes; + fix.fixId = FIX_UNREACHABLE_CODE.GetFixId().data(); + actions.push_back(std::move(fix)); + } + + return actions; +} + +CombinedCodeActions FixUnreachableCode::GetAllCodeActions(const CodeFixAllContext &codeFixAllCtx) +{ + CodeFixProvider provider; + auto changes = provider.CodeFixAll( + codeFixAllCtx, GetErrorCodes(), [&](ChangeTracker &tracker, const DiagnosticWithLocation &diag) { + MakeChangeForUnreachableCode(tracker, codeFixAllCtx.context, diag.GetStart()); + }); + + CombinedCodeActions combined; + combined.changes = std::move(changes.changes); + combined.commands = std::move(changes.commands); + return combined; +} +// NOLINTNEXTLINE +AutoCodeFixRegister g_fixUnreachableCode(FIX_UNREACHABLE_CODE.GetFixId().data()); + +} // namespace ark::es2panda::lsp diff --git a/ets2panda/test/unit/lsp/CMakeLists.txt b/ets2panda/test/unit/lsp/CMakeLists.txt index a7968df400..63da3bb2b7 100644 --- a/ets2panda/test/unit/lsp/CMakeLists.txt +++ b/ets2panda/test/unit/lsp/CMakeLists.txt @@ -340,4 +340,8 @@ ets2panda_add_gtest(lsp_api_spelling_test CPP_SOURCES ets2panda_add_gtest(lsp_api_test_constructor_for_derived_need_super_call CPP_SOURCES constructor_for_derived_need_super_call_test.cpp +) + +ets2panda_add_gtest(lsp_api_fix_unreachable_code_test CPP_SOURCES + fix_unreachable_code_test.cpp ) \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/fix_unreachable_code_test.cpp b/ets2panda/test/unit/lsp/fix_unreachable_code_test.cpp new file mode 100644 index 0000000000..c3544bec8d --- /dev/null +++ b/ets2panda/test/unit/lsp/fix_unreachable_code_test.cpp @@ -0,0 +1,394 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lsp_api_test.h" +#include +#include +#include "lsp/include/api.h" +#include "lsp/include/cancellation_token.h" +#include "lsp/include/register_code_fix/fix_unreachable_code.h" + +namespace { + +using ark::es2panda::lsp::Initializer; +using ark::es2panda::lsp::codefixes::FIX_UNREACHABLE_CODE; + +constexpr std::string_view EXPECTED_FIX_NAME = FIX_UNREACHABLE_CODE.GetFixId(); +constexpr auto ERROR_CODES = FIX_UNREACHABLE_CODE.GetSupportedCodeNumbers(); +constexpr std::string_view EXPECTED_FIX_DESCRIPTION = "Remove unreachable code"; +constexpr int DEFAULT_THROTTLE = 20; + +class FixUnreachableCodeTests : public LSPAPITests { +public: + static ark::es2panda::lsp::CancellationToken CreateNonCancellationToken() + { + return ark::es2panda::lsp::CancellationToken(DEFAULT_THROTTLE, &GetNullHost()); + } + + static size_t LineColToPos(es2panda_Context *context, const size_t line, const size_t col) + { + auto ctx = reinterpret_cast(context); + auto index = ark::es2panda::lexer::LineIndex(ctx->parserProgram->SourceCode()); + return index.GetOffset(ark::es2panda::lexer::SourceLocation(line, col, ctx->parserProgram)); + } + + static void ValidateCodeFixActionInfo(const CodeFixActionInfo &info, const size_t expectedTextChangeStart, + const size_t expectedTextChangeLength, const std::string &expectedFileName) + { + ASSERT_EQ(info.fixName_, EXPECTED_FIX_NAME); + ASSERT_EQ(info.fixId_, EXPECTED_FIX_NAME); + ASSERT_EQ(info.description_, EXPECTED_FIX_DESCRIPTION); + ASSERT_EQ(info.changes_[0].fileName, expectedFileName); + ASSERT_EQ(info.changes_[0].textChanges[0].span.start, expectedTextChangeStart); + ASSERT_EQ(info.changes_[0].textChanges[0].span.length, expectedTextChangeLength); + ASSERT_EQ(info.changes_[0].textChanges[0].newText, ""); + } + +private: + class NullCancellationToken : public ark::es2panda::lsp::HostCancellationToken { + public: + bool IsCancellationRequested() override + { + return false; + } + }; + + static NullCancellationToken &GetNullHost() + { + static NullCancellationToken instance; + return instance; + } +}; + +TEST_F(FixUnreachableCodeTests, TestFixRemoveUnreachableAfterReturn1) +{ + std::vector fileNames = {"FixUnreachableCodeAfterReturn1.ets"}; + std::vector fileContents = { + R"( +function func(): boolean { +return false; +console.log("log"); +})"}; + + auto filePaths = CreateTempFile(fileNames, fileContents); + ASSERT_EQ(fileNames.size(), filePaths.size()); + + Initializer initializer; + auto *context = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + + const size_t start = LineColToPos(context, 4, 1); + const size_t length = 1; + const size_t expectedTextChangeStart = 42; + const size_t expectedTextChangeLength = 19; + const int expectedFixResultSize = 1; + + std::vector errorCodes(ERROR_CODES.begin(), ERROR_CODES.end()); + CodeFixOptions options = {CreateNonCancellationToken(), ark::es2panda::lsp::FormatCodeSettings(), {}}; + + auto fixResult = + ark::es2panda::lsp::GetCodeFixesAtPositionImpl(context, start, start + length, errorCodes, options); + ASSERT_EQ(fixResult.size(), expectedFixResultSize); + + ValidateCodeFixActionInfo(fixResult[0], expectedTextChangeStart, expectedTextChangeLength, filePaths[0]); + + initializer.DestroyContext(context); +} + +TEST_F(FixUnreachableCodeTests, TestFixRemoveUnreachableAfterReturn2) +{ + std::vector fileNames = {"FixUnreachableCodeAfterReturn2.ets"}; + std::vector fileContents = { + R"( +function func(): boolean { +return false; +if (true) { +console.log("log"); +} +})"}; + + auto filePaths = CreateTempFile(fileNames, fileContents); + ASSERT_EQ(fileNames.size(), filePaths.size()); + + Initializer initializer; + auto *context = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + + const size_t start = LineColToPos(context, 4, 1); + const size_t length = 1; + const size_t expectedTextChangeStart = 42; + const size_t expectedTextChangeLength = 33; + const int expectedFixResultSize = 1; + + std::vector errorCodes(ERROR_CODES.begin(), ERROR_CODES.end()); + CodeFixOptions options = {CreateNonCancellationToken(), ark::es2panda::lsp::FormatCodeSettings(), {}}; + + auto fixResult = + ark::es2panda::lsp::GetCodeFixesAtPositionImpl(context, start, start + length, errorCodes, options); + ASSERT_EQ(fixResult.size(), expectedFixResultSize); + + ValidateCodeFixActionInfo(fixResult[0], expectedTextChangeStart, expectedTextChangeLength, filePaths[0]); + + initializer.DestroyContext(context); +} + +TEST_F(FixUnreachableCodeTests, TestFixRemoveUnreachableAfterReturn3) +{ + std::vector fileNames = {"FixUnreachableCodeAfterReturn3.ets"}; + std::vector fileContents = { + R"( +function func(): void{ +if (true) { +return; +console.log("log"); +} +})"}; + + auto filePaths = CreateTempFile(fileNames, fileContents); + ASSERT_EQ(fileNames.size(), filePaths.size()); + + Initializer initializer; + auto *context = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + + const size_t start = LineColToPos(context, 5, 1); + const size_t length = 1; + const size_t expectedTextChangeStart = 44; + const size_t expectedTextChangeLength = 19; + const int expectedFixResultSize = 1; + + std::vector errorCodes(ERROR_CODES.begin(), ERROR_CODES.end()); + CodeFixOptions options = {CreateNonCancellationToken(), ark::es2panda::lsp::FormatCodeSettings(), {}}; + + auto fixResult = + ark::es2panda::lsp::GetCodeFixesAtPositionImpl(context, start, start + length, errorCodes, options); + ASSERT_EQ(fixResult.size(), expectedFixResultSize); + + ValidateCodeFixActionInfo(fixResult[0], expectedTextChangeStart, expectedTextChangeLength, filePaths[0]); + + initializer.DestroyContext(context); +} + +TEST_F(FixUnreachableCodeTests, TestFixRemoveUnreachableAfterWhileFalse1) +{ + std::vector fileNames = {"FixUnreachableCodeWhileFalse1.ets"}; + std::vector fileContents = { + R"( +function test(): void{ +while (false) { +console.log("log"); +} +} +)"}; + + auto filePaths = CreateTempFile(fileNames, fileContents); + ASSERT_EQ(fileNames.size(), filePaths.size()); + + Initializer initializer; + auto *context = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + + const size_t start = LineColToPos(context, 3, 13); + const size_t length = 1; + const size_t expectedTextChangeStart = 24; + const size_t expectedTextChangeLength = 37; + const int expectedFixResultSize = 1; + + std::vector errorCodes(ERROR_CODES.begin(), ERROR_CODES.end()); + CodeFixOptions options = {CreateNonCancellationToken(), ark::es2panda::lsp::FormatCodeSettings(), {}}; + + auto fixResult = + ark::es2panda::lsp::GetCodeFixesAtPositionImpl(context, start, start + length, errorCodes, options); + ASSERT_EQ(fixResult.size(), expectedFixResultSize); + + ValidateCodeFixActionInfo(fixResult[0], expectedTextChangeStart, expectedTextChangeLength, filePaths[0]); + + initializer.DestroyContext(context); +} + +TEST_F(FixUnreachableCodeTests, TestFixRemoveUnreachableAfterWhileFalse2) +{ + std::vector fileNames = {"FixUnreachableCodeWhileFalse2.ets"}; + std::vector fileContents = { + R"( +function test(): void{ +while (0) { +console.log("log"); +} +} +)"}; + + auto filePaths = CreateTempFile(fileNames, fileContents); + ASSERT_EQ(fileNames.size(), filePaths.size()); + + Initializer initializer; + auto *context = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + + const size_t start = LineColToPos(context, 3, 9); + const size_t length = 1; + const size_t expectedTextChangeStart = 24; + const size_t expectedTextChangeLength = 33; + const int expectedFixResultSize = 1; + + std::vector errorCodes(ERROR_CODES.begin(), ERROR_CODES.end()); + CodeFixOptions options = {CreateNonCancellationToken(), ark::es2panda::lsp::FormatCodeSettings(), {}}; + + auto fixResult = + ark::es2panda::lsp::GetCodeFixesAtPositionImpl(context, start, start + length, errorCodes, options); + ASSERT_EQ(fixResult.size(), expectedFixResultSize); + + ValidateCodeFixActionInfo(fixResult[0], expectedTextChangeStart, expectedTextChangeLength, filePaths[0]); + + initializer.DestroyContext(context); +} + +TEST_F(FixUnreachableCodeTests, TestFixRemoveUnreachableAfterWhileFalse3) +{ + std::vector fileNames = {"FixUnreachableCodeWhileFalse3.ets"}; + std::vector fileContents = { + R"( +function test():void { +const x = 0; +while (x) { +console.log("log"); +}})"}; + + auto filePaths = CreateTempFile(fileNames, fileContents); + ASSERT_EQ(fileNames.size(), filePaths.size()); + + Initializer initializer; + auto *context = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + + const size_t start = LineColToPos(context, 4, 9); + const size_t length = 1; + const size_t expectedTextChangeStart = 37; + const size_t expectedTextChangeLength = 33; + const int expectedFixResultSize = 1; + + std::vector errorCodes(ERROR_CODES.begin(), ERROR_CODES.end()); + CodeFixOptions options = {CreateNonCancellationToken(), ark::es2panda::lsp::FormatCodeSettings(), {}}; + + auto fixResult = + ark::es2panda::lsp::GetCodeFixesAtPositionImpl(context, start, start + length, errorCodes, options); + ASSERT_EQ(fixResult.size(), expectedFixResultSize); + + ValidateCodeFixActionInfo(fixResult[0], expectedTextChangeStart, expectedTextChangeLength, filePaths[0]); + + initializer.DestroyContext(context); +} + +TEST_F(FixUnreachableCodeTests, TestFixRemoveUnreachableAfterWhileFalse4) +{ + std::vector fileNames = {"FixUnreachableCodeWhileFalse4.ets"}; + std::vector fileContents = { + R"( +function test():void { +const x=5; +while (x!=5) { +console.log("log"); +}} +)"}; + + auto filePaths = CreateTempFile(fileNames, fileContents); + ASSERT_EQ(fileNames.size(), filePaths.size()); + + Initializer initializer; + auto *context = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + + const size_t start = LineColToPos(context, 4, 12); + const size_t length = 1; + const size_t expectedTextChangeStart = 35; + const size_t expectedTextChangeLength = 36; + const int expectedFixResultSize = 1; + + std::vector errorCodes(ERROR_CODES.begin(), ERROR_CODES.end()); + CodeFixOptions options = {CreateNonCancellationToken(), ark::es2panda::lsp::FormatCodeSettings(), {}}; + + auto fixResult = + ark::es2panda::lsp::GetCodeFixesAtPositionImpl(context, start, start + length, errorCodes, options); + ASSERT_EQ(fixResult.size(), expectedFixResultSize); + + ValidateCodeFixActionInfo(fixResult[0], expectedTextChangeStart, expectedTextChangeLength, filePaths[0]); + + initializer.DestroyContext(context); +} + +TEST_F(FixUnreachableCodeTests, TestFixRemoveUnreachableAfterWhileFalse5) +{ + std::vector fileNames = {"FixUnreachableCodeWhileFalse5.ets"}; + std::vector fileContents = { + R"( +function test():void { +while (1!=1) { +console.log("log"); +}} +)"}; + + auto filePaths = CreateTempFile(fileNames, fileContents); + ASSERT_EQ(fileNames.size(), filePaths.size()); + + Initializer initializer; + auto *context = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + + const size_t start = LineColToPos(context, 3, 12); + const size_t length = 1; + const size_t expectedTextChangeStart = 24; + const size_t expectedTextChangeLength = 36; + const int expectedFixResultSize = 1; + + std::vector errorCodes(ERROR_CODES.begin(), ERROR_CODES.end()); + CodeFixOptions options = {CreateNonCancellationToken(), ark::es2panda::lsp::FormatCodeSettings(), {}}; + + auto fixResult = + ark::es2panda::lsp::GetCodeFixesAtPositionImpl(context, start, start + length, errorCodes, options); + ASSERT_EQ(fixResult.size(), expectedFixResultSize); + + ValidateCodeFixActionInfo(fixResult[0], expectedTextChangeStart, expectedTextChangeLength, filePaths[0]); + + initializer.DestroyContext(context); +} + +TEST_F(FixUnreachableCodeTests, TestFixRemoveUnreachableAfterIfFalse) +{ + std::vector fileNames = {"FixUnreachableCodeIfFalse.ets"}; + std::vector fileContents = { + R"( +function nested(): void { +if (false) { +console.log("log"); +} +return; +})"}; + + auto filePaths = CreateTempFile(fileNames, fileContents); + ASSERT_EQ(fileNames.size(), filePaths.size()); + + Initializer initializer; + auto *context = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + const size_t start = LineColToPos(context, 4, 11); + const size_t length = 1; + const size_t expectedTextChangeStart = 27; + const size_t expectedTextChangeLength = 34; + const int expectedFixResultSize = 1; + + std::vector errorCodes(ERROR_CODES.begin(), ERROR_CODES.end()); + CodeFixOptions options = {CreateNonCancellationToken(), ark::es2panda::lsp::FormatCodeSettings(), {}}; + + auto fixResult = + ark::es2panda::lsp::GetCodeFixesAtPositionImpl(context, start, start + length, errorCodes, options); + ASSERT_EQ(fixResult.size(), expectedFixResultSize); + + ValidateCodeFixActionInfo(fixResult[0], expectedTextChangeStart, expectedTextChangeLength, filePaths[0]); + + initializer.DestroyContext(context); +} + +} // namespace \ No newline at end of file diff --git a/ets2panda/util/diagnostic/warning.yaml b/ets2panda/util/diagnostic/warning.yaml index 208822a6fa..49d33126ce 100644 --- a/ets2panda/util/diagnostic/warning.yaml +++ b/ets2panda/util/diagnostic/warning.yaml @@ -120,6 +120,7 @@ warning: - name: UNREACHABLE_STMT id: 26 message: "Unreachable statement." + code_fix_ids: [FixUnreachableCode] graveyard: - 10 -- Gitee