From 9ffc84b4af9005a3c8e0501081a1d96e9f87ad7e Mon Sep 17 00:00:00 2001 From: yunusemrekarakaya Date: Fri, 11 Jul 2025 11:03:50 +0300 Subject: [PATCH] [LSPAPI] ForgottenThisPropertyAccess Issue : https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICLIZ1 Signed-off-by: yunusemrekarakaya --- ets2panda/lsp/BUILD.gn | 6 +- ets2panda/lsp/CMakeLists.txt | 2 +- ...ess.h => forgotten_this_property_access.h} | 38 ++++-- .../forgetten_this_property_access.cpp | 51 -------- .../forgotten_this_property_access.cpp | 113 ++++++++++++++++++ ets2panda/test/unit/lsp/CMakeLists.txt | 4 + .../forgotten_this_property_access_test.cpp | 64 ++++++++++ ets2panda/util/diagnostic/semantic.yaml | 2 + 8 files changed, 217 insertions(+), 63 deletions(-) rename ets2panda/lsp/include/register_code_fix/{forgetten_this_property_access.h => forgotten_this_property_access.h} (54%) delete mode 100644 ets2panda/lsp/src/register_code_fix/forgetten_this_property_access.cpp create mode 100644 ets2panda/lsp/src/register_code_fix/forgotten_this_property_access.cpp create mode 100644 ets2panda/test/unit/lsp/forgotten_this_property_access_test.cpp diff --git a/ets2panda/lsp/BUILD.gn b/ets2panda/lsp/BUILD.gn index 78dec71308c..59b38a6e39a 100644 --- a/ets2panda/lsp/BUILD.gn +++ b/ets2panda/lsp/BUILD.gn @@ -81,15 +81,15 @@ ohos_source_set("libes2panda_lsp_static") { "src/refactors/refactor_types.cpp", "src/references.cpp", "src/register_code_fix/add_missing_declare_property.cpp", - "src/register_code_fix/fix_class_doesnt_implement_inherited_abstract_member.cpp", "src/register_code_fix/convert_const_to_let.cpp", + "src/register_code_fix/fix_class_doesnt_implement_inherited_abstract_member.cpp", "src/register_code_fix/fix_missing_call_parantheses.cpp", "src/register_code_fix/fix_nan_equality.cpp", - "src/register_code_fix/forgetten_this_property_access.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", - "src/rename.cpp", "src/register_code_fix/ui_plugin_suggest.cpp", + "src/rename.cpp", "src/script_element_kind.cpp", "src/services/services.cpp", "src/services/text_change/change_tracker.cpp", diff --git a/ets2panda/lsp/CMakeLists.txt b/ets2panda/lsp/CMakeLists.txt index bb3d59457c4..783c9b1bc56 100644 --- a/ets2panda/lsp/CMakeLists.txt +++ b/ets2panda/lsp/CMakeLists.txt @@ -115,7 +115,7 @@ set(ES2PANDA_LSP_SRC ./src/register_code_fix/convert_const_to_let.cpp ./src/register_code_fix/fix_missing_call_parantheses.cpp ./src/register_code_fix/fix_nan_equality.cpp - ./src/register_code_fix/forgetten_this_property_access.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 ./src/register_code_fix/ui_plugin_suggest.cpp diff --git a/ets2panda/lsp/include/register_code_fix/forgetten_this_property_access.h b/ets2panda/lsp/include/register_code_fix/forgotten_this_property_access.h similarity index 54% rename from ets2panda/lsp/include/register_code_fix/forgetten_this_property_access.h rename to ets2panda/lsp/include/register_code_fix/forgotten_this_property_access.h index d5ea48b3195..248d414efaf 100644 --- a/ets2panda/lsp/include/register_code_fix/forgetten_this_property_access.h +++ b/ets2panda/lsp/include/register_code_fix/forgotten_this_property_access.h @@ -2,9 +2,9 @@ * 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 + * You may obtain a copy of the License at* * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -16,22 +16,44 @@ #ifndef FORGOTTEN_THIS_PROPERTY_ACCESS_H #define FORGOTTEN_THIS_PROPERTY_ACCESS_H -#include -#include +#include +#include #include "lsp/include/code_fixes/code_fix_types.h" +#include "public/es2panda_lib.h" #include "lsp/include/services/text_change/change_tracker.h" -#include "lsp/include/types.h" namespace ark::es2panda::lsp { -class ForgettenThisPropertyAccess : public CodeFixRegistration { +class ForgottenThisPropertyAccess : public CodeFixRegistration { public: - ForgettenThisPropertyAccess(); + ForgottenThisPropertyAccess(); std::vector GetCodeActions(const CodeFixContext &context) override; CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; }; +struct Info { +private: + ark::es2panda::ir::AstNode *node_; + std::string className_; + +public: + Info(ark::es2panda::ir::AstNode *node, std::string className) : node_(node), className_(std::move(className)) {} + + ark::es2panda::ir::AstNode *GetNode() const + { + return node_; + } + const std::string &GetClassName() const + { + return className_; + } +}; + +Info GetInfoThisProp(es2panda_Context *context, size_t offset); +void DoChanges(es2panda_Context *context, ChangeTracker tracker); + } // namespace ark::es2panda::lsp -#endif + +#endif // FORGOTTEN_THIS_PROPERTY_ACCESS_H \ No newline at end of file diff --git a/ets2panda/lsp/src/register_code_fix/forgetten_this_property_access.cpp b/ets2panda/lsp/src/register_code_fix/forgetten_this_property_access.cpp deleted file mode 100644 index c1bda5b238a..00000000000 --- a/ets2panda/lsp/src/register_code_fix/forgetten_this_property_access.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/** - * 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/forgetten_this_property_access.h" -#include -#include -#include "lsp/include/code_fix_provider.h" -#include "lsp/include/internal_api.h" - -namespace ark::es2panda::lsp { - -const int G_FORGETTEN_THIS_PROPERTY_ACCESS_CODE = 1004; // change this to the error code you want to handle - -ForgettenThisPropertyAccess::ForgettenThisPropertyAccess() -{ - const char *forgottenThisPropertAccesId = "ForgettenThisPropertyAccess"; - SetErrorCodes({G_FORGETTEN_THIS_PROPERTY_ACCESS_CODE}); // change this to the error code you want to handle - SetFixIds({forgottenThisPropertAccesId}); -} - -std::vector ForgettenThisPropertyAccess::GetCodeActions(const CodeFixContext &context) -{ - std::vector returnedActions; - if (context.errorCode == G_FORGETTEN_THIS_PROPERTY_ACCESS_CODE) { - } - return returnedActions; -} - -CombinedCodeActions ForgettenThisPropertyAccess::GetAllCodeActions(const CodeFixAllContext &codeFixAll) -{ - CombinedCodeActions combinedCodeActions; - if (codeFixAll.fixId == "ForgettenThisPropertyAccess") { - } - - return combinedCodeActions; -} -// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) -AutoCodeFixRegister g_forgettenThisPropertyAccess("ForgettenThisPropertyAccess"); -} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/register_code_fix/forgotten_this_property_access.cpp b/ets2panda/lsp/src/register_code_fix/forgotten_this_property_access.cpp new file mode 100644 index 00000000000..abad90b3498 --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/forgotten_this_property_access.cpp @@ -0,0 +1,113 @@ +/** + * 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 "register_code_fix/forgotten_this_property_access.h" +#include +#include "code_fix_provider.h" +#include "generated/code_fix_register.h" + +namespace ark::es2panda::lsp { +using codefixes::FORGOTTEN_THIS_PROPERTY_ACCESS; + +ForgottenThisPropertyAccess::ForgottenThisPropertyAccess() +{ + auto errorCodes = FORGOTTEN_THIS_PROPERTY_ACCESS.GetSupportedCodeNumbers(); + SetErrorCodes({errorCodes.begin(), errorCodes.end()}); // change this to the error code you want to handle + SetFixIds({FORGOTTEN_THIS_PROPERTY_ACCESS.GetFixId().data()}); +} + +Info GetInfoThisProp(es2panda_Context *context, size_t offset) +{ + ir::AstNode *node = ark::es2panda::lsp::GetTouchingToken(context, offset, false); + std::string className; + if (node == nullptr) { + return {nullptr, ""}; + } + if (node->IsIdentifier()) { + className = node->AsIdentifier()->Name().Utf8(); + } + Info info(node, className); + return info; +} + +void DoChanges(es2panda_Context *context, ChangeTracker tracker) +{ + auto ctx = reinterpret_cast(context); + const auto impl = es2panda_GetImpl(ES2PANDA_LIB_VERSION); + + const auto &diagnostics = + ctx->diagnosticEngine->GetDiagnosticStorage(ark::es2panda::util::DiagnosticType::SEMANTIC); + + for (const auto &diagnostic : diagnostics) { + auto index = ark::es2panda::lexer::LineIndex(ctx->parserProgram->SourceCode()); + auto offset = index.GetOffset( + ark::es2panda::lexer::SourceLocation(diagnostic->Line(), diagnostic->Offset(), ctx->parserProgram)); + auto node = ark::es2panda::lsp::GetTouchingToken(context, offset, false); + es2panda_AstNode *thisExpr = impl->CreateThisExpression(context); + es2panda_AstNode *memberExpr = + impl->CreateMemberExpression(context, thisExpr, reinterpret_cast(node), + MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, false, false); + impl->AstNodeSetParent(context, thisExpr, memberExpr); + impl->AstNodeSetParent(context, reinterpret_cast(node), memberExpr); + auto memNode = reinterpret_cast(memberExpr); + if (memNode == nullptr) { + continue; + } + tracker.ReplaceNode(context, node, memNode, {}); + } +} + +std::vector ForgottenThisPropertyAccess::GetCodeActions(const CodeFixContext &context) +{ + std::vector returnedActions; + + const auto info = GetInfoThisProp(context.context, context.span.start); + if (info.GetNode() == nullptr) { + return {}; + } + TextChangesContext textChangesContext {context.host, context.formatContext, context.preferences}; + const auto changes = + ChangeTracker::With(textChangesContext, [&](ChangeTracker &tracker) { DoChanges(context.context, tracker); }); + std::vector actions; + CodeFixAction action; + action.fixName = FORGOTTEN_THIS_PROPERTY_ACCESS.GetFixId().data(); + action.description = "Add 'this.' to property access"; + action.fixId = FORGOTTEN_THIS_PROPERTY_ACCESS.GetFixId().data(); + action.changes.insert(action.changes.end(), changes.begin(), changes.end()); + action.fixAllDescription = "Add 'this.' to all property accesses in the file"; + returnedActions.push_back(action); + return returnedActions; +} + +CombinedCodeActions ForgottenThisPropertyAccess::GetAllCodeActions(const CodeFixAllContext &codeFixAll) +{ + CodeFixProvider provider; + const auto changes = provider.CodeFixAll(codeFixAll, GetErrorCodes(), + [&](ChangeTracker &tracker, const DiagnosticWithLocation &diag) { + auto info = GetInfoThisProp(codeFixAll.context, diag.GetStart()); + if (info.GetNode() != nullptr) { + DoChanges(codeFixAll.context, tracker); + } + }); + + CombinedCodeActions combined; + combined.changes = changes.changes; + combined.commands = changes.commands; + return combined; +} +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoCodeFixRegister g_forgottenThisPropertyAccess("ForgottenThisPropertyAccess"); + +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/CMakeLists.txt b/ets2panda/test/unit/lsp/CMakeLists.txt index 06df7356e7c..3583b874042 100644 --- a/ets2panda/test/unit/lsp/CMakeLists.txt +++ b/ets2panda/test/unit/lsp/CMakeLists.txt @@ -259,6 +259,10 @@ ets2panda_add_gtest(lsp_api_test_fix_convert_const_to_let CPP_SOURCES fix_convert_const_to_let_test.cpp ) +ets2panda_add_gtest(lsp_api_test_forgotten_this_property_access CPP_SOURCES + forgotten_this_property_access_test.cpp +) + ets2panda_add_gtest(lsp_api_test_remove_accidental_call_parentheses CPP_SOURCES remove_accidental_call_parentheses_test.cpp ) \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/forgotten_this_property_access_test.cpp b/ets2panda/test/unit/lsp/forgotten_this_property_access_test.cpp new file mode 100644 index 00000000000..f96700a94a7 --- /dev/null +++ b/ets2panda/test/unit/lsp/forgotten_this_property_access_test.cpp @@ -0,0 +1,64 @@ +/** + * 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 "gtest/gtest.h" +#include "lsp_api_test.h" +#include +#include +#include "lsp/include/register_code_fix/forgotten_this_property_access.h" + +namespace { +class ForgottenThisPropertyAccessTests : public LSPAPITests {}; + +TEST_F(ForgottenThisPropertyAccessTests, ForgottenThisPropertyAccessTests_GetInfo) +{ + const char *source = R"(class Person { +name = "Alice"; +greet() { +console.log(name); +} +} + )"; + ark::es2panda::lsp::Initializer initializer = ark::es2panda::lsp::Initializer(); + es2panda_Context *context = + initializer.CreateContext("ForgottenThisPropertyAccessTests_GetInfo.ets", ES2PANDA_STATE_CHECKED, source); + + auto ctx = reinterpret_cast(context); + const auto impl = es2panda_GetImpl(ES2PANDA_LIB_VERSION); + + const auto &diagnostics = + ctx->diagnosticEngine->GetDiagnosticStorage(ark::es2panda::util::DiagnosticType::SEMANTIC); + + for (const auto &diagnostic : diagnostics) { + auto index = ark::es2panda::lexer::LineIndex(ctx->parserProgram->SourceCode()); + auto offset = index.GetOffset( + ark::es2panda::lexer::SourceLocation(diagnostic->Line(), diagnostic->Offset(), ctx->parserProgram)); + auto node = ark::es2panda::lsp::GetTouchingToken(context, offset, false); + es2panda_AstNode *thisExpr = impl->CreateThisExpression(context); + es2panda_AstNode *memberExpr = + impl->CreateMemberExpression(context, thisExpr, reinterpret_cast(node), + MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, false, false); + impl->AstNodeSetParent(context, thisExpr, memberExpr); + impl->AstNodeSetParent(context, reinterpret_cast(node), memberExpr); + auto memNode = reinterpret_cast(memberExpr); + if (memNode == nullptr) { + continue; + } + ASSERT_EQ(memNode->DumpEtsSrc(), "this.name"); + } + + initializer.DestroyContext(context); +} + +} // namespace \ No newline at end of file diff --git a/ets2panda/util/diagnostic/semantic.yaml b/ets2panda/util/diagnostic/semantic.yaml index aad4b5292a7..6e8226fa771 100644 --- a/ets2panda/util/diagnostic/semantic.yaml +++ b/ets2panda/util/diagnostic/semantic.yaml @@ -1202,6 +1202,8 @@ semantic: - name: PROP_ACCESS_WITHOUT_THIS id: 145 message: "Property '{}' must be accessed through 'this'" + code_fix_ids: [ForgottenThisPropertyAccess] + - name: PROP_ASSIGN_TO_NUMERIC_INDEX id: 324 -- Gitee