From 671de9830972e856a67ed1ae52a4c724346ba086 Mon Sep 17 00:00:00 2001 From: yp9522 Date: Wed, 20 Aug 2025 15:03:30 +0800 Subject: [PATCH] add VariableDeclarator&Declaration https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICTUI7 Signed-off-by: yp9522 --- ets2panda/lsp/include/node_matchers.h | 8 + ets2panda/lsp/src/node_matchers.cpp | 138 ++++++++++++++- ets2panda/test/unit/lsp/CMakeLists.txt | 32 ++++ .../get_node_annotation_declaration_test.cpp | 157 +++++++++++++++++ .../lsp/get_node_annotation_usage_test.cpp | 162 +++++++++++++++++ .../lsp/get_node_await_expression_test.cpp | 108 ++++++++++++ .../unit/lsp/get_node_bigInt_literal_test.cpp | 116 ++++++++++++ .../lsp/get_node_class_declaration_test.cpp | 158 +++++++++++++++++ .../lsp/get_node_class_static_block_test.cpp | 165 ++++++++++++++++++ .../unit/lsp/get_node_declaration_test.cpp | 118 +++++++++++++ .../unit/lsp/get_node_declarator_test.cpp | 124 +++++++++++++ 11 files changed, 1283 insertions(+), 3 deletions(-) mode change 100755 => 100644 ets2panda/lsp/src/node_matchers.cpp create mode 100644 ets2panda/test/unit/lsp/get_node_annotation_declaration_test.cpp create mode 100644 ets2panda/test/unit/lsp/get_node_annotation_usage_test.cpp create mode 100644 ets2panda/test/unit/lsp/get_node_await_expression_test.cpp create mode 100644 ets2panda/test/unit/lsp/get_node_bigInt_literal_test.cpp create mode 100644 ets2panda/test/unit/lsp/get_node_class_declaration_test.cpp create mode 100644 ets2panda/test/unit/lsp/get_node_class_static_block_test.cpp create mode 100644 ets2panda/test/unit/lsp/get_node_declaration_test.cpp create mode 100644 ets2panda/test/unit/lsp/get_node_declarator_test.cpp diff --git a/ets2panda/lsp/include/node_matchers.h b/ets2panda/lsp/include/node_matchers.h index a57247b70c..3b91017309 100755 --- a/ets2panda/lsp/include/node_matchers.h +++ b/ets2panda/lsp/include/node_matchers.h @@ -37,6 +37,14 @@ bool MatchTSTypeAliasDeclaration(ir::AstNode *childNode, const NodeInfo *info); bool MatchExportSpecifier(ir::AstNode *childNode, const NodeInfo *info); bool MatchMemberExpression(ir::AstNode *childNode, const NodeInfo *info); bool MatchTSClassImplements(ir::AstNode *childNode, const NodeInfo *info); +bool MatchVariableDeclarator(ir::AstNode *childNode, const NodeInfo *info); +bool MatchVariableDeclaration(ir::AstNode *childNode, const NodeInfo *info); +bool MatchClassDeclaration(ir::AstNode *childNode, const NodeInfo *info); +bool MatchClassStaticBlock(ir::AstNode *childNode, const NodeInfo *info); +bool MatchAnnotationDeclaration(ir::AstNode *childNode, const NodeInfo *info); +bool MatchAnnotationUsage(ir::AstNode *childNode, const NodeInfo *info); +bool MatchAwaitExpression(ir::AstNode *childNode, const NodeInfo *info); +bool MatchBigIntLiteral(ir::AstNode *childNode, const NodeInfo *info); ir::AstNode *ExtractExportSpecifierIdentifier(ir::AstNode *node, const NodeInfo *info); ir::AstNode *ExtractTSClassImplementsIdentifier(ir::AstNode *node, const NodeInfo *info); diff --git a/ets2panda/lsp/src/node_matchers.cpp b/ets2panda/lsp/src/node_matchers.cpp old mode 100755 new mode 100644 index f50d62cd0e..f992992b4d --- a/ets2panda/lsp/src/node_matchers.cpp +++ b/ets2panda/lsp/src/node_matchers.cpp @@ -18,6 +18,8 @@ #include "public/es2panda_lib.h" #include "public/public.h" #include "ir/ets/etsReExportDeclaration.h" +#include "ir/statements/annotationDeclaration.h" +#include "ir/statements/annotationUsage.h" namespace ark::es2panda::lsp { @@ -102,6 +104,72 @@ bool MatchTSClassImplements(ir::AstNode *childNode, const NodeInfo *info) return std::string(dd->GetIdent()->Name()) == info->name; } +bool MatchVariableDeclarator(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsVariableDeclarator() && + std::string(childNode->AsVariableDeclarator()->Id()->AsIdentifier()->Name()) == info->name; +} + +bool MatchVariableDeclaration(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsVariableDeclaration() && + std::string(childNode->AsVariableDeclaration()->Declarators()[0]->Id()->AsIdentifier()->Name()) == + info->name; +} + +bool MatchClassStaticBlock(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsClassStaticBlock()) { + return false; + } + auto parent = childNode->AsClassStaticBlock()->Parent(); + return parent->IsClassDefinition() && std::string(parent->AsClassDefinition()->Ident()->Name()) == info->name; +} + +bool MatchClassDeclaration(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsClassDeclaration() && + std::string(childNode->AsClassDeclaration()->Definition()->Ident()->Name()) == info->name; +} + +bool MatchAnnotationDeclaration(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsAnnotationDeclaration() && + std::string(childNode->AsAnnotationDeclaration()->GetBaseName()->Name()) == info->name; +} + +bool MatchAnnotationUsage(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsAnnotationUsage() && + std::string(childNode->AsAnnotationUsage()->GetBaseName()->Name()) == info->name; +} + +bool MatchAwaitExpression(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsAwaitExpression()) { + return false; + } + auto awaitExpr = childNode->AsAwaitExpression(); + if (awaitExpr && awaitExpr->Argument() && awaitExpr->Argument()->IsIdentifier()) { + auto identifier = awaitExpr->Argument()->AsIdentifier(); + return identifier && std::string(identifier->Name()) == info->name; + } + return false; +} + +bool MatchBigIntLiteral(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsBigIntLiteral()) { + return false; + } + std::string bigIntLiteral = std::string(childNode->AsBigIntLiteral()->Str()); + if (childNode->Parent()->IsUnaryExpression()) { + bigIntLiteral.insert(0, lexer::TokenToString(childNode->Parent()->AsUnaryExpression()->OperatorType())); + return bigIntLiteral == info->name; + } + return bigIntLiteral == info->name; +} + ir::AstNode *ExtractExportSpecifierIdentifier(ir::AstNode *node, const NodeInfo *info) { if (!node->IsETSReExportDeclaration()) { @@ -149,6 +217,36 @@ ir::AstNode *ExtractTSClassImplementsIdentifier(ir::AstNode *node, const NodeInf return node; } +ir::AstNode *ExtractClassStaticBlockIdentifier(ir::AstNode *node, const NodeInfo *info) +{ + if (!node->IsClassStaticBlock()) { + return node; + } + + auto parent = node->AsClassStaticBlock()->Parent(); + if (parent == nullptr) { + return node; + } + + if (parent->IsClassDefinition() && std::string(parent->AsClassDefinition()->Ident()->Name()) == info->name) { + return node->AsClassStaticBlock()->Id(); + } + + return node; +} + +ir::AstNode *ExtractAwaitExpressionIdentifier(ir::AstNode *node, const NodeInfo *) +{ + if (!node->IsAwaitExpression()) { + return node; + } + + if (node->AsAwaitExpression()->Argument() && node->AsAwaitExpression()->Argument()->IsIdentifier()) { + return const_cast(node->AsAwaitExpression()->Argument()->AsIdentifier()); + } + return node; +} + const std::unordered_map nodeExtractors = { {ir::AstNodeType::CLASS_DEFINITION, [](ir::AstNode *node, const NodeInfo *) { @@ -188,9 +286,35 @@ const std::unordered_map nodeExtractors = { [](ir::AstNode *node, const NodeInfo *) { return node->IsMemberExpression() ? node->AsMemberExpression()->Property()->AsIdentifier() : node; }}, + {ir::AstNodeType::VARIABLE_DECLARATOR, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsVariableDeclarator() ? node->AsVariableDeclarator()->Id()->AsIdentifier() : node; + }}, {ir::AstNodeType::TS_CLASS_IMPLEMENTS, - [](ir::AstNode *node, const NodeInfo *info) { return ExtractTSClassImplementsIdentifier(node, info); }}}; - + [](ir::AstNode *node, const NodeInfo *info) { return ExtractTSClassImplementsIdentifier(node, info); }}, + {ir::AstNodeType::VARIABLE_DECLARATION, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsVariableDeclaration() ? node->AsVariableDeclaration()->Declarators()[0]->Id()->AsIdentifier() + : node; + }}, + {ir::AstNodeType::CLASS_DECLARATION, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsClassDeclaration() ? node->AsClassDeclaration()->Definition()->Ident() : node; + }}, + {ir::AstNodeType::CLASS_STATIC_BLOCK, + [](ir::AstNode *node, const NodeInfo *info) { return ExtractClassStaticBlockIdentifier(node, info); }}, + {ir::AstNodeType::ANNOTATION_DECLARATION, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsAnnotationDeclaration() ? node->AsAnnotationDeclaration()->GetBaseName() : node; + }}, + {ir::AstNodeType::ANNOTATION_USAGE, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsAnnotationUsage() ? node->AsAnnotationUsage()->GetBaseName() : node; + }}, + {ir::AstNodeType::AWAIT_EXPRESSION, + [](ir::AstNode *node, const NodeInfo *info) { return ExtractAwaitExpressionIdentifier(node, info); }}, + {ir::AstNodeType::BIGINT_LITERAL, + [](ir::AstNode *node, const NodeInfo *) { return node->IsBigIntLiteral() ? node->AsBigIntLiteral() : node; }}}; ir::AstNode *ExtractIdentifierFromNode(ir::AstNode *node, const NodeInfo *info) { if (!node) @@ -215,5 +339,13 @@ const std::unordered_map nodeMatchers = { {ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION, MatchTSTypeAliasDeclaration}, {ir::AstNodeType::EXPORT_SPECIFIER, MatchExportSpecifier}, {ir::AstNodeType::MEMBER_EXPRESSION, MatchMemberExpression}, - {ir::AstNodeType::TS_CLASS_IMPLEMENTS, MatchTSClassImplements}}; + {ir::AstNodeType::TS_CLASS_IMPLEMENTS, MatchTSClassImplements}, + {ir::AstNodeType::VARIABLE_DECLARATOR, MatchVariableDeclarator}, + {ir::AstNodeType::VARIABLE_DECLARATION, MatchVariableDeclaration}, + {ir::AstNodeType::CLASS_DECLARATION, MatchClassDeclaration}, + {ir::AstNodeType::CLASS_STATIC_BLOCK, MatchClassStaticBlock}, + {ir::AstNodeType::ANNOTATION_DECLARATION, MatchAnnotationDeclaration}, + {ir::AstNodeType::ANNOTATION_USAGE, MatchAnnotationUsage}, + {ir::AstNodeType::AWAIT_EXPRESSION, MatchAwaitExpression}, + {ir::AstNodeType::BIGINT_LITERAL, MatchBigIntLiteral}}; } // 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 d896777b56..6c31b6a862 100644 --- a/ets2panda/test/unit/lsp/CMakeLists.txt +++ b/ets2panda/test/unit/lsp/CMakeLists.txt @@ -381,3 +381,35 @@ ets2panda_add_gtest(lsp_api_get_node_export_test CPP_SOURCES ets2panda_add_gtest(lsp_api_get_node_ts_class_Implements_test CPP_SOURCES get_node_ts_class_Implements_test.cpp ) + +ets2panda_add_gtest(lsp_api_get_node_declaration_test CPP_SOURCES + get_node_declaration_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_declarator_test CPP_SOURCES + get_node_declarator_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_class_declaration_test CPP_SOURCES + get_node_class_declaration_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_class_static_block_test CPP_SOURCES + get_node_class_static_block_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_annotation_declaration_test CPP_SOURCES + get_node_annotation_declaration_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_annotation_usage_test CPP_SOURCES + get_node_annotation_usage_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_await_expression_test CPP_SOURCES + get_node_await_expression_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_bigInt_literal_test CPP_SOURCES + get_node_bigInt_literal_test.cpp +) \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_annotation_declaration_test.cpp b/ets2panda/test/unit/lsp/get_node_annotation_declaration_test.cpp new file mode 100644 index 0000000000..b7ec372e7c --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_annotation_declaration_test.cpp @@ -0,0 +1,157 @@ +/** + * 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 "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "ir/ets/etsReExportDeclaration.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetAnnotationDeclarationTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( + // 定义注解 + @interface Validate { + } + + @interface Log { + level: string; + } + + @interface Component { + name: string; + version: number; + } + + @interface Deprecated { + } + + // 使用注解的类和方法 + @Component({name: "Service", version: 1}) + class Service { + @Validate + @Log({level: 'info'}) + doSomething() { + // ... + } + + @Deprecated + oldMethod() { + // ... + } + } + )"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + + static void GenerateContexts(Initializer &initializer) + { + contexts_ = + initializer.CreateContext("GetAnnotationDeclarationTest.ets", ES2PANDA_STATE_CHECKED, sourceCode_.c_str()); + } + + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetAnnotationDeclarationTests, GetSimpleAnnotationDeclaration) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string annotationName = "Validate"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {annotationName, ark::es2panda::ir::AstNodeType::ANNOTATION_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(annotationName), std::string::npos); +} + +TEST_F(LspGetAnnotationDeclarationTests, GetAnnotationDeclarationWithProperties) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string annotationName = "Log"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {annotationName, ark::es2panda::ir::AstNodeType::ANNOTATION_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(annotationName), std::string::npos); +} + +TEST_F(LspGetAnnotationDeclarationTests, GetComplexAnnotationDeclaration) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string annotationName = "Component"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {annotationName, ark::es2panda::ir::AstNodeType::ANNOTATION_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(annotationName), std::string::npos); +} + +TEST_F(LspGetAnnotationDeclarationTests, GetAnotherSimpleAnnotationDeclaration) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string annotationName = "Deprecated"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {annotationName, ark::es2panda::ir::AstNodeType::ANNOTATION_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(annotationName), std::string::npos); +} + +TEST_F(LspGetAnnotationDeclarationTests, GetNonExistentAnnotationDeclaration) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string annotationName = "NonExistent"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {annotationName, ark::es2panda::ir::AstNodeType::ANNOTATION_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + ASSERT_EQ(res.start, static_cast(0)); + ASSERT_EQ(res.length, static_cast(0)); +} +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_annotation_usage_test.cpp b/ets2panda/test/unit/lsp/get_node_annotation_usage_test.cpp new file mode 100644 index 0000000000..288415314a --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_annotation_usage_test.cpp @@ -0,0 +1,162 @@ +/** + * 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 "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "ir/ets/etsReExportDeclaration.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetAnnotationUsageTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( + // 定义注解 + @interface Injectable { + } + + @interface Component { + name: string; + } + + @interface Log { + level: string; + } + + @interface Deprecated { + } + + // 使用注解的类和方法(不定义实际的函数) + @Injectable + class DatabaseService { + connect() { + return "Connected to DB"; + } + } + + @Component({name: "test"}) + class TestComponent { + @Log({level: "info"}) + doSomething() { + // ... + } + + @Deprecated + oldMethod() { + // ... + } + } + )"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + + static void GenerateContexts(Initializer &initializer) + { + contexts_ = + initializer.CreateContext("GetAnnotationUsageTest.ets", ES2PANDA_STATE_CHECKED, sourceCode_.c_str()); + } + + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetAnnotationUsageTests, GetClassAnnotationUsage) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string annotationName = "Injectable"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {annotationName, ark::es2panda::ir::AstNodeType::ANNOTATION_USAGE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(annotationName), std::string::npos); +} + +TEST_F(LspGetAnnotationUsageTests, GetClassAnnotationUsageWithProperties) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string annotationName = "Component"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {annotationName, ark::es2panda::ir::AstNodeType::ANNOTATION_USAGE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(annotationName), std::string::npos); +} + +TEST_F(LspGetAnnotationUsageTests, GetMethodAnnotationUsage) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string annotationName = "Log"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {annotationName, ark::es2panda::ir::AstNodeType::ANNOTATION_USAGE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(annotationName), std::string::npos); +} + +TEST_F(LspGetAnnotationUsageTests, GetAnotherMethodAnnotationUsage) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string annotationName = "Deprecated"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {annotationName, ark::es2panda::ir::AstNodeType::ANNOTATION_USAGE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(annotationName), std::string::npos); +} + +TEST_F(LspGetAnnotationUsageTests, GetNonExistentAnnotationUsage) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string annotationName = "NonExistent"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {annotationName, ark::es2panda::ir::AstNodeType::ANNOTATION_USAGE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + ASSERT_EQ(res.start, static_cast(0)); + ASSERT_EQ(res.length, static_cast(0)); +} +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_await_expression_test.cpp b/ets2panda/test/unit/lsp/get_node_await_expression_test.cpp new file mode 100644 index 0000000000..06b88b73f2 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_await_expression_test.cpp @@ -0,0 +1,108 @@ +/** + * 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 "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "ir/ets/etsReExportDeclaration.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetAwaitExpressionTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( +async function foo1(p: Promise>): Promise { + let result: string = await p; +} + +async function foo2(): Promise { + let x: Promise = Promise.resolve(10.0); + let result2: number = await x; +} + )"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + + static void GenerateContexts(Initializer &initializer) + { + contexts_ = + initializer.CreateContext("GetAwaitExpressionTest.ets", ES2PANDA_STATE_CHECKED, sourceCode_.c_str()); + } + + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetAwaitExpressionTests, GetAnyAwaitExpression) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "p"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::AWAIT_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find("p"), std::string::npos); +} + +TEST_F(LspGetAwaitExpressionTests, GetAwaitExpressionByAnotherParameterName) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string paramName = "x"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {paramName, ark::es2panda::ir::AstNodeType::AWAIT_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(paramName), std::string::npos); +} + +TEST_F(LspGetAwaitExpressionTests, GetNonExistentAwaitExpression) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string paramName = "nonExistent"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {paramName, ark::es2panda::ir::AstNodeType::AWAIT_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + ASSERT_EQ(res.start, static_cast(0)); + ASSERT_EQ(res.length, static_cast(0)); +} + +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_bigInt_literal_test.cpp b/ets2panda/test/unit/lsp/get_node_bigInt_literal_test.cpp new file mode 100644 index 0000000000..44c0504a8e --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_bigInt_literal_test.cpp @@ -0,0 +1,116 @@ +/** + * 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 "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "ir/ets/etsReExportDeclaration.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetBigIntLiteralTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( +let a = 153n; // bigint literal +let b = 1_153n; // bigint literal +let c = -153n; // negative bigint literal + )"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + + static void GenerateContexts(Initializer &initializer) + { + contexts_ = initializer.CreateContext("GetBigIntLiteralTest.ets", ES2PANDA_STATE_CHECKED, sourceCode_.c_str()); + } + + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetBigIntLiteralTests, GetBigIntLiteralByValue153n) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string literalValue = "153"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {literalValue, ark::es2panda::ir::AstNodeType::BIGINT_LITERAL}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find("153"), std::string::npos); +} + +TEST_F(LspGetBigIntLiteralTests, GetBigIntLiteralByValue1153n) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string literalValue = "1_153"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {literalValue, ark::es2panda::ir::AstNodeType::BIGINT_LITERAL}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find("1_153"), std::string::npos); +} + +TEST_F(LspGetBigIntLiteralTests, GetBigIntLiteralByValueNegative153n) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string literalValue = "-153"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {literalValue, ark::es2panda::ir::AstNodeType::BIGINT_LITERAL}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find("153"), std::string::npos); +} + +TEST_F(LspGetBigIntLiteralTests, GetNonExistentBigIntLiteral) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string literalValue = "999"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {literalValue, ark::es2panda::ir::AstNodeType::BIGINT_LITERAL}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + ASSERT_EQ(res.start, static_cast(0)); + ASSERT_EQ(res.length, static_cast(0)); +} + +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_class_declaration_test.cpp b/ets2panda/test/unit/lsp/get_node_class_declaration_test.cpp new file mode 100644 index 0000000000..a14adcc1c3 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_class_declaration_test.cpp @@ -0,0 +1,158 @@ +/** + * 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 "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "ir/ets/etsReExportDeclaration.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetClassDeclarationTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( + class Base { + prop1: number = 1; + } + + class Derived extends Base { + prop2: string = "test"; + } + + class StaticClass { + static staticMethod() {} + } + + class PrivateClass { + private privProp: boolean = true; + } + + class EmptyClass {} + )"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + + static void GenerateContexts(Initializer &initializer) + { + contexts_ = + initializer.CreateContext("GetClassDeclarationTest.ets", ES2PANDA_STATE_CHECKED, sourceCode_.c_str()); + } + + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetClassDeclarationTests, GetBaseClassDeclaration) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string className = "Base"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {className, ark::es2panda::ir::AstNodeType::CLASS_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(className), std::string::npos); +} + +TEST_F(LspGetClassDeclarationTests, GetDerivedClassDeclaration) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string className = "Derived"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {className, ark::es2panda::ir::AstNodeType::CLASS_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(className), std::string::npos); +} + +TEST_F(LspGetClassDeclarationTests, GetStaticClassDeclaration) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string className = "StaticClass"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {className, ark::es2panda::ir::AstNodeType::CLASS_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(className), std::string::npos); +} + +TEST_F(LspGetClassDeclarationTests, GetPrivateClassDeclaration) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string className = "PrivateClass"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {className, ark::es2panda::ir::AstNodeType::CLASS_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(className), std::string::npos); +} + +TEST_F(LspGetClassDeclarationTests, GetEmptyClassDeclaration) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string className = "EmptyClass"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {className, ark::es2panda::ir::AstNodeType::CLASS_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(className), std::string::npos); +} + +TEST_F(LspGetClassDeclarationTests, GetNonExistentClass) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string className = "NonExistentClass"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {className, ark::es2panda::ir::AstNodeType::CLASS_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + ASSERT_EQ(res.start, static_cast(0)); + ASSERT_EQ(res.length, static_cast(0)); +} +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_class_static_block_test.cpp b/ets2panda/test/unit/lsp/get_node_class_static_block_test.cpp new file mode 100644 index 0000000000..1bc17c9dc1 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_class_static_block_test.cpp @@ -0,0 +1,165 @@ +#include "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "ir/ets/etsReExportDeclaration.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetClassStaticBlockTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( +class A { + static staticProperty: string = 'Initial Value'; + + static { + console.log('Static block executed'); + A.staticProperty = 'Initialized in static block A'; + } +} + +class B { + static staticProperty: string = 'Initial Value'; + + static { + console.log('Static block executed'); + B.staticProperty = 'Initialized in static block B'; + } +} + +// 类没有静态块 +class C { + method() {} +} + +// 类有静态块和静态方法 +class D { + static staticMethod() {} + + static { + console.log('Static block in D'); + } +} + +// 空类 +class E {} + +let a = new A(); +console.log(A.staticProperty); +let b = new B(); +console.log(B.staticProperty); + )"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + + static void GenerateContexts(Initializer &initializer) + { + contexts_ = + initializer.CreateContext("GetClassStaticBlockTest.ets", ES2PANDA_STATE_CHECKED, sourceCode_.c_str()); + } + + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetClassStaticBlockTests, GetClassStaticBlockA) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string className = "A"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {className, ark::es2panda::ir::AstNodeType::CLASS_STATIC_BLOCK}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + ASSERT_EQ(res.start, 188); // End position of the class static + ASSERT_EQ(res.length, 1); +} + +TEST_F(LspGetClassStaticBlockTests, GetClassStaticBlockB) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string className = "B"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {className, ark::es2panda::ir::AstNodeType::CLASS_STATIC_BLOCK}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + ASSERT_EQ(res.start, 380); + ASSERT_EQ(res.length, 1); +} + +TEST_F(LspGetClassStaticBlockTests, GetClassWithoutStaticBlock) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string className = "C"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {className, ark::es2panda::ir::AstNodeType::CLASS_STATIC_BLOCK}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + ASSERT_EQ(res.start, static_cast(0)); + ASSERT_EQ(res.length, static_cast(0)); +} + +TEST_F(LspGetClassStaticBlockTests, GetClassWithStaticBlockAndStaticMethod) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string className = "D"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {className, ark::es2panda::ir::AstNodeType::CLASS_STATIC_BLOCK}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + ASSERT_EQ(res.start, 573); + ASSERT_EQ(res.length, 1); +} + +TEST_F(LspGetClassStaticBlockTests, GetEmptyClass) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string className = "E"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {className, ark::es2panda::ir::AstNodeType::CLASS_STATIC_BLOCK}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + ASSERT_EQ(res.start, static_cast(0)); + ASSERT_EQ(res.length, static_cast(0)); +} + +TEST_F(LspGetClassStaticBlockTests, GetNonExistentClassStaticBlock) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string className = "NonExistentClass"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {className, ark::es2panda::ir::AstNodeType::CLASS_STATIC_BLOCK}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + ASSERT_EQ(res.start, static_cast(0)); + ASSERT_EQ(res.length, static_cast(0)); +} +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_declaration_test.cpp b/ets2panda/test/unit/lsp/get_node_declaration_test.cpp new file mode 100644 index 0000000000..03505338ab --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_declaration_test.cpp @@ -0,0 +1,118 @@ +/** + * 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 "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "ir/ets/etsReExportDeclaration.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetNodeDeclarationTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( +type Direction = 'up' | 'down' | 'left' | 'right'; +function move(dir: Direction): void { + let a = 'aaa'; + const b = 123; + let c = true; +} + )"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + + static void GenerateContexts(Initializer &initializer) + { + contexts_ = + initializer.CreateContext("GetNodeDeclarationTest.ets", ES2PANDA_STATE_CHECKED, sourceCode_.c_str()); + } + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetNodeDeclarationTests, GetLetVariableDeclaration1) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "a"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::IDENTIFIER}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); +} + +TEST_F(LspGetNodeDeclarationTests, GetConstVariableDeclaration2) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "b"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::IDENTIFIER}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); +} + +TEST_F(LspGetNodeDeclarationTests, GetVarVariableDeclaration3) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "c"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::IDENTIFIER}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); +} + +TEST_F(LspGetNodeDeclarationTests, GetNonExistentVariable4) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "nonExistent"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::IDENTIFIER}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + ASSERT_EQ(res.start, static_cast(0)); + ASSERT_EQ(res.length, static_cast(0)); +} +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_declarator_test.cpp b/ets2panda/test/unit/lsp/get_node_declarator_test.cpp new file mode 100644 index 0000000000..0bb0182725 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_declarator_test.cpp @@ -0,0 +1,124 @@ +/** + * 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 "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "ir/ets/etsReExportDeclaration.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetNodeTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( + type Direction = 'up' | 'down' | 'left' | 'right'; + function move(dir: Direction): void { + let a = 'aaa'; + const b = 123; + let c = true; + } + )"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + + static void GenerateContexts(Initializer &initializer) + { + contexts_ = initializer.CreateContext("GetNodeTest.ets", ES2PANDA_STATE_CHECKED, sourceCode_.c_str()); + } + + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetNodeTests, GetLetVariableDeclarator1) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "a"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::VARIABLE_DECLARATOR}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + ASSERT_NE(res.start, static_cast(-1)); + ASSERT_NE(res.length, static_cast(0)); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); +} + +TEST_F(LspGetNodeTests, GetConstVariableDeclarator2) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "b"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::VARIABLE_DECLARATOR}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + ASSERT_NE(res.start, static_cast(-1)); + ASSERT_NE(res.length, static_cast(0)); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); +} + +TEST_F(LspGetNodeTests, GetSecondLetVariableDeclarator3) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "c"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::VARIABLE_DECLARATOR}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + ASSERT_NE(res.start, static_cast(-1)); + ASSERT_NE(res.length, static_cast(0)); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); +} + +TEST_F(LspGetNodeTests, GetNonExistentVariableDeclarator4) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "nonExistent"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::VARIABLE_DECLARATOR}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + ASSERT_EQ(res.start, static_cast(0)); + ASSERT_EQ(res.length, static_cast(0)); +} +} // namespace \ No newline at end of file -- Gitee