• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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