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