• 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 "quick_info.h"
17 #include "internal_api.h"
18 #include "ir/astNode.h"
19 #include "public/public.h"
20 #include "ir/ets/etsUnionType.h"
21 #include "api.h"
22 #include "compiler/lowering/util.h"
23 
24 namespace ark::es2panda::lsp {
25 
GetEnumMemberByName(ir::AstNode * node,const util::StringView & name)26 ir::AstNode *GetEnumMemberByName(ir::AstNode *node, const util::StringView &name)
27 {
28     if (node->Type() != ir::AstNodeType::TS_ENUM_DECLARATION) {
29         return nullptr;
30     }
31     auto enumDecl = node->AsTSEnumDeclaration();
32     auto enumMember = enumDecl->FindChild([&name](ir::AstNode *child) {
33         return child->IsTSEnumMember() && child->AsTSEnumMember()->Key()->AsIdentifier()->Name() == name;
34     });
35     return enumMember == nullptr ? nullptr : enumMember;
36 }
37 
IsIncludedToken(const ir::AstNode * node)38 bool IsIncludedToken(const ir::AstNode *node)
39 {
40     auto type = node->Type();
41     static const std::unordered_set<ir::AstNodeType> INCLUDED_TOKEN_TYPES = {
42         ir::AstNodeType::IDENTIFIER,
43         ir::AstNodeType::METHOD_DEFINITION,
44         ir::AstNodeType::ETS_NEW_CLASS_INSTANCE_EXPRESSION,
45         ir::AstNodeType::CLASS_DECLARATION,
46         ir::AstNodeType::ETS_TUPLE,
47         ir::AstNodeType::STRING_LITERAL,
48         ir::AstNodeType::NUMBER_LITERAL,
49         ir::AstNodeType::TEMPLATE_LITERAL,
50         ir::AstNodeType::TEMPLATE_ELEMENT,
51         ir::AstNodeType::ASSIGNMENT_EXPRESSION,
52     };
53     return INCLUDED_TOKEN_TYPES.find(type) != INCLUDED_TOKEN_TYPES.end();
54 }
55 
GetTokenForQuickInfo(es2panda_Context * context,size_t position)56 ir::AstNode *GetTokenForQuickInfo(es2panda_Context *context, size_t position)
57 {
58     auto node = GetTouchingToken(context, position, false);
59     if (node == nullptr) {
60         return nullptr;
61     }
62     if (!IsIncludedToken(node)) {
63         return nullptr;
64     }
65     return node;
66 }
67 
IsObjectLiteralElement(ir::AstNode * node)68 bool IsObjectLiteralElement(ir::AstNode *node)
69 {
70     auto type = node->Type();
71     static const std::unordered_set<ir::AstNodeType> INCLUDED_OBJECT_LITERAL_ELEMENT_TYPES = {
72         ir::AstNodeType::PROPERTY,
73     };
74     return INCLUDED_OBJECT_LITERAL_ELEMENT_TYPES.find(type) != INCLUDED_OBJECT_LITERAL_ELEMENT_TYPES.end();
75 }
76 
GetContainingObjectLiteralNode(ir::AstNode * node)77 ir::AstNode *GetContainingObjectLiteralNode(ir::AstNode *node)
78 {
79     if (node == nullptr) {
80         return nullptr;
81     }
82     auto type = node->Type();
83     if (type == ir::AstNodeType::STRING_LITERAL || type == ir::AstNodeType::NUMBER_LITERAL ||
84         type == ir::AstNodeType::TEMPLATE_LITERAL || type == ir::AstNodeType::IDENTIFIER) {
85         if (IsObjectLiteralElement(node->Parent())) {
86             return node->Parent();
87         }
88     } else if (type == ir::AstNodeType::TEMPLATE_ELEMENT) {
89         if (IsObjectLiteralElement(node->Parent()->Parent())) {
90             return node->Parent()->Parent();
91         }
92     }
93     return nullptr;
94 }
95 
GetContextualTypeNode(ir::AstNode * node)96 ir::AstNode *GetContextualTypeNode(ir::AstNode *node)
97 {
98     if (node == nullptr) {
99         return nullptr;
100     }
101     if (node->Type() == ir::AstNodeType::OBJECT_EXPRESSION) {
102         if (node->Parent()->Type() == ir::AstNodeType::CLASS_PROPERTY) {
103             auto propertyObj = node->Parent()->AsClassElement();
104             auto type = propertyObj->TsType();
105             auto contextualTypeNode = type->Variable()->Declaration()->Node();
106             return contextualTypeNode;
107         }
108         if (node->Parent()->Type() == ir::AstNodeType::ASSIGNMENT_EXPRESSION) {
109             auto propertyObj = node->Parent()->AsAssignmentExpression();
110             auto type = propertyObj->TsType();
111             auto contextualTypeNode = type->Variable()->Declaration()->Node();
112             return contextualTypeNode;
113         }
114     }
115     return nullptr;
116 }
117 
GetPropertyNodeFromContextualType(ir::AstNode * node,ir::AstNode * contextualTypeNode)118 ir::AstNode *GetPropertyNodeFromContextualType(ir::AstNode *node, ir::AstNode *contextualTypeNode)
119 {
120     auto type = contextualTypeNode->Type();
121     auto property = node->AsProperty()->Key();
122     ark::es2panda::util::StringView propertyName;
123     if (property->Type() == ir::AstNodeType::STRING_LITERAL) {
124         propertyName = property->AsStringLiteral()->Str();
125     } else if (property->Type() == ir::AstNodeType::IDENTIFIER) {
126         propertyName = property->AsIdentifier()->Name();
127     }
128     if (type == ir::AstNodeType::CLASS_DEFINITION) {
129         auto def = contextualTypeNode->AsClassDefinition();
130         auto bodies = def->Body();
131         for (auto it : bodies) {
132             auto methodDef = it->AsMethodDefinition();
133             auto name = methodDef->Key()->AsIdentifier()->Name();
134             if (name == propertyName) {
135                 return it;
136             }
137         }
138     }
139     if (type == ir::AstNodeType::TS_INTERFACE_DECLARATION) {
140         auto def = contextualTypeNode->AsTSInterfaceDeclaration();
141         auto bodies = def->Body()->Body();
142         for (auto it : bodies) {
143             auto methodDef = it->AsMethodDefinition();
144             auto name = methodDef->Key()->AsIdentifier()->Name();
145             if (name == propertyName) {
146                 return it;
147             }
148         }
149     }
150     return node;
151 }
152 
IsDeclaration(ir::AstNode * node)153 bool IsDeclaration(ir::AstNode *node)
154 {
155     return node->Type() == ir::AstNodeType::CLASS_DECLARATION ||
156            node->Type() == ir::AstNodeType::FUNCTION_DECLARATION ||
157            node->Type() == ir::AstNodeType::IMPORT_DECLARATION ||
158            node->Type() == ir::AstNodeType::ANNOTATION_DECLARATION ||
159            node->Type() == ir::AstNodeType::EXPORT_ALL_DECLARATION ||
160            node->Type() == ir::AstNodeType::EXPORT_DEFAULT_DECLARATION ||
161            node->Type() == ir::AstNodeType::EXPORT_NAMED_DECLARATION ||
162            node->Type() == ir::AstNodeType::ETS_PACKAGE_DECLARATION ||
163            node->Type() == ir::AstNodeType::ETS_IMPORT_DECLARATION ||
164            node->Type() == ir::AstNodeType::STRUCT_DECLARATION ||
165            node->Type() == ir::AstNodeType::TS_ENUM_DECLARATION ||
166            node->Type() == ir::AstNodeType::TS_SIGNATURE_DECLARATION ||
167            node->Type() == ir::AstNodeType::TS_TYPE_PARAMETER_DECLARATION ||
168            node->Type() == ir::AstNodeType::TS_MODULE_DECLARATION ||
169            node->Type() == ir::AstNodeType::TS_IMPORT_EQUALS_DECLARATION ||
170            node->Type() == ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION ||
171            node->Type() == ir::AstNodeType::TS_INTERFACE_DECLARATION ||
172            node->Type() == ir::AstNodeType::VARIABLE_DECLARATION;
173 }
174 
IsDefinition(ir::AstNode * node)175 bool IsDefinition(ir::AstNode *node)
176 {
177     return node->Type() == ir::AstNodeType::CLASS_DEFINITION || node->Type() == ir::AstNodeType::METHOD_DEFINITION;
178 }
179 
IsIdentifierOfDeclaration(ir::AstNode * node)180 bool IsIdentifierOfDeclaration(ir::AstNode *node)
181 {
182     return node->Parent()->Type() == ir::AstNodeType::IMPORT_SPECIFIER ||
183                    (node->Parent()->Type() == ir::AstNodeType::EXPORT_SPECIFIER)
184                ? node->Type() == ir::AstNodeType::IDENTIFIER
185                : node->Type() == ir::AstNodeType::IDENTIFIER && IsDeclaration(node->Parent());
186 }
187 
GetNodeAtLocation(ir::AstNode * node)188 ir::AstNode *GetNodeAtLocation(ir::AstNode *node)
189 {
190     if (node->IsProgram()) {
191         return node->Modifiers() == ir::ModifierFlags::EXPORT ? node : nullptr;
192     }
193     auto parent = node->Parent();
194     if (IsIdentifierOfDeclaration(node)) {
195         return parent;
196     }
197     if (node->Type() == ir::AstNodeType::IDENTIFIER) {
198         if (IsDeclaration(parent) || IsDefinition(parent)) {
199             if (compiler::ClassDefinitionIsEnumTransformed(parent)) {
200                 parent = parent->AsClassDefinition()->OrigEnumDecl()->AsTSEnumDeclaration();
201             }
202             return parent;
203         }
204         if (parent->Type() == ir::AstNodeType::MEMBER_EXPRESSION) {
205             auto declNode = compiler::DeclarationFromIdentifier(parent->AsMemberExpression()->Object()->AsIdentifier());
206             if (compiler::ClassDefinitionIsEnumTransformed(declNode)) {
207                 declNode = declNode->AsClassDefinition()->OrigEnumDecl()->AsTSEnumDeclaration();
208             }
209             return declNode;
210         }
211         return compiler::DeclarationFromIdentifier(node->AsIdentifier());
212     }
213 
214     return nullptr;
215 }
216 
GetNodeAtLocationForQuickInfo(ir::AstNode * node)217 ir::AstNode *GetNodeAtLocationForQuickInfo(ir::AstNode *node)
218 {
219     if (node != nullptr) {
220         auto object = GetContainingObjectLiteralNode(node);
221         if (object != nullptr) {
222             auto contextualTypeNode = GetContextualTypeNode(object->Parent());
223             return GetPropertyNodeFromContextualType(object, contextualTypeNode);
224         }
225         return GetNodeAtLocation(node);
226     }
227     return nullptr;
228 }
229 
ModifiersToString(ir::ModifierFlags flags)230 std::string ModifiersToString(ir::ModifierFlags flags)
231 {
232     std::ostringstream oss;
233     bool first = true;
234     auto addModifier = [flags, &oss, &first](ir::ModifierFlags flag, const std::string &name) {
235         if ((static_cast<uint32_t>(flags) & static_cast<uint32_t>(flag)) != 0) {
236             if (!first) {
237                 oss << " ";
238             }
239             oss << name;
240             first = false;
241         }
242     };
243     addModifier(ir::ModifierFlags::STATIC, "static");
244     addModifier(ir::ModifierFlags::ASYNC, "async");
245     addModifier(ir::ModifierFlags::PUBLIC, "public");
246     addModifier(ir::ModifierFlags::PROTECTED, "protected");
247     addModifier(ir::ModifierFlags::PRIVATE, "private");
248     addModifier(ir::ModifierFlags::DECLARE, "declare");
249     addModifier(ir::ModifierFlags::READONLY, "readonly");
250     addModifier(ir::ModifierFlags::OPTIONAL, "optional");
251     addModifier(ir::ModifierFlags::DEFINITE, "definite");
252     addModifier(ir::ModifierFlags::ABSTRACT, "abstract");
253     addModifier(ir::ModifierFlags::CONST, "const");
254     addModifier(ir::ModifierFlags::FINAL, "final");
255     addModifier(ir::ModifierFlags::NATIVE, "native");
256     addModifier(ir::ModifierFlags::OVERRIDE, "override");
257     addModifier(ir::ModifierFlags::CONSTRUCTOR, "constructor");
258     addModifier(ir::ModifierFlags::SYNCHRONIZED, "synchronized");
259     addModifier(ir::ModifierFlags::FUNCTIONAL, "functional");
260     addModifier(ir::ModifierFlags::IN, "in");
261     addModifier(ir::ModifierFlags::OUT, "out");
262     addModifier(ir::ModifierFlags::INTERNAL, "internal");
263     addModifier(ir::ModifierFlags::EXPORT, "export");
264     addModifier(ir::ModifierFlags::GETTER, "getter");
265     addModifier(ir::ModifierFlags::SETTER, "setter");
266     addModifier(ir::ModifierFlags::DEFAULT_EXPORT, "default_export");
267     addModifier(ir::ModifierFlags::SUPER_OWNER, "super_owner");
268     addModifier(ir::ModifierFlags::ANNOTATION_DECLARATION, "annotation_declaration");
269     addModifier(ir::ModifierFlags::ANNOTATION_USAGE, "annotation_usage");
270     addModifier(ir::ModifierFlags::READONLY_PARAMETER, "readonly_parameter");
271     return oss.str();
272 }
273 
GetKindModifiers(ir::AstNode * node)274 std::string GetKindModifiers(ir::AstNode *node)
275 {
276     auto flags = node->Modifiers();
277     return ModifiersToString(flags);
278 }
279 
GetContainerNode(ir::AstNode * node)280 ir::AstNode *GetContainerNode(ir::AstNode *node)
281 {
282     if (node == nullptr) {
283         return nullptr;
284     }
285     while (!node->IsProgram()) {
286         switch (node->Type()) {
287             case ir::AstNodeType::TS_METHOD_SIGNATURE:
288             case ir::AstNodeType::FUNCTION_DECLARATION:
289             case ir::AstNodeType::FUNCTION_EXPRESSION:
290             case ir::AstNodeType::CLASS_DECLARATION:
291             case ir::AstNodeType::STRUCT_DECLARATION:
292             case ir::AstNodeType::TS_INTERFACE_DECLARATION:
293             case ir::AstNodeType::TS_ENUM_DECLARATION:
294             case ir::AstNodeType::TS_MODULE_DECLARATION:
295             case ir::AstNodeType::METHOD_DEFINITION:
296                 return node;
297             default:
298                 node = node->Parent();
299         }
300     }
301     return node;
302 }
303 
GetNodeFileName(ir::AstNode * contextualTypeNode)304 std::string GetNodeFileName(ir::AstNode *contextualTypeNode)
305 {
306     if (!contextualTypeNode->IsETSImportDeclaration()) {
307         return "";
308     }
309     return std::string(contextualTypeNode->AsETSImportDeclaration()->ResolvedSource());
310 }
311 
IsClass(ir::AstNode * node)312 bool IsClass(ir::AstNode *node)
313 {
314     return node->Type() == ir::AstNodeType::STRUCT_DECLARATION || node->Type() == ir::AstNodeType::CLASS_DECLARATION ||
315            node->Type() == ir::AstNodeType::CLASS_EXPRESSION || node->Type() == ir::AstNodeType::CLASS_DEFINITION;
316 }
317 
IsCallOrNewExpression(ir::AstNode * node)318 bool IsCallOrNewExpression(ir::AstNode *node)
319 {
320     return node->Type() == ir::AstNodeType::CALL_EXPRESSION || node->Type() == ir::AstNodeType::NEW_EXPRESSION;
321 }
322 
IsTaggedTemplateExpression(ir::AstNode * node)323 bool IsTaggedTemplateExpression(ir::AstNode *node)
324 {
325     return node->Type() == ir::AstNodeType::TAGGED_TEMPLATE_EXPRESSION;
326 }
327 
IsFunctionType(ir::AstNode * node)328 bool IsFunctionType(ir::AstNode *node)
329 {
330     return node->Type() == ir::AstNodeType::TS_METHOD_SIGNATURE ||
331            node->Type() == ir::AstNodeType::TS_INDEX_SIGNATURE || node->Type() == ir::AstNodeType::ETS_FUNCTION_TYPE ||
332            node->Type() == ir::AstNodeType::TS_CONSTRUCTOR_TYPE ||
333            node->Type() == ir::AstNodeType::FUNCTION_DECLARATION ||
334            node->Type() == ir::AstNodeType::FUNCTION_EXPRESSION ||
335            node->Type() == ir::AstNodeType::ARROW_FUNCTION_EXPRESSION;
336 }
337 
IsFunctionLike(ir::AstNode * node)338 bool IsFunctionLike(ir::AstNode *node)
339 {
340     return node != nullptr && IsFunctionType(node);
341 }
342 
GetNodeKind(ir::AstNode * node)343 std::string GetNodeKind(ir::AstNode *node)
344 {
345     if (node->Modifiers() != ir::ModifierFlags::NONE) {
346         return ModifiersToString(node->Modifiers());
347     }
348     if (node->Type() == ir::AstNodeType::PROPERTY) {
349         return "property";
350     }
351     if (IsClass(node)) {
352         return "class";
353     }
354     return "";
355 }
356 
TransDisplayPartsToStr(const std::vector<SymbolDisplayPart> & displayParts)357 std::string TransDisplayPartsToStr(const std::vector<SymbolDisplayPart> &displayParts)
358 {
359     std::stringstream ss;
360     for (const auto &part : displayParts) {
361         ss << "[" << part.GetText() << "](" << part.GetKind() << ")" << std::endl;
362     }
363     return ss.str();
364 }
365 
PrimitiveTypeToName(ir::PrimitiveType type)366 std::string PrimitiveTypeToName(ir::PrimitiveType type)
367 {
368     switch (type) {
369         case ir::PrimitiveType::BYTE:
370             return "byte";
371         case ir::PrimitiveType::INT:
372             return "int";
373         case ir::PrimitiveType::LONG:
374             return "long";
375         case ir::PrimitiveType::SHORT:
376             return "short";
377         case ir::PrimitiveType::FLOAT:
378             return "float";
379         case ir::PrimitiveType::DOUBLE:
380             return "double";
381         case ir::PrimitiveType::BOOLEAN:
382             return "boolean";
383         case ir::PrimitiveType::CHAR:
384             return "char";
385         case ir::PrimitiveType::VOID:
386             return "void";
387         default:
388             UNREACHABLE();
389     }
390 }
391 
GetNameForUnionType(const ir::TypeNode * unionType)392 std::string GetNameForUnionType(const ir::TypeNode *unionType)
393 {
394     const auto &types = unionType->AsETSUnionType()->Types();
395     std::string newstr;
396     for (size_t i = 0; i < types.size(); ++i) {
397         newstr += GetNameForTypeNode(types[i]);
398         if (i != types.size() - 1) {
399             newstr += "|";
400         }
401     }
402     return newstr;
403 }
404 
GetNameForTypeReference(const ir::TypeNode * typeReference)405 std::string GetNameForTypeReference(const ir::TypeNode *typeReference)
406 {
407     std::string typeParamNames;
408     auto typeParam = typeReference->AsETSTypeReference()->Part()->TypeParams();
409     if (typeParam != nullptr && typeParam->IsTSTypeParameterInstantiation()) {
410         typeParamNames = "<";
411         for (auto param : typeParam->Params()) {
412             typeParamNames += GetNameForTypeNode(param) + ",";
413         }
414         typeParamNames.pop_back();
415         typeParamNames += ">";
416     }
417     return typeReference->AsETSTypeReference()->Part()->GetIdent()->Name().Mutf8() + typeParamNames;
418 }
419 
GetNameForFunctionType(const ir::TypeNode * functionType)420 std::string GetNameForFunctionType(const ir::TypeNode *functionType)
421 {
422     std::string params;
423     for (const auto *param : functionType->AsETSFunctionType()->Params()) {
424         params += param->AsETSParameterExpression()->Name().Mutf8() + ":" +
425                   GetNameForTypeNode(param->AsETSParameterExpression()->TypeAnnotation()) + ",";
426     }
427     if (!params.empty()) {
428         params.pop_back();
429     }
430     const std::string returnType = GetNameForTypeNode(functionType->AsETSFunctionType()->ReturnType());
431     return "((" + params + ") => " + returnType + ")";
432 }
433 
GetNameForTypeNode(const ir::TypeNode * typeAnnotation)434 std::string GetNameForTypeNode(const ir::TypeNode *typeAnnotation)
435 {
436     if (typeAnnotation->IsETSUnionType()) {
437         return GetNameForUnionType(typeAnnotation);
438     }
439     if (typeAnnotation->IsETSPrimitiveType()) {
440         return PrimitiveTypeToName(typeAnnotation->AsETSPrimitiveType()->GetPrimitiveType());
441     }
442 
443     if (typeAnnotation->IsETSTypeReference()) {
444         return GetNameForTypeReference(typeAnnotation);
445     }
446 
447     if (typeAnnotation->IsETSFunctionType()) {
448         return GetNameForFunctionType(typeAnnotation);
449     }
450 
451     if (typeAnnotation->IsTSArrayType()) {
452         return GetNameForTypeNode(typeAnnotation->AsTSArrayType()->ElementType()) + "[]";
453     }
454 
455     if (typeAnnotation->IsETSNullType()) {
456         return "null";
457     }
458 
459     if (typeAnnotation->IsETSUndefinedType()) {
460         return "undefined";
461     }
462     return "undefined";
463 }
464 
GetNameForETSUnionType(const ir::TypeNode * typeAnnotation)465 std::string GetNameForETSUnionType(const ir::TypeNode *typeAnnotation)
466 {
467     ASSERT(typeAnnotation->IsETSUnionType());
468     std::string newstr;
469     for (size_t i = 0; i < typeAnnotation->AsETSUnionType()->Types().size(); i++) {
470         auto type = typeAnnotation->AsETSUnionType()->Types()[i];
471         std::string str = GetNameForTypeNode(type);
472         newstr += str;
473         if (i != typeAnnotation->AsETSUnionType()->Types().size() - 1) {
474             newstr += "|";
475         }
476     }
477     return newstr;
478 }
479 
MergeSymbolDisplayPart(const std::vector<SymbolDisplayPart> & symbolDisplayPart1,const std::vector<SymbolDisplayPart> & symbolDisplayPart2)480 std::vector<SymbolDisplayPart> MergeSymbolDisplayPart(const std::vector<SymbolDisplayPart> &symbolDisplayPart1,
481                                                       const std::vector<SymbolDisplayPart> &symbolDisplayPart2)
482 {
483     std::vector<SymbolDisplayPart> result;
484     result.reserve(symbolDisplayPart1.size() + symbolDisplayPart2.size());
485 
486     for (const SymbolDisplayPart &part : symbolDisplayPart1) {
487         result.emplace_back(part);
488     }
489     for (const SymbolDisplayPart &part : symbolDisplayPart2) {
490         result.emplace_back(part);
491     }
492     return result;
493 }
494 
GetNameFromClassExpression(ir::AstNode * node)495 std::string GetNameFromClassExpression(ir::AstNode *node)
496 {
497     if (node == nullptr || !node->IsClassExpression()) {
498         return "";
499     }
500     if (node->AsClassExpression()->Variable() == nullptr) {
501         return "";
502     }
503     return std::string(node->AsClassExpression()->Variable()->Name());
504 }
505 
GetNameFromETSStructDeclaration(ir::AstNode * node)506 std::string GetNameFromETSStructDeclaration(ir::AstNode *node)
507 {
508     if (node == nullptr || !node->IsETSStructDeclaration()) {
509         return "";
510     }
511     if (node->AsETSStructDeclaration()->Definition() == nullptr) {
512         return "";
513     }
514     if (node->AsETSStructDeclaration()->Definition()->Ident() == nullptr) {
515         return "";
516     }
517     return std::string(node->AsETSStructDeclaration()->Definition()->Ident()->Name());
518 }
519 
GetNameFromClassDeclaration(ir::AstNode * node)520 std::string GetNameFromClassDeclaration(ir::AstNode *node)
521 {
522     if (node == nullptr || !node->IsClassDeclaration()) {
523         return "";
524     }
525     if (node->AsClassDeclaration()->Definition() == nullptr) {
526         return "";
527     }
528     if (node->AsClassDeclaration()->Definition()->Ident() == nullptr) {
529         return "";
530     }
531     return std::string(node->AsClassDeclaration()->Definition()->Ident()->Name());
532 }
533 
GetNameFromClassDefinition(ir::AstNode * node)534 std::string GetNameFromClassDefinition(ir::AstNode *node)
535 {
536     if (node == nullptr || !node->IsClassDefinition()) {
537         return "";
538     }
539     if (node->AsClassDefinition()->Ident() == nullptr) {
540         return "";
541     }
542     return std::string(node->AsClassDefinition()->Ident()->Name());
543 }
544 
CreateDisplayForClass(ir::AstNode * node)545 std::vector<SymbolDisplayPart> CreateDisplayForClass(ir::AstNode *node)
546 {
547     std::vector<SymbolDisplayPart> displayParts;
548     if (!IsClass(node)) {
549         return displayParts;
550     }
551     if (node->Type() == ir::AstNodeType::CLASS_EXPRESSION) {
552         displayParts.emplace_back(CreatePunctuation("("));
553         displayParts.emplace_back(CreateKeyword("local class"));
554         displayParts.emplace_back(CreatePunctuation(")"));
555         displayParts.emplace_back(CreateSpace());
556         displayParts.emplace_back(CreateClassName(GetNameFromClassExpression(node)));
557     } else if (node->Type() == ir::AstNodeType::STRUCT_DECLARATION) {
558         displayParts.emplace_back(CreateKeyword("struct"));
559         displayParts.emplace_back(CreateSpace());
560         displayParts.emplace_back(CreateClassName(GetNameFromETSStructDeclaration(node)));
561     } else if (node->Type() == ir::AstNodeType::CLASS_DECLARATION) {
562         displayParts.emplace_back(CreateKeyword("class"));
563         displayParts.emplace_back(CreateSpace());
564         displayParts.emplace_back(CreateClassName(GetNameFromClassDeclaration(node)));
565     } else {
566         // class definition
567         if (node->AsClassDefinition()->OrigEnumDecl() != nullptr) {
568             displayParts.emplace_back(CreateKeyword("enum"));
569         } else {
570             displayParts.emplace_back(CreateKeyword("class"));
571         }
572         displayParts.emplace_back(CreateSpace());
573         displayParts.emplace_back(CreateClassName(GetNameFromClassDefinition(node)));
574     }
575     return displayParts;
576 }
577 
GetNameFromTSInterfaceDeclaration(ir::AstNode * node)578 std::string GetNameFromTSInterfaceDeclaration(ir::AstNode *node)
579 {
580     if (node == nullptr || !node->IsTSInterfaceDeclaration()) {
581         return "";
582     }
583     if (node->AsTSInterfaceDeclaration()->Id() == nullptr) {
584         return "";
585     }
586     return std::string(node->AsTSInterfaceDeclaration()->Id()->AsIdentifier()->Name());
587 }
588 
CreateDisplayForInterface(ir::AstNode * node)589 std::vector<SymbolDisplayPart> CreateDisplayForInterface(ir::AstNode *node)
590 {
591     std::vector<SymbolDisplayPart> displayParts;
592     if (node->Type() != ir::AstNodeType::TS_INTERFACE_DECLARATION) {
593         return displayParts;
594     }
595     displayParts.emplace_back(CreateKeyword("interface"));
596     displayParts.emplace_back(CreateSpace());
597     displayParts.emplace_back(CreateClassName(GetNameFromTSInterfaceDeclaration(node)));
598     return displayParts;
599 }
600 
CreateDisplayForTypeAlias(ir::AstNode * node)601 std::vector<SymbolDisplayPart> CreateDisplayForTypeAlias(ir::AstNode *node)
602 {
603     std::vector<SymbolDisplayPart> displayParts;
604     if (node->Type() != ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION) {
605         return displayParts;
606     }
607     displayParts.emplace_back(CreateKeyword("type"));
608     displayParts.emplace_back(CreateSpace());
609     displayParts.emplace_back(CreateClassName(std::string(node->AsTSTypeAliasDeclaration()->Id()->Name())));
610     displayParts.emplace_back(CreateSpace());
611     displayParts.emplace_back(CreateOperator("="));
612     displayParts.emplace_back(CreateSpace());
613 
614     auto typeAnnotation = node->AsTSTypeAliasDeclaration()->TypeAnnotation();
615     auto type = GetNameForTypeNode(typeAnnotation);
616     displayParts.emplace_back(CreateTypeName(type));
617     return displayParts;
618 }
619 
CreateDisplayForEnum(ir::AstNode * node)620 std::vector<SymbolDisplayPart> CreateDisplayForEnum(ir::AstNode *node)
621 {
622     std::vector<SymbolDisplayPart> displayParts;
623     if (node->Type() != ir::AstNodeType::TS_ENUM_DECLARATION) {
624         return displayParts;
625     }
626     displayParts.emplace_back(CreateKeyword("enum"));
627     displayParts.emplace_back(CreateSpace());
628     displayParts.emplace_back(CreateEnumName(std::string(node->AsTSEnumDeclaration()->Key()->Name())));
629     return displayParts;
630 }
631 
CreateDisplayOfFunctionParams(ir::AstNode * node)632 std::vector<SymbolDisplayPart> CreateDisplayOfFunctionParams(ir::AstNode *node)
633 {
634     std::vector<SymbolDisplayPart> displayParts;
635     if (node->Type() != ir::AstNodeType::SCRIPT_FUNCTION) {
636         return displayParts;
637     }
638     displayParts.emplace_back(CreatePunctuation("("));
639     auto functionParams = node->AsScriptFunction()->Params();
640     bool first = true;
641     for (auto param : functionParams) {
642         if (!first) {
643             displayParts.emplace_back(CreatePunctuation(","));
644             displayParts.emplace_back(CreateSpace());
645         }
646         displayParts.emplace_back(CreateFunctionParameter(std::string(param->AsETSParameterExpression()->Name())));
647         displayParts.emplace_back(CreatePunctuation(":"));
648         displayParts.emplace_back(CreateSpace());
649         displayParts.emplace_back(
650             CreateTypeParameter(GetNameForTypeNode(param->AsETSParameterExpression()->TypeAnnotation())));
651         first = false;
652     }
653     displayParts.emplace_back(CreatePunctuation(")"));
654     return displayParts;
655 }
656 
CreateDisplayOfTypeParams(const ark::ArenaVector<ark::es2panda::ir::TSTypeParameter * > & typeParams)657 std::vector<SymbolDisplayPart> CreateDisplayOfTypeParams(
658     const ark::ArenaVector<ark::es2panda::ir::TSTypeParameter *> &typeParams)
659 {
660     std::vector<SymbolDisplayPart> displayParts;
661     if (typeParams.empty()) {
662         return displayParts;
663     }
664     displayParts.emplace_back(CreatePunctuation("<"));
665     bool first = true;
666     for (auto param : typeParams) {
667         if (!first) {
668             displayParts.emplace_back(CreatePunctuation(","));
669             displayParts.emplace_back(CreateSpace());
670         }
671         displayParts.emplace_back(CreateTypeParameter(std::string(param->AsTSTypeParameter()->Name()->Name())));
672         first = false;
673     }
674     displayParts.emplace_back(CreatePunctuation(">"));
675     return displayParts;
676 }
677 
CreateDisplayOfReturnType(ark::es2panda::ir::TypeNode * returnType)678 std::vector<SymbolDisplayPart> CreateDisplayOfReturnType(ark::es2panda::ir::TypeNode *returnType)
679 {
680     std::vector<SymbolDisplayPart> displayParts;
681     displayParts.emplace_back(CreatePunctuation(":"));
682     displayParts.emplace_back(CreateSpace());
683     if (returnType == nullptr) {
684         displayParts.emplace_back(CreateReturnType("void"));
685         return displayParts;
686     }
687     if (returnType->Type() == ir::AstNodeType::ETS_TYPE_REFERENCE) {
688         auto part = returnType->AsETSTypeReference()->Part()->AsETSTypeReferencePart();
689         auto typeName = part->Name()->AsIdentifier()->Name();
690         displayParts.emplace_back(CreateReturnType(std::string(typeName)));
691     }
692     return displayParts;
693 }
694 
CreateDisplayOfTypeName(ir::AstNode * node)695 std::vector<SymbolDisplayPart> CreateDisplayOfTypeName(ir::AstNode *node)
696 {
697     std::vector<SymbolDisplayPart> displayParts;
698     std::string typeName(node->AsTSTypeParameter()->Name()->Name());
699     displayParts.emplace_back(CreateTypeParameter(typeName));
700     displayParts.emplace_back(CreateSpace());
701     displayParts.emplace_back(CreateKeyword("in"));
702     displayParts.emplace_back(CreateSpace());
703     return displayParts;
704 }
705 
CreateDisplayForTypeParameterOfSciprtFunction(ir::AstNode * node)706 std::vector<SymbolDisplayPart> CreateDisplayForTypeParameterOfSciprtFunction(ir::AstNode *node)
707 {
708     std::vector<SymbolDisplayPart> displayParts;
709     displayParts = CreateDisplayOfTypeName(node);
710 
711     auto grandParent = node->Parent()->Parent();
712     if (grandParent->Type() == ir::AstNodeType::SCRIPT_FUNCTION) {
713         auto parent = node->Parent();
714         displayParts.emplace_back(CreateFunctionName(std::string(grandParent->AsScriptFunction()->Id()->Name())));
715 
716         auto typeParam = parent->AsTSTypeParameterDeclaration()->Params();
717         auto displayOfTypeParams = CreateDisplayOfTypeParams(typeParam);
718         displayParts = MergeSymbolDisplayPart(displayParts, displayOfTypeParams);
719 
720         auto displayOfFunctionParam = CreateDisplayOfFunctionParams(grandParent);
721         displayParts = MergeSymbolDisplayPart(displayParts, displayOfFunctionParam);
722 
723         auto returnType = grandParent->AsScriptFunction()->ReturnTypeAnnotation();
724         auto displayOfReturnType = CreateDisplayOfReturnType(returnType);
725         displayParts = MergeSymbolDisplayPart(displayParts, displayOfReturnType);
726     }
727     return displayParts;
728 }
729 
CreateDisplayForTypeParameterOfClassDefinition(ir::AstNode * node)730 std::vector<SymbolDisplayPart> CreateDisplayForTypeParameterOfClassDefinition(ir::AstNode *node)
731 {
732     std::vector<SymbolDisplayPart> displayParts;
733     displayParts = CreateDisplayOfTypeName(node);
734 
735     auto grandParent = node->Parent()->Parent();
736     if (grandParent->Type() == ir::AstNodeType::CLASS_DEFINITION) {
737         auto definition = grandParent->AsClassDefinition();
738         displayParts.emplace_back(CreateClassName(std::string(definition->Ident()->Name())));
739 
740         auto typeParams = definition->TypeParams()->Params();
741         auto displayOfTypeParams = CreateDisplayOfTypeParams(typeParams);
742         displayParts = MergeSymbolDisplayPart(displayParts, displayOfTypeParams);
743     }
744     return displayParts;
745 }
746 
CreateDisplayForTypeParameterOfTypeAliasDeclaration(ir::AstNode * node)747 std::vector<SymbolDisplayPart> CreateDisplayForTypeParameterOfTypeAliasDeclaration(ir::AstNode *node)
748 {
749     std::vector<SymbolDisplayPart> displayParts;
750     displayParts = CreateDisplayOfTypeName(node);
751     displayParts.emplace_back(CreateKeyword("type"));
752     displayParts.emplace_back(CreateSpace());
753 
754     auto grandParent = node->Parent()->Parent();
755     if (grandParent->Type() == ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION) {
756         displayParts.emplace_back(CreateTypeName(std::string(grandParent->AsTSTypeAliasDeclaration()->Id()->Name())));
757         auto typeParams = node->Parent()->AsTSTypeParameterDeclaration()->Params();
758         auto displayOfTypeParams = CreateDisplayOfTypeParams(typeParams);
759         displayParts = MergeSymbolDisplayPart(displayParts, displayOfTypeParams);
760     }
761     return displayParts;
762 }
763 
CreateDisplayForTypeParameter(ir::AstNode * node)764 std::vector<SymbolDisplayPart> CreateDisplayForTypeParameter(ir::AstNode *node)
765 {
766     std::vector<SymbolDisplayPart> displayParts;
767     if (node->Type() != ir::AstNodeType::TS_TYPE_PARAMETER) {
768         return displayParts;
769     }
770     auto grandParent = node->Parent()->Parent();
771     if (grandParent->Type() == ir::AstNodeType::SCRIPT_FUNCTION) {
772         return CreateDisplayForTypeParameterOfSciprtFunction(node);
773     }
774     if (grandParent->Type() == ir::AstNodeType::CLASS_DEFINITION) {
775         return CreateDisplayForTypeParameterOfClassDefinition(node);
776     }
777     if (grandParent->Type() == ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION) {
778         return CreateDisplayForTypeParameterOfTypeAliasDeclaration(node);
779     }
780 
781     return displayParts;
782 }
783 
CreateDisplayForEnumMember(ir::AstNode * node)784 std::vector<SymbolDisplayPart> CreateDisplayForEnumMember(ir::AstNode *node)
785 {
786     std::vector<SymbolDisplayPart> displayParts;
787     if (node->Type() != ir::AstNodeType::TS_ENUM_MEMBER) {
788         return displayParts;
789     }
790     auto enumDecl = node->Parent()->AsTSEnumDeclaration()->Key()->Name();
791     auto enumMember = node->AsTSEnumMember()->Key()->AsIdentifier()->Name();
792     displayParts.emplace_back(CreateEnumName(std::string(enumDecl)));
793     displayParts.emplace_back(CreatePunctuation("."));
794     displayParts.emplace_back(CreateEnumMember(std::string(enumMember)));
795     displayParts.emplace_back(CreateSpace());
796     displayParts.emplace_back(CreateOperator("="));
797     displayParts.emplace_back(CreateSpace());
798     auto init = node->AsTSEnumMember()->Init();
799     if (init->Type() == ir::AstNodeType::NUMBER_LITERAL) {
800         displayParts.emplace_back(CreateText(std::string(init->AsNumberLiteral()->Str())));
801     }
802     if (init->Type() == ir::AstNodeType::STRING_LITERAL) {
803         displayParts.emplace_back(CreatePunctuation("\""));
804         std::string str(init->AsStringLiteral()->Str());
805         displayParts.emplace_back(CreateText(str));
806         displayParts.emplace_back(CreatePunctuation("\""));
807     }
808     // Only number and string literal is supported now
809     if (init->Type() == ir::AstNodeType::BIGINT_LITERAL) {
810         displayParts.emplace_back(CreateText(std::string(init->AsBigIntLiteral()->Str())));
811     }
812     if (init->Type() == ir::AstNodeType::BOOLEAN_LITERAL) {
813         displayParts.emplace_back(CreateText(init->AsBooleanLiteral()->Value() ? "true" : "false"));
814     }
815     if (init->Type() == ir::AstNodeType::CHAR_LITERAL) {
816         char charLiteral = init->AsCharLiteral()->Char();
817         std::string charToStr(1, charLiteral);
818         displayParts.emplace_back(charToStr);
819     }
820     if (init->Type() == ir::AstNodeType::NULL_LITERAL) {
821         displayParts.emplace_back(CreateText("null"));
822     }
823     if (init->Type() == ir::AstNodeType::UNDEFINED_LITERAL) {
824         displayParts.emplace_back(CreateText("undefined"));
825     }
826     if (init->Type() == ir::AstNodeType::REGEXP_LITERAL) {
827         displayParts.emplace_back(CreateText(std::string(init->AsRegExpLiteral()->Pattern())));
828     }
829     return displayParts;
830 }
831 
CreateDisplayForMethodDefinitionOfConstructor(ir::AstNode * node,const std::string & kindModifier)832 std::vector<SymbolDisplayPart> CreateDisplayForMethodDefinitionOfConstructor(ir::AstNode *node,
833                                                                              const std::string &kindModifier)
834 {
835     std::vector<SymbolDisplayPart> displayParts;
836     if (node->Parent()->Type() != ir::AstNodeType::CLASS_DEFINITION || kindModifier != "constructor") {
837         return displayParts;
838     }
839     displayParts.emplace_back(CreateKeyword(kindModifier));
840     displayParts.emplace_back(CreateSpace());
841     auto classDefinition = node->Parent();
842     auto className = classDefinition->AsClassDefinition()->Ident()->Name();
843     displayParts.emplace_back(CreateClassName(std::string(className)));
844     auto functionExpression = node->AsMethodDefinition()->Value()->AsFunctionExpression();
845     if (functionExpression == nullptr) {
846         return displayParts;
847     }
848     auto scriptFunction = functionExpression->Function();
849     if (scriptFunction->Type() == ir::AstNodeType::SCRIPT_FUNCTION) {
850         auto script = scriptFunction->AsScriptFunction();
851         auto typeParameter = script->TypeParams();
852         if (typeParameter != nullptr) {
853             auto params = typeParameter->AsTSTypeParameterDeclaration()->Params();
854             auto displayOfTypeParams = CreateDisplayOfTypeParams(params);
855             displayParts = MergeSymbolDisplayPart(displayParts, displayOfTypeParams);
856         }
857         auto returnType = script->ReturnTypeAnnotation();
858         auto displayOfReturnType = CreateDisplayOfReturnType(returnType);
859         displayParts = MergeSymbolDisplayPart(displayParts, displayOfReturnType);
860     }
861     return displayParts;
862 }
863 
CreateDisplayForMethodDefinitionOfGetterOrSetter(ir::AstNode * node,const std::string & kindModifier)864 std::vector<SymbolDisplayPart> CreateDisplayForMethodDefinitionOfGetterOrSetter(ir::AstNode *node,
865                                                                                 const std::string &kindModifier)
866 {
867     std::vector<SymbolDisplayPart> displayParts;
868     if (node->Parent()->Type() != ir::AstNodeType::CLASS_DEFINITION ||
869         (kindModifier != "setter" && kindModifier != "getter")) {
870         return displayParts;
871     }
872     displayParts.emplace_back(CreatePunctuation("("));
873     displayParts.emplace_back(CreateKeyword(kindModifier));
874     displayParts.emplace_back(CreatePunctuation(")"));
875     displayParts.emplace_back(CreateSpace());
876     auto classDefinition = node->Parent();
877     auto className = classDefinition->AsClassDefinition()->Ident()->Name();
878     displayParts.emplace_back(CreateClassName(std::string(className)));
879     displayParts.emplace_back(CreatePunctuation("."));
880     auto ident = node->AsMethodDefinition()->Key()->AsIdentifier();
881     if (ident == nullptr) {
882         return displayParts;
883     }
884     auto propertyName = ident->Name();
885     displayParts.emplace_back(CreateProperty(std::string(propertyName)));
886     displayParts.emplace_back(CreateSpace());
887 
888     auto functionExpression = node->AsMethodDefinition()->Value()->AsFunctionExpression();
889     if (functionExpression == nullptr) {
890         return displayParts;
891     }
892     auto scriptFunction = functionExpression->Function();
893     if (scriptFunction->Type() == ir::AstNodeType::SCRIPT_FUNCTION) {
894         auto script = scriptFunction->AsScriptFunction();
895         auto returnType = script->ReturnTypeAnnotation();
896         auto displayOfReturnType = CreateDisplayOfReturnType(returnType);
897         displayParts = MergeSymbolDisplayPart(displayParts, displayOfReturnType);
898     }
899 
900     return displayParts;
901 }
902 
CreateDisplayForMethodDefinitionOfInterfaceBody(ir::AstNode * node)903 std::vector<SymbolDisplayPart> CreateDisplayForMethodDefinitionOfInterfaceBody(ir::AstNode *node)
904 {
905     std::vector<SymbolDisplayPart> displayParts;
906     if (node->Parent()->Type() != ir::AstNodeType::TS_INTERFACE_BODY) {
907         return displayParts;
908     }
909     auto interfaceDecl = node->Parent()->Parent();
910     if (interfaceDecl != nullptr && interfaceDecl->Type() == ir::AstNodeType::TS_INTERFACE_DECLARATION) {
911         auto interfaceName = interfaceDecl->AsTSInterfaceDeclaration()->Id()->Name();
912         displayParts.emplace_back(CreateInterface(std::string(interfaceName)));
913         displayParts.emplace_back(CreatePunctuation("."));
914         auto propertyName = node->AsMethodDefinition()->Key()->AsIdentifier()->Name();
915         displayParts.emplace_back(CreateProperty(std::string(propertyName)));
916     }
917     auto functionExpression = node->AsMethodDefinition()->Value()->AsFunctionExpression();
918     if (functionExpression == nullptr) {
919         return displayParts;
920     }
921     auto scriptFunction = functionExpression->Function();
922     if (scriptFunction->Type() == ir::AstNodeType::SCRIPT_FUNCTION) {
923         auto script = scriptFunction->AsScriptFunction();
924         auto typeParameter = script->TypeParams();
925         if (typeParameter != nullptr) {
926             auto params = typeParameter->AsTSTypeParameterDeclaration()->Params();
927             auto displayOfTypeParams = CreateDisplayOfTypeParams(params);
928             displayParts = MergeSymbolDisplayPart(displayParts, displayOfTypeParams);
929         }
930         auto returnType = script->ReturnTypeAnnotation();
931         auto displayOfReturnType = CreateDisplayOfReturnType(returnType);
932         displayParts = MergeSymbolDisplayPart(displayParts, displayOfReturnType);
933     }
934     return displayParts;
935 }
936 
CreateDisplayForMethodDefinition(ir::AstNode * node,const std::string & kindModifier)937 std::vector<SymbolDisplayPart> CreateDisplayForMethodDefinition(ir::AstNode *node, const std::string &kindModifier)
938 {
939     std::vector<SymbolDisplayPart> displayParts;
940     if (node->Type() != ir::AstNodeType::METHOD_DEFINITION) {
941         return displayParts;
942     }
943     if (kindModifier == "constructor" && node->Parent()->Type() == ir::AstNodeType::CLASS_DEFINITION) {
944         return CreateDisplayForMethodDefinitionOfConstructor(node, kindModifier);
945     }
946     if ((kindModifier == "getter" || kindModifier == "setter") &&
947         node->Parent()->Type() == ir::AstNodeType::CLASS_DEFINITION) {
948         return CreateDisplayForMethodDefinitionOfGetterOrSetter(node, kindModifier);
949     }
950     if (node->Parent() != nullptr && node->Parent()->Type() == ir::AstNodeType::TS_INTERFACE_BODY) {
951         return CreateDisplayForMethodDefinitionOfInterfaceBody(node);
952     }
953     if (node->Parent() != nullptr && node->Parent()->IsClassDefinition()) {
954         auto className = node->Parent()->AsClassDefinition()->Ident()->Name();
955         if (className != "ETSGLOBAL") {
956             displayParts.emplace_back(CreateClassName(std::string(className)));
957             displayParts.emplace_back(CreatePunctuation("."));
958         } else {
959             displayParts.emplace_back(CreateKeyword("function"));
960             displayParts.emplace_back(CreateSpace());
961         }
962     }
963 
964     auto functionName = node->AsMethodDefinition()->Key()->AsIdentifier()->Name();
965     displayParts.emplace_back(CreateFunctionName(std::string(functionName)));
966 
967     if (node->AsMethodDefinition()->Value() == nullptr) {
968         return displayParts;
969     }
970     auto scriptFunction = node->AsMethodDefinition()->Value()->AsFunctionExpression()->Function();
971     if (scriptFunction == nullptr) {
972         return displayParts;
973     }
974     if (scriptFunction->Type() == ir::AstNodeType::SCRIPT_FUNCTION) {
975         auto script = scriptFunction->AsScriptFunction();
976         auto typeParameter = script->TypeParams();
977         if (typeParameter != nullptr) {
978             auto params = typeParameter->AsTSTypeParameterDeclaration()->Params();
979             auto displayOfTypeParams = CreateDisplayOfTypeParams(params);
980             displayParts = MergeSymbolDisplayPart(displayParts, displayOfTypeParams);
981         }
982 
983         auto displayOfFunctionParam = CreateDisplayOfFunctionParams(script);
984         displayParts = MergeSymbolDisplayPart(displayParts, displayOfFunctionParam);
985 
986         auto returnType = script->ReturnTypeAnnotation();
987         auto displayOfReturnType = CreateDisplayOfReturnType(returnType);
988         displayParts = MergeSymbolDisplayPart(displayParts, displayOfReturnType);
989     }
990     return displayParts;
991 }
992 
IsKindModifierInSet(const std::string & target)993 bool IsKindModifierInSet(const std::string &target)
994 {
995     static std::set<std::string> kindModifierSet = {"const", "static public declare const"};
996     return kindModifierSet.find(target) != kindModifierSet.end();
997 }
998 
CreateDisplayForClassProperty(ir::AstNode * node,const std::string & kindModifier)999 std::vector<SymbolDisplayPart> CreateDisplayForClassProperty(ir::AstNode *node, const std::string &kindModifier)
1000 {
1001     std::vector<SymbolDisplayPart> displayParts;
1002     if (node->Type() != ir::AstNodeType::CLASS_PROPERTY) {
1003         return displayParts;
1004     }
1005     auto classDef = node->Parent();
1006     if (classDef->Type() == ir::AstNodeType::CLASS_DEFINITION) {
1007         auto className = classDef->AsClassDefinition()->Ident()->Name();
1008         if (className != "ETSGLOBAL") {
1009             displayParts.emplace_back(CreateClassName(std::string(className)));
1010             displayParts.emplace_back(CreatePunctuation("."));
1011         } else if (IsKindModifierInSet(kindModifier)) {
1012             displayParts.emplace_back(CreateKeyword("const"));
1013             displayParts.emplace_back(CreateSpace());
1014         } else {
1015             displayParts.emplace_back(CreateKeyword("let"));
1016             displayParts.emplace_back(CreateSpace());
1017         }
1018         auto propertyName = node->AsClassProperty()->Key()->AsIdentifier()->Name();
1019         displayParts.emplace_back(CreateProperty(std::string(propertyName)));
1020         displayParts.emplace_back(CreatePunctuation(":"));
1021         displayParts.emplace_back(CreateSpace());
1022 
1023         auto typeAnnotation = node->AsClassProperty()->TypeAnnotation();
1024         std::string type;
1025         if (typeAnnotation == nullptr) {
1026             if (node->AsClassProperty()->Value() == nullptr ||
1027                 !node->AsClassProperty()->Value()->IsETSNewClassInstanceExpression()) {
1028                 displayParts.emplace_back(CreateTypeName("undefined"));
1029                 return displayParts;
1030             }
1031             auto newClassExpr = node->AsClassProperty()->Value()->AsETSNewClassInstanceExpression();
1032             if (newClassExpr != nullptr) {
1033                 type = std::string(newClassExpr->GetTypeRef()->AsETSTypeReference()->Part()->GetIdent()->Name());
1034             }
1035         } else {
1036             type = GetNameForTypeNode(typeAnnotation);
1037         }
1038         displayParts.emplace_back(CreateTypeName(type));
1039     }
1040     return displayParts;
1041 }
1042 
CreateDisplayForETSParameterExpression(ir::AstNode * node)1043 std::vector<SymbolDisplayPart> CreateDisplayForETSParameterExpression(ir::AstNode *node)
1044 {
1045     std::vector<SymbolDisplayPart> displayParts;
1046     if (node->Type() != ir::AstNodeType::ETS_PARAMETER_EXPRESSION) {
1047         return displayParts;
1048     }
1049     auto paramName = node->AsETSParameterExpression()->Name();
1050     displayParts.emplace_back(CreateFunctionParameter(std::string(paramName)));
1051     displayParts.emplace_back(CreatePunctuation(":"));
1052     displayParts.emplace_back(CreateSpace());
1053 
1054     auto typeAnnotation = node->AsETSParameterExpression()->TypeAnnotation();
1055     if (typeAnnotation == nullptr) {
1056         return displayParts;
1057     }
1058     auto type = GetNameForTypeNode(typeAnnotation);
1059     displayParts.emplace_back(CreateTypeName(type));
1060 
1061     return displayParts;
1062 }
1063 
CreateDisplayForImportDeclaration(ir::AstNode * node)1064 std::vector<SymbolDisplayPart> CreateDisplayForImportDeclaration(ir::AstNode *node)
1065 {
1066     std::vector<SymbolDisplayPart> displayParts;
1067     if (node->Type() != ir::AstNodeType::IMPORT_DECLARATION) {
1068         return displayParts;
1069     }
1070     displayParts.emplace_back(CreateKeyword("namespace"));
1071     displayParts.emplace_back(CreateSpace());
1072     auto specifiers = node->AsImportDeclaration()->Specifiers();
1073     bool first = true;
1074     for (auto spec : specifiers) {
1075         if (!first) {
1076             displayParts.emplace_back(CreatePunctuation(","));
1077             displayParts.emplace_back(CreateSpace());
1078         }
1079         if (spec->Type() == ir::AstNodeType::IMPORT_DEFAULT_SPECIFIER ||
1080             spec->Type() == ir::AstNodeType::IMPORT_NAMESPACE_SPECIFIER ||
1081             spec->Type() == ir::AstNodeType::IMPORT_SPECIFIER) {
1082             displayParts.emplace_back(CreateNamespace(std::string(spec->AsImportDefaultSpecifier()->Local()->Name())));
1083         }
1084         first = false;
1085     }
1086 
1087     return displayParts;
1088 }
1089 
GetQuickInfo(ir::AstNode * node,ir::AstNode * containerNode,ir::AstNode * nodeForQuickInfo,const std::string & fileName)1090 QuickInfo GetQuickInfo(ir::AstNode *node, ir::AstNode *containerNode, ir::AstNode *nodeForQuickInfo,
1091                        const std::string &fileName)
1092 {
1093     if (containerNode == nullptr || nodeForQuickInfo == nullptr || node == nullptr) {
1094         return QuickInfo();
1095     }
1096     auto kindModifiers = GetKindModifiers(node);
1097     TextSpan span(nodeForQuickInfo->Start().index, nodeForQuickInfo->End().index - nodeForQuickInfo->Start().index);
1098     auto nodeKind = GetNodeKind(node);
1099     std::vector<SymbolDisplayPart> displayParts;
1100 
1101     std::string kind;
1102     std::vector<SymbolDisplayPart> document;
1103     std::vector<DocTagInfo> tags;
1104 
1105     if (IsClass(node)) {
1106         displayParts = CreateDisplayForClass(node);
1107         kind = "class";
1108     } else if (node->Type() == ir::AstNodeType::ETS_PARAMETER_EXPRESSION) {
1109         displayParts = CreateDisplayForETSParameterExpression(node);
1110     } else if (node->Type() == ir::AstNodeType::CLASS_PROPERTY) {
1111         // After enum refactoring, enum declaration is transformed to a class declaration
1112         if (compiler::ClassDefinitionIsEnumTransformed(node->Parent())) {
1113             auto enumDecl = node->Parent()->AsClassDefinition()->OrigEnumDecl()->AsTSEnumDeclaration();
1114             auto enumMember = GetEnumMemberByName(enumDecl, node->AsClassProperty()->Key()->AsIdentifier()->Name());
1115             displayParts = CreateDisplayForEnumMember(enumMember);
1116         } else {
1117             displayParts = CreateDisplayForClassProperty(node, kindModifiers);
1118             kind = "property";
1119         }
1120     } else if (node->Type() == ir::AstNodeType::TS_INTERFACE_DECLARATION) {
1121         displayParts = CreateDisplayForInterface(node);
1122         kind = "interface";
1123     } else if (node->Type() == ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION) {
1124         displayParts = CreateDisplayForTypeAlias(node);
1125     } else if (node->Type() == ir::AstNodeType::TS_ENUM_DECLARATION) {
1126         displayParts = CreateDisplayForEnum(node);
1127     } else if (node->Type() == ir::AstNodeType::IMPORT_DECLARATION) {
1128         displayParts = CreateDisplayForImportDeclaration(node);
1129     } else if (node->Type() == ir::AstNodeType::TS_TYPE_PARAMETER) {
1130         displayParts = CreateDisplayForTypeParameter(node);
1131     } else if (node->Type() == ir::AstNodeType::METHOD_DEFINITION) {
1132         displayParts = CreateDisplayForMethodDefinition(node, kindModifiers);
1133         kind = "function";
1134         if (node->Parent() != nullptr && node->Parent()->Type() == ir::AstNodeType::TS_INTERFACE_BODY) {
1135             kind = "property";
1136         }
1137     }
1138     return QuickInfo(kind, kindModifiers, span, displayParts, document, tags, fileName);
1139 }
1140 
GetQuickInfoAtPositionImpl(es2panda_Context * context,size_t position,std::string fileName)1141 QuickInfo GetQuickInfoAtPositionImpl(es2panda_Context *context, size_t position, std::string fileName)
1142 {
1143     if (context == nullptr) {
1144         return QuickInfo();
1145     }
1146     auto touchingToken = GetTouchingToken(context, position, false);
1147     if (touchingToken == nullptr || touchingToken->IsProgram()) {
1148         return QuickInfo();
1149     }
1150     auto nodeForQuickInfo = GetTokenForQuickInfo(context, position);
1151     auto node = GetNodeAtLocationForQuickInfo(nodeForQuickInfo);
1152     auto object = GetContainingObjectLiteralNode(nodeForQuickInfo);
1153     auto nodeFileName = std::move(fileName);
1154     if (object != nullptr) {
1155         auto contextualTypeNode = GetContextualTypeNode(GetContainingObjectLiteralNode(nodeForQuickInfo)->Parent());
1156         if (contextualTypeNode != nullptr && contextualTypeNode->IsETSImportDeclaration()) {
1157             nodeFileName = GetNodeFileName(contextualTypeNode);
1158         }
1159     }
1160     if (node == nullptr) {
1161         return QuickInfo();
1162     }
1163 
1164     return GetQuickInfo(node, GetContainerNode(nodeForQuickInfo), nodeForQuickInfo, nodeFileName);
1165 }
1166 
1167 }  // namespace ark::es2panda::lsp