1 /**
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "create_type_help_items.h"
17 #include <iostream>
18 #include <string>
19 #include "utils/arena_containers.h"
20
21 namespace ark::es2panda::lsp {
22
CreateTypeHelpItems(const ir::AstNode * node,lexer::SourceRange location,TextSpan applicableSpan)23 SignatureHelpItems CreateTypeHelpItems(const ir::AstNode *node, lexer::SourceRange location, TextSpan applicableSpan)
24 {
25 std::vector<checker::Type *> result;
26 SignatureHelpItems items;
27 SignatureHelpItem item;
28 if (node == nullptr) {
29 return items;
30 }
31 GetLocalTypeParametersOfClassOrInterfaceOrTypeAlias(node, result);
32 GetTypeHelpItem(&result, node, item);
33 items.SetItems(item);
34 items.SetApplicableSpan(applicableSpan.start, applicableSpan.length);
35 items.SetSelectedItemIndex(location.start.index);
36 items.SetArgumentIndex(location.start.index);
37 items.SetArgumentCount(location.end.index - location.start.index);
38 return items;
39 }
40
GetLocalTypeParametersOfClassOrInterfaceOrTypeAlias(const ir::AstNode * node,std::vector<checker::Type * > & result)41 void GetLocalTypeParametersOfClassOrInterfaceOrTypeAlias(const ir::AstNode *node, std::vector<checker::Type *> &result)
42 {
43 if (node == nullptr) {
44 return;
45 }
46 if (node->IsTSInterfaceDeclaration() || node->IsClassDefinition() || node->IsClassExpression() ||
47 node->IsTSTypeAliasDeclaration()) {
48 auto typeParams = GetEffectiveTypeParameterDeclarations(node, result);
49 for (auto *param : typeParams) {
50 result.push_back(param);
51 }
52 }
53 }
54
GetEffectiveTypeParameterDeclarations(const ir::AstNode * node,std::vector<checker::Type * > & result)55 std::vector<checker::Type *> GetEffectiveTypeParameterDeclarations(const ir::AstNode *node,
56 std::vector<checker::Type *> &result)
57 {
58 if (node == nullptr) {
59 return result;
60 }
61 const ir::TSTypeParameterDeclaration *typeParams = nullptr;
62 if (node->IsClassDefinition()) {
63 typeParams = node->AsClassDefinition()->TypeParams();
64 } else if (node->IsTSInterfaceDeclaration()) {
65 typeParams = node->AsTSInterfaceDeclaration()->TypeParams();
66 } else if (node->IsTSTypeAliasDeclaration()) {
67 typeParams = node->AsTSTypeAliasDeclaration()->TypeParams();
68 } else if (node->IsETSStructDeclaration()) {
69 typeParams = node->AsETSStructDeclaration()->Definition()->TypeParams();
70 } else if (node->IsTSEnumDeclaration()) {
71 auto members = node->AsTSEnumDeclaration()->Members();
72 for (auto member : members) {
73 result.push_back(reinterpret_cast<checker::Type *>(member->AsTSEnumMember()->Type()));
74 }
75 }
76 if (typeParams != nullptr) {
77 for (auto *param : typeParams->Params()) {
78 result.push_back(reinterpret_cast<checker::Type *>(param));
79 }
80 }
81 return result;
82 }
83
GetTypeHelpItem(std::vector<checker::Type * > * typeParameters,const ir::AstNode * node,SignatureHelpItem & result)84 void GetTypeHelpItem(std::vector<checker::Type *> *typeParameters, const ir::AstNode *node, SignatureHelpItem &result)
85 {
86 const ir::TSTypeParameterDeclaration *typeParams = nullptr;
87 if (node->IsClassDeclaration()) {
88 result.SetPrefixDisplayParts(
89 CreateClassName(std::string(node->AsClassDeclaration()->Definition()->Ident()->Name())));
90 typeParams = node->AsClassDeclaration()->Definition()->TypeParams();
91 } else if (node->IsTSInterfaceDeclaration()) {
92 result.SetPrefixDisplayParts(CreateClassName(node->AsTSInterfaceDeclaration()->Id()->ToString()));
93 typeParams = node->AsTSInterfaceDeclaration()->TypeParams();
94 } else if (node->IsETSStructDeclaration()) {
95 result.SetPrefixDisplayParts(
96 SignatureCreateStructName(std::string(node->AsETSStructDeclaration()->Definition()->Ident()->Name())));
97 typeParams = node->AsETSStructDeclaration()->Definition()->TypeParams();
98 } else if (node->IsTSEnumDeclaration()) {
99 result.SetPrefixDisplayParts(CreateEnumName(std::string(node->AsTSEnumDeclaration()->Key()->Name())));
100 auto members = node->AsTSEnumDeclaration()->Members();
101 for (auto member : members) {
102 typeParameters->push_back(reinterpret_cast<checker::Type *>(member->AsTSEnumMember()->Type()));
103 }
104 }
105 result.SetPrefixDisplayParts(CreatePunctuation("<"));
106
107 if (typeParams != nullptr) {
108 for (auto *param : typeParams->Params()) {
109 typeParameters->push_back(reinterpret_cast<checker::Type *>(param));
110 }
111 }
112 bool isFirst = true;
113 for (auto *typeParam : *typeParameters) {
114 if (!isFirst) {
115 result.SetSeparatorDisplayParts(CreatePunctuation(", "));
116 }
117
118 SignatureHelpParameter signatureHelpParameter;
119 auto *typeParamNode = reinterpret_cast<ir::TSTypeParameter *>(typeParam);
120 signatureHelpParameter.SetName(typeParamNode->Name()->ToString());
121 if (auto *constraint = typeParamNode->Constraint()) {
122 auto name = signatureHelpParameter.GetName();
123 std::string constraintStr = constraint->ToString();
124 signatureHelpParameter.SetDisplayParts(CreateTypeName(name));
125 signatureHelpParameter.SetDisplayParts(CreateKeyword(" extends "));
126 signatureHelpParameter.SetDisplayParts(CreateTypeName(constraintStr));
127 } else {
128 std::string name = signatureHelpParameter.GetName();
129 signatureHelpParameter.SetDisplayParts(CreateTypeName(name));
130 }
131 result.SetParameters(signatureHelpParameter);
132 isFirst = false;
133 }
134 result.SetSuffixDisplayParts(CreatePunctuation(">"));
135 }
136
137 } // namespace ark::es2panda::lsp