diff --git a/ets2panda/lsp/include/get_signature.h b/ets2panda/lsp/include/get_signature.h index ca8f94c4bd5293650d50410458f9581ff5747871..5a37866948ad31f06034cdfbaa16f31f412118f5 100644 --- a/ets2panda/lsp/include/get_signature.h +++ b/ets2panda/lsp/include/get_signature.h @@ -22,8 +22,7 @@ #include "public/es2panda_lib.h" namespace ark::es2panda::lsp { size_t FindFirstNonSpaceLeft(const std::string &str, size_t pos); -SignatureHelpItems MakeSignatureHelpItem(ir::AstNode *callExpressionNode, ir::AstNode *node, ir::AstNode *declNode, - checker::Signature *signature, size_t position); +void MakeSignatureHelpItem(ir::AstNode *declNode, ir::ScriptFunction *function, SignatureHelpItems &result); SignatureHelpItems GetSignature(es2panda_Context *context, size_t position); } // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/get_signature.cpp b/ets2panda/lsp/src/get_signature.cpp index 3247ca95ad78697fa2cb63a7c39433cc298f98e0..4df2dd66f3c23691b15ef2f1f449a4cc3461e878 100644 --- a/ets2panda/lsp/src/get_signature.cpp +++ b/ets2panda/lsp/src/get_signature.cpp @@ -14,6 +14,7 @@ */ #include +#include #include "checker/types/signature.h" #include "compiler/lowering/util.h" #include "get_signature.h" @@ -46,15 +47,13 @@ size_t FindFirstNonSpaceLeft(const std::string &str, size_t pos) return std::string::npos; } -SignatureHelpItems MakeSignatureHelpItem(ir::AstNode *callExpressionNode, ir::AstNode *node, ir::AstNode *declNode, - checker::Signature *signature, size_t position) +void MakeSignatureHelpItem(ir::AstNode *declNode, ir::ScriptFunction *function, SignatureHelpItems &res) { - SignatureHelpItems res; - res.SetApplicableSpan(node->End().index + 1, position - node->End().index - 1); - res.SetArgumentIndex(callExpressionNode->AsCallExpression()->Arguments().size()); - auto params = signature->GetSignatureInfo()->params; - auto returnType = signature->ReturnType(); - res.SetArgumentCount(params.size()); + if (declNode == nullptr || function == nullptr) { + return; + } + auto paramNodes = function->Params(); + auto returnTypeNode = function->ReturnTypeAnnotation(); SignatureHelpItem item; auto methodName = std::string(declNode->AsMethodDefinition()->Id()->Name()); @@ -68,12 +67,17 @@ SignatureHelpItems MakeSignatureHelpItem(ir::AstNode *callExpressionNode, ir::As item.SetSuffixDisplayParts(SymbolDisplayPart(" ", "space")); item.SetSuffixDisplayParts(SymbolDisplayPart("=>", "punctuation")); item.SetSuffixDisplayParts(SymbolDisplayPart(" ", "space")); - item.SetSuffixDisplayParts(SymbolDisplayPart(returnType->ToString(), "keyword")); + item.SetSuffixDisplayParts( + SymbolDisplayPart(returnTypeNode != nullptr ? returnTypeNode->DumpEtsSrc() : "", "keyword")); - for (auto param : params) { + for (auto param : paramNodes) { + if (!param->IsETSParameterExpression()) { + return; + } + auto paramTypeAnnotation = param->AsETSParameterExpression()->TypeAnnotation(); SignatureHelpParameter paramItem; - auto paramName = std::string(param->Name()); - auto paramType = param->TsType()->ToString(); + auto paramName = std::string(param->AsETSParameterExpression()->Name()); + auto paramType = paramTypeAnnotation != nullptr ? paramTypeAnnotation->DumpEtsSrc() : ""; paramItem.SetName(paramName); paramItem.SetDisplayParts(SymbolDisplayPart(paramName, "parameterNmae")); paramItem.SetDisplayParts(SymbolDisplayPart(":", "punctuation")); @@ -83,7 +87,6 @@ SignatureHelpItems MakeSignatureHelpItem(ir::AstNode *callExpressionNode, ir::As } res.SetItems(item); - return res; } SignatureHelpItems GetSignature(es2panda_Context *context, size_t position) @@ -107,6 +110,7 @@ SignatureHelpItems GetSignature(es2panda_Context *context, size_t position) auto foundPos = std::string(sourceCode).rfind('(', position); auto targetPos = FindFirstNonSpaceLeft(std::string(sourceCode), foundPos); auto node = GetTouchingToken(context, targetPos - 1, false); + FindPrecedingToken(targetPos - 1, ctx->parserProgram->Ast(), ctx->allocator); if (node == nullptr || !node->IsIdentifier()) { return res; } @@ -116,16 +120,15 @@ SignatureHelpItems GetSignature(es2panda_Context *context, size_t position) return res; } - auto function = declNode->AsMethodDefinition()->Function(); - if (function == nullptr) { - return res; - } + res.SetApplicableSpan(node->End().index + 1, position - node->End().index - 1); + res.SetArgumentIndex(callExpressionNode->AsCallExpression()->Arguments().size()); + res.SetArgumentCount(declNode->AsMethodDefinition()->Function()->Params().size()); - auto signature = function->Signature(); - if (signature == nullptr) { - return res; + MakeSignatureHelpItem(declNode, declNode->AsMethodDefinition()->Function(), res); + for (auto overload : declNode->AsMethodDefinition()->Overloads()) { + MakeSignatureHelpItem(declNode, overload->Function(), res); } - res = MakeSignatureHelpItem(callExpressionNode, node, declNode, signature, position); + return res; } } // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_signature_test.cpp b/ets2panda/test/unit/lsp/get_signature_test.cpp index 4e5454401130635d655204be852214f246502268..a72f6dc5bf79caedba7bfd3d2df1da07d0fc6dea 100644 --- a/ets2panda/test/unit/lsp/get_signature_test.cpp +++ b/ets2panda/test/unit/lsp/get_signature_test.cpp @@ -28,8 +28,8 @@ class LspGetSignatureTests : public LSPAPITests {}; TEST_F(LspGetSignatureTests, LspTests) { Initializer initializer = Initializer(); - auto ctx = initializer.CreateContext("get_signature_test.ets", ES2PANDA_STATE_CHECKED, - R"(function add(a:number, b:number): number { + auto ctx = initializer.CreateContext("get_signature_test1.ets", ES2PANDA_STATE_CHECKED, + R"(function add(a:number, b:Double): double { return a + b; } add())"); @@ -50,10 +50,10 @@ add())"); ASSERT_EQ(result.GetApplicableSpan().start, expectedSpanStart); ASSERT_EQ(result.GetItems().at(0).GetPrefixDisplayParts().at(0).GetText(), "add"); ASSERT_EQ(result.GetItems().at(0).GetPrefixDisplayParts().at(0).GetKind(), "functionName"); - ASSERT_EQ(result.GetItems().at(0).GetSuffixDisplayParts().at(returnTypeIndex).GetText(), "Double"); + ASSERT_EQ(result.GetItems().at(0).GetSuffixDisplayParts().at(returnTypeIndex).GetText(), "double"); ASSERT_EQ(result.GetItems().at(0).GetSuffixDisplayParts().at(returnTypeIndex).GetKind(), "keyword"); ASSERT_EQ(result.GetItems().at(0).GetParameters().at(0).GetDisplayParts().at(0).GetText(), "a"); - ASSERT_EQ(result.GetItems().at(0).GetParameters().at(0).GetDisplayParts().at(typeIndex).GetText(), "Double"); + ASSERT_EQ(result.GetItems().at(0).GetParameters().at(0).GetDisplayParts().at(typeIndex).GetText(), "number"); ASSERT_EQ(result.GetItems().at(0).GetParameters().at(1).GetDisplayParts().at(0).GetText(), "b"); ASSERT_EQ(result.GetItems().at(0).GetParameters().at(1).GetDisplayParts().at(typeIndex).GetText(), "Double"); } @@ -61,7 +61,7 @@ add())"); TEST_F(LspGetSignatureTests, LspTests2) { Initializer initializer = Initializer(); - auto ctx = initializer.CreateContext("get_signature_test.ets", ES2PANDA_STATE_CHECKED, + auto ctx = initializer.CreateContext("get_signature_test2.ets", ES2PANDA_STATE_CHECKED, R"(function add(a:number, b:number): number { return a + b; } @@ -84,26 +84,81 @@ add(11,))"); TEST_F(LspGetSignatureTests, LspTests3) { Initializer initializer = Initializer(); - auto ctx = initializer.CreateContext("get_signature_test.ets", ES2PANDA_STATE_CHECKED, - R"(function add(a:number, b): number { + auto ctx = initializer.CreateContext("get_signature_test3.ets", ES2PANDA_STATE_CHECKED, + R"(function add(a, b) { return a + b; } add(11,))"); const LSPAPI *lspApi = GetImpl(); - const size_t offset = 61; + const size_t offset = 46; lspApi->getSignatureHelpItems(ctx, offset); auto result = ark::es2panda::lsp::GetSignature(ctx, offset); initializer.DestroyContext(ctx); const size_t expectedCount = 2; const size_t expectedIndex = 1; const size_t expectedSpanLength = 3; - const size_t expectedSpanStart = 58; + const size_t expectedSpanStart = 43; const size_t typeIndex = 3; + const size_t returnTypeIndex = 4; ASSERT_EQ(result.GetArgumentCount(), expectedCount); ASSERT_EQ(result.GetArgumentIndex(), expectedIndex); ASSERT_EQ(result.GetApplicableSpan().length, expectedSpanLength); ASSERT_EQ(result.GetApplicableSpan().start, expectedSpanStart); + ASSERT_EQ(result.GetItems().at(0).GetParameters().at(0).GetDisplayParts().at(typeIndex).GetText(), "*ERROR_TYPE*"); ASSERT_EQ(result.GetItems().at(0).GetParameters().at(1).GetDisplayParts().at(typeIndex).GetText(), "*ERROR_TYPE*"); + ASSERT_EQ(result.GetItems().at(0).GetSuffixDisplayParts().at(returnTypeIndex).GetText(), ""); +} + +TEST_F(LspGetSignatureTests, LspTests4) +{ + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext("get_signature_test4.ets", ES2PANDA_STATE_CHECKED, + R"(declare function Foo(a: number, b:string):void; +declare function Foo(a: number):void; +Foo())"); + const LSPAPI *lspApi = GetImpl(); + const size_t offset = 90; + lspApi->getSignatureHelpItems(ctx, offset); + auto result = ark::es2panda::lsp::GetSignature(ctx, offset); + initializer.DestroyContext(ctx); + const size_t expectedCount = 2; + const size_t expectedIndex = 0; + const size_t expectedSpanLength = 0; + const size_t expectedSpanStart = 90; + const size_t typeIndex = 3; + ASSERT_EQ(result.GetArgumentCount(), expectedCount); + ASSERT_EQ(result.GetArgumentIndex(), expectedIndex); + ASSERT_EQ(result.GetApplicableSpan().length, expectedSpanLength); + ASSERT_EQ(result.GetApplicableSpan().start, expectedSpanStart); + ASSERT_EQ(result.GetItems().at(0).GetParameters().at(0).GetDisplayParts().at(typeIndex).GetText(), "number"); + ASSERT_EQ(result.GetItems().at(0).GetParameters().at(1).GetDisplayParts().at(typeIndex).GetText(), "string"); + ASSERT_EQ(result.GetItems().at(1).GetParameters().at(0).GetDisplayParts().at(typeIndex).GetText(), "number"); +} + +TEST_F(LspGetSignatureTests, LspTests5) +{ + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext("get_signature_test5.ets", ES2PANDA_STATE_CHECKED, + R"(class A{ + Foo(a: number){} +} +let a = new A(); +a.Foo())"); + const LSPAPI *lspApi = GetImpl(); + const size_t offset = 55; + lspApi->getSignatureHelpItems(ctx, offset); + auto result = ark::es2panda::lsp::GetSignature(ctx, offset); + initializer.DestroyContext(ctx); + const size_t expectedCount = 1; + const size_t expectedIndex = 0; + const size_t expectedSpanLength = 0; + const size_t expectedSpanStart = 55; + const size_t typeIndex = 3; + ASSERT_EQ(result.GetArgumentCount(), expectedCount); + ASSERT_EQ(result.GetArgumentIndex(), expectedIndex); + ASSERT_EQ(result.GetApplicableSpan().length, expectedSpanLength); + ASSERT_EQ(result.GetApplicableSpan().start, expectedSpanStart); + ASSERT_EQ(result.GetItems().at(0).GetParameters().at(0).GetDisplayParts().at(typeIndex).GetText(), "number"); } } // namespace \ No newline at end of file