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 "get_adjusted_location.h"
17 #include "internal_api.h"
18 #include <cassert>
19 #include <string>
20 #include <vector>
21 #include "public/es2panda_lib.h"
22 #include "public/public.h"
23 #include "ir/astNodeFlags.h"
24 #include "utils/arena_containers.h"
25 #include "util/options.h"
26
27 using ark::es2panda::ir::AstNode;
28 using ark::es2panda::ir::AstNodeType;
29 using ark::es2panda::ir::ModifierFlags;
30
31 namespace ark::es2panda::lsp {
32
GetChildren(AstNode * node,ArenaAllocator * allocator)33 ArenaVector<AstNode *> GetChildren(AstNode *node, ArenaAllocator *allocator)
34 {
35 ArenaVector<AstNode *> children(allocator->Adapter());
36
37 if (node == nullptr) {
38 return children;
39 }
40
41 node->IterateRecursively([&children](const AstNode *current) {
42 if (current != nullptr) {
43 children.push_back(const_cast<AstNode *>(current));
44 }
45 });
46
47 return children;
48 }
49
GetTouchingPropertyName(es2panda_Context * context,size_t pos)50 AstNode *GetTouchingPropertyName(es2panda_Context *context, size_t pos)
51 {
52 AstNode *token = GetTouchingToken(context, pos, false);
53 if (token == nullptr) {
54 return nullptr;
55 }
56
57 if (token->IsCallExpression() && token->AsCallExpression()->Callee()->IsIdentifier()) {
58 return token->AsCallExpression()->Callee()->AsIdentifier();
59 }
60
61 if (token->IsProperty() || token->IsIdentifier()) {
62 return token;
63 }
64
65 if (token->IsClassDeclaration() || token->IsFunctionDeclaration() || token->IsTSConstructorType()) {
66 return token;
67 }
68
69 return nullptr;
70 }
71
IsDeclarationOrModifier(AstNode * node,AstNode * parent,bool forRename)72 bool IsDeclarationOrModifier(AstNode *node, AstNode *parent, bool forRename)
73 {
74 return (
75 // Modifier check
76 (IsModifier(node) && forRename && CanHaveModifiers(*parent) &&
77 (parent->Modifiers() & node->Modifiers()) != 0U) ||
78 // Class implementation check
79 (node->IsTSClassImplements() && (parent->IsClassDeclaration() || node->IsClassExpression())) ||
80 // Function declaration check
81 (node->IsFunctionDeclaration() && (parent->IsFunctionDeclaration() || node->IsFunctionExpression())) ||
82 // Interface declaration check
83 (node->IsTSInterfaceDeclaration() && parent->IsTSInterfaceDeclaration()) ||
84 // Enum declaration check
85 (node->IsTSEnumDeclaration() && parent->IsTSEnumDeclaration()) ||
86 // Type alias declaration check
87 (node->IsTSTypeAliasDeclaration() && parent->IsTSTypeAliasDeclaration()) ||
88 // Module and import namespace check
89 ((node->IsImportNamespaceSpecifier() || node->IsTSModuleDeclaration()) && parent->IsTSModuleDeclaration()) ||
90 // Import equals declaration check
91 (node->IsTSImportEqualsDeclaration() && parent->IsTSImportEqualsDeclaration()));
92 }
93
HandleTSAsExpression(AstNode * node,AstNode * parent,const ArenaVector<AstNode * > & parentChildren)94 std::optional<AstNode *> HandleTSAsExpression(AstNode *node, AstNode *parent,
95 const ArenaVector<AstNode *> &parentChildren)
96 {
97 if (!node->IsTSAsExpression()) {
98 return std::nullopt;
99 }
100 // Import/Export specifier check
101 if (parent->IsImportSpecifier() || parent->IsExportSpecifier() || parent->IsImportNamespaceSpecifier()) {
102 return std::make_optional(FindFirstIdentifier(parent, false, parentChildren));
103 }
104 // Export all declaration check
105 if (parent->IsExportAllDeclaration()) {
106 if (auto *exportClause = FindNodeOfType(parent, AstNodeType::EXPORT_SPECIFIER, parentChildren)) {
107 if (exportClause->AsExportSpecifier()->Local()->IsIdentifier() &&
108 exportClause->AsExportSpecifier()->Local()->AsIdentifier()->Name() == "*") {
109 return std::make_optional(FindFirstIdentifier(exportClause, false, parentChildren));
110 }
111 }
112 }
113 return std::nullopt;
114 }
115
HandleTSImportType(AstNode * node,AstNode * parent,const ArenaVector<AstNode * > & parentChildren,bool forRename,ArenaAllocator * allocator)116 std::optional<AstNode *> HandleTSImportType(AstNode *node, AstNode *parent,
117 const ArenaVector<AstNode *> &parentChildren, bool forRename,
118 ArenaAllocator *allocator)
119 {
120 if (!node->IsTSImportType()) {
121 return std::nullopt;
122 }
123 if (auto location = GetAdjustedLocationForDeclaration(parent->Parent(), forRename, parentChildren, allocator)) {
124 return location;
125 }
126
127 if (parent->IsExportAllDeclaration()) {
128 if (auto location = GetAdjustedLocationForExportDeclaration(parent, forRename, parentChildren)) {
129 return location;
130 }
131 }
132 return std::nullopt;
133 }
134
HandleImportDeclaration(AstNode * node,AstNode * parent,const ArenaVector<AstNode * > & parentChildren,bool forRename)135 std::optional<AstNode *> HandleImportDeclaration(AstNode *node, AstNode *parent,
136 const ArenaVector<AstNode *> &parentChildren, bool forRename)
137 {
138 if (!node->IsImportDeclaration() || !parent->IsImportDeclaration()) {
139 return std::nullopt;
140 }
141 return GetAdjustedLocationForImportDeclaration(parent, forRename, parentChildren);
142 }
143
HandleExportAllDeclaration(AstNode * node,AstNode * parent,bool forRename,const ArenaVector<AstNode * > & parentChildren)144 inline std::optional<AstNode *> HandleExportAllDeclaration(AstNode *node, AstNode *parent, bool forRename,
145 const ArenaVector<AstNode *> &parentChildren)
146 {
147 if (!node->IsExportAllDeclaration() || !parent->IsExportAllDeclaration()) {
148 return std::nullopt;
149 }
150 return GetAdjustedLocationForExportDeclaration(parent, forRename, parentChildren);
151 }
152
HandleTSClassImplements(AstNode * node,AstNode * parent)153 inline std::optional<AstNode *> HandleTSClassImplements(AstNode *node, AstNode *parent)
154 {
155 if (!node->IsTSClassImplements() || !parent->IsTSClassImplements()) {
156 return std::nullopt;
157 }
158 return GetAdjustedLocationForHeritageClause(parent);
159 }
160
HandleTSInferType(AstNode * node,AstNode * parent,const ArenaVector<AstNode * > & parentChildren)161 inline std::optional<AstNode *> HandleTSInferType(AstNode *node, AstNode *parent,
162 const ArenaVector<AstNode *> &parentChildren)
163 {
164 if (!node->IsTSInferType() || !parent->IsTSInferType()) {
165 return std::nullopt;
166 }
167 if (auto *typeParam = FindTypeParameter(parent, parentChildren)) {
168 return std::make_optional(FindFirstIdentifier(typeParam, false, parentChildren));
169 }
170 return std::nullopt;
171 }
172
HandleTSTypeParameterDeclaration(AstNode * parent,const ArenaVector<AstNode * > & parentChildren)173 inline std::optional<AstNode *> HandleTSTypeParameterDeclaration(AstNode *parent,
174 const ArenaVector<AstNode *> &parentChildren)
175 {
176 if (!parent->IsTSTypeParameterDeclaration() || !parent->Parent()->IsTSTypeParameterDeclaration()) {
177 return std::nullopt;
178 }
179 return std::make_optional(FindFirstIdentifier(parent, false, parentChildren));
180 }
181
HandleTSTypeOperator(AstNode * parent,const ArenaVector<AstNode * > & parentChildren)182 std::optional<AstNode *> HandleTSTypeOperator(AstNode *parent, const ArenaVector<AstNode *> &parentChildren)
183 {
184 if (!parent->IsTSTypeOperator()) {
185 return std::nullopt;
186 }
187 if (auto *typeRef = FindTypeReference(parent, parentChildren)) {
188 return std::make_optional(FindFirstIdentifier(typeRef, false, parentChildren));
189 }
190 if (auto *arrayType = FindArrayType(parent, parentChildren)) {
191 if (auto *elementType = FindTypeReference(arrayType, parentChildren)) {
192 return std::make_optional(FindFirstIdentifier(elementType, false, parentChildren));
193 }
194 }
195 return std::nullopt;
196 }
197
HandleBasicExpressions(AstNode * node,AstNode * parent,const ArenaVector<AstNode * > & parentChildren)198 std::optional<AstNode *> HandleBasicExpressions(AstNode *node, AstNode *parent,
199 const ArenaVector<AstNode *> &parentChildren)
200 {
201 if ((node->IsNewExpression() && parent->IsNewExpression()) ||
202 (node->IsTSVoidKeyword() && parent->IsTSVoidKeyword()) ||
203 (node->IsTypeofExpression() && parent->IsTypeofExpression()) ||
204 (node->IsAwaitExpression() && parent->IsAwaitExpression()) ||
205 (node->IsYieldExpression() && parent->IsYieldExpression())) {
206 if (auto *expr = FindFirstExpression(parent, parentChildren)) {
207 return std::make_optional(SkipOuterExpressions(expr));
208 }
209 }
210 return std::nullopt;
211 }
212
HandleBinaryExpressions(AstNode * node,AstNode * parent,const ArenaVector<AstNode * > & parentChildren)213 std::optional<AstNode *> HandleBinaryExpressions(AstNode *node, AstNode *parent,
214 const ArenaVector<AstNode *> &parentChildren)
215 {
216 if (!parent->IsBinaryExpression()) {
217 return std::nullopt;
218 }
219 if (node->IsTSTypeOperator() ||
220 (node->IsForInStatement() && parent->FindChild([node](AstNode *child) { return child == node; }) != nullptr)) {
221 auto *firstExpr = FindFirstExpression(parent, parentChildren);
222 if (auto *rightExpr = FindFirstExpressionAfter(parent, firstExpr, parentChildren)) {
223 return std::make_optional(SkipOuterExpressions(rightExpr));
224 }
225 }
226 return std::nullopt;
227 }
228
HandleForStatements(AstNode * node,AstNode * parent,const ArenaVector<AstNode * > & parentChildren)229 std::optional<AstNode *> HandleForStatements(AstNode *node, AstNode *parent,
230 const ArenaVector<AstNode *> &parentChildren)
231 {
232 if ((node->IsForInStatement() && parent->IsForInStatement()) ||
233 (node->IsForOfStatement() && parent->IsForOfStatement())) {
234 if (auto *expr = FindFirstExpression(parent, parentChildren)) {
235 return std::make_optional(SkipOuterExpressions(expr));
236 }
237 }
238 return std::nullopt;
239 }
240
HandleNonRenameExpressions(AstNode * node,AstNode * parent,const ArenaVector<AstNode * > & parentChildren,bool forRename)241 std::optional<AstNode *> HandleNonRenameExpressions(AstNode *node, AstNode *parent,
242 const ArenaVector<AstNode *> &parentChildren, bool forRename)
243 {
244 if (forRename) {
245 return std::nullopt;
246 }
247 // Try each handler in sequence
248 if (auto result = HandleBasicExpressions(node, parent, parentChildren)) {
249 return result;
250 }
251
252 if (auto result = HandleBinaryExpressions(node, parent, parentChildren)) {
253 return result;
254 }
255 // Handle type assertions
256 if (node->IsTSAsExpression() && parent->IsTSAsExpression() && parent->IsTSTypeReference()) {
257 return std::make_optional(FindFirstIdentifier(parent, false, parentChildren));
258 }
259 if (auto result = HandleForStatements(node, parent, parentChildren)) {
260 return result;
261 }
262 return std::nullopt;
263 }
264
HandleDefaultExport(AstNode * node,ArenaAllocator * allocator)265 std::optional<AstNode *> HandleDefaultExport(AstNode *node, ArenaAllocator *allocator)
266 {
267 if ((node->Modifiers() & ModifierFlags::DEFAULT_EXPORT) == 0U) {
268 return std::nullopt;
269 }
270 const std::array<AstNodeType, 21> declarationTypes = {AstNodeType::VARIABLE_DECLARATION,
271 AstNodeType::PROPERTY,
272 AstNodeType::FUNCTION_DECLARATION,
273 AstNodeType::CLASS_DECLARATION,
274 AstNodeType::TS_INTERFACE_DECLARATION,
275 AstNodeType::TS_ENUM_DECLARATION,
276 AstNodeType::TS_TYPE_ALIAS_DECLARATION,
277 AstNodeType::TS_TYPE_PARAMETER_DECLARATION,
278 AstNodeType::TS_MODULE_DECLARATION,
279 AstNodeType::TS_CONSTRUCTOR_TYPE,
280 AstNodeType::TS_TYPE_ASSERTION,
281 AstNodeType::TS_AS_EXPRESSION,
282 AstNodeType::TS_NON_NULL_EXPRESSION,
283 AstNodeType::BINARY_EXPRESSION,
284 AstNodeType::FOR_IN_STATEMENT,
285 AstNodeType::FOR_OF_STATEMENT,
286 AstNodeType::NEW_EXPRESSION,
287 AstNodeType::TS_VOID_KEYWORD,
288 AstNodeType::TYPEOF_EXPRESSION,
289 AstNodeType::AWAIT_EXPRESSION,
290 AstNodeType::YIELD_EXPRESSION};
291
292 auto children = GetChildren(node, allocator);
293 for (const auto type : declarationTypes) {
294 if (auto *declaration = FindNodeOfType(node, type, children)) {
295 return std::make_optional(declaration);
296 }
297 }
298 return std::nullopt;
299 }
300
HandleVariableDeclaration(AstNode * parent,const ArenaVector<AstNode * > & parentChildren)301 inline std::optional<AstNode *> HandleVariableDeclaration(AstNode *parent, const ArenaVector<AstNode *> &parentChildren)
302 {
303 if (parent->IsVariableDeclaration()) {
304 if (auto *identifier = FindFirstIdentifier(parent, false, parentChildren)) {
305 return std::make_optional(identifier);
306 }
307 }
308 return std::nullopt;
309 }
310
HandleExternalModuleReference(AstNode * parent,const ArenaVector<AstNode * > & parentChildren)311 inline std::optional<AstNode *> HandleExternalModuleReference(AstNode *parent,
312 const ArenaVector<AstNode *> &parentChildren)
313 {
314 if (parent->IsTSExternalModuleReference()) {
315 if (auto *expr = FindFirstExpression(parent, parentChildren)) {
316 return std::make_optional(expr);
317 }
318 }
319 return std::nullopt;
320 }
321
HandleModuleSpecifier(AstNode * parent,const ArenaVector<AstNode * > & parentChildren)322 inline std::optional<AstNode *> HandleModuleSpecifier(AstNode *parent, const ArenaVector<AstNode *> &parentChildren)
323 {
324 if ((parent->IsImportDeclaration() || parent->IsExportAllDeclaration())) {
325 if (auto *moduleSpecifier = FindNodeOfType(parent, AstNodeType::STRING_LITERAL, parentChildren)) {
326 return std::make_optional(moduleSpecifier);
327 }
328 }
329 return std::nullopt;
330 }
331
HandleExpressionAndTypes(AstNode * node,AstNode * parent,const ArenaVector<AstNode * > & parentChildren,bool forRename,ArenaAllocator * allocator)332 std::optional<AstNode *> HandleExpressionAndTypes(AstNode *node, AstNode *parent,
333 const ArenaVector<AstNode *> &parentChildren, bool forRename,
334 ArenaAllocator *allocator)
335 {
336 // Expression handlers
337 if (auto result = HandleTSAsExpression(node, parent, parentChildren)) {
338 return result;
339 }
340 if (auto result = HandleTSImportType(node, parent, parentChildren, forRename, allocator)) {
341 return result;
342 }
343
344 // Type system handlers
345 if (auto result = HandleTSClassImplements(node, parent)) {
346 return result;
347 }
348 if (auto result = HandleTSInferType(node, parent, parentChildren)) {
349 return result;
350 }
351 if (auto result = HandleTSTypeParameterDeclaration(parent, parentChildren)) {
352 return result;
353 }
354 if (auto result = HandleTSTypeOperator(parent, parentChildren)) {
355 return result;
356 }
357 return std::nullopt;
358 }
359
HandleModulesAndExports(AstNode * node,AstNode * parent,const ArenaVector<AstNode * > & parentChildren,bool forRename,ArenaAllocator * allocator)360 std::optional<AstNode *> HandleModulesAndExports(AstNode *node, AstNode *parent,
361 const ArenaVector<AstNode *> &parentChildren, bool forRename,
362 ArenaAllocator *allocator)
363 {
364 // Import/Export handlers
365 if (auto result = HandleImportDeclaration(node, parent, parentChildren, forRename)) {
366 return result;
367 }
368 if (auto result = HandleExportAllDeclaration(node, parent, forRename, parentChildren)) {
369 return result;
370 }
371 if (auto result = HandleExternalModuleReference(parent, parentChildren)) {
372 return result;
373 }
374 if (auto result = HandleModuleSpecifier(parent, parentChildren)) {
375 return result;
376 }
377 if (auto result = HandleDefaultExport(node, allocator)) {
378 return result;
379 }
380
381 return std::nullopt;
382 }
383
GetAdjustedLocation(AstNode * node,bool forRename,ArenaAllocator * allocator)384 std::optional<AstNode *> GetAdjustedLocation(AstNode *node, bool forRename, ArenaAllocator *allocator)
385 {
386 node = GetOriginalNode(node);
387 auto *parent = node->Parent();
388 if (parent == nullptr) {
389 return std::make_optional(node);
390 }
391
392 ArenaVector<AstNode *> parentChildren = GetChildren(parent, allocator);
393
394 // Declaration handlers
395 if (IsDeclarationOrModifier(node, parent, forRename)) {
396 if (auto location = GetAdjustedLocationForDeclaration(parent, forRename, parentChildren, allocator)) {
397 return location;
398 }
399 }
400 // Expression and Type handlers
401 if (auto result = HandleExpressionAndTypes(node, parent, parentChildren, forRename, allocator)) {
402 return result;
403 }
404 // Module and Export handlers
405 if (auto result = HandleModulesAndExports(node, parent, parentChildren, forRename, allocator)) {
406 return result;
407 }
408 // Variable handlers
409 if (auto result = HandleVariableDeclaration(parent, parentChildren)) {
410 return result;
411 }
412 if (auto result = HandleNonRenameExpressions(node, parent, parentChildren, forRename)) {
413 return result;
414 }
415 return std::make_optional(node);
416 }
417
GetAdjustedLocationForDeclaration(AstNode * node,bool forRename,const ArenaVector<AstNode * > & children,ArenaAllocator * allocator)418 std::optional<AstNode *> GetAdjustedLocationForDeclaration(AstNode *node, bool forRename,
419 const ArenaVector<AstNode *> &children,
420 ArenaAllocator *allocator)
421 {
422 if (!forRename) {
423 switch (node->Type()) {
424 case AstNodeType::CLASS_DECLARATION:
425 case AstNodeType::CLASS_EXPRESSION:
426 case AstNodeType::STRUCT_DECLARATION:
427 return GetAdjustedLocationForClass(node, allocator);
428 case AstNodeType::FUNCTION_DECLARATION:
429 case AstNodeType::FUNCTION_EXPRESSION:
430 return GetAdjustedLocationForFunction(node, allocator);
431 case AstNodeType::TS_CONSTRUCTOR_TYPE:
432 return std::make_optional(node);
433 default:
434 break;
435 }
436 }
437 if (node->IsExportNamedDeclaration()) {
438 return std::make_optional(FindFirstIdentifier(node, false, children));
439 }
440 return std::nullopt;
441 }
442
GetAdjustedLocationForImportDeclaration(AstNode * node,bool forRename,const ArenaVector<AstNode * > & children)443 std::optional<AstNode *> GetAdjustedLocationForImportDeclaration(AstNode *node, bool forRename,
444 const ArenaVector<AstNode *> &children)
445 {
446 if (!node->IsImportDeclaration()) {
447 return std::nullopt;
448 }
449 if (forRename) {
450 auto *importNode = node->FindChild(
451 [](AstNode *child) { return child->IsImportSpecifier() || child->IsImportNamespaceSpecifier(); });
452 if (importNode != nullptr) {
453 return std::make_optional(FindFirstIdentifier(importNode, false, children));
454 }
455 return std::nullopt;
456 }
457 auto *importNode = node->FindChild(
458 [](AstNode *child) { return child->IsImportSpecifier() || child->IsImportNamespaceSpecifier(); });
459 if (importNode != nullptr) {
460 if (auto *identifier = FindFirstIdentifier(importNode, false, children)) {
461 return std::make_optional(identifier);
462 }
463 return std::make_optional(importNode);
464 }
465 return std::nullopt;
466 }
467
GetAdjustedLocationForExportDeclaration(AstNode * node,bool forRename,const ArenaVector<AstNode * > & children)468 std::optional<AstNode *> GetAdjustedLocationForExportDeclaration(AstNode *node, bool forRename,
469 const ArenaVector<AstNode *> &children)
470 {
471 if (!node->IsExportAllDeclaration()) {
472 return std::nullopt;
473 }
474 if (forRename) {
475 return std::make_optional(FindFirstIdentifier(node, false, children));
476 }
477 auto *exportSpecifier = FindNodeOfType(node, AstNodeType::EXPORT_SPECIFIER, children);
478 if (exportSpecifier != nullptr) {
479 if (auto *identifier = FindFirstIdentifier(exportSpecifier, false, children)) {
480 return std::make_optional(identifier);
481 }
482 return std::make_optional(exportSpecifier);
483 }
484 if ((node->Modifiers() & ModifierFlags::DEFAULT_EXPORT) != 0U) {
485 const std::array<AstNodeType, 21> declarationTypes = {AstNodeType::VARIABLE_DECLARATION,
486 AstNodeType::PROPERTY,
487 AstNodeType::FUNCTION_DECLARATION,
488 AstNodeType::CLASS_DECLARATION,
489 AstNodeType::TS_INTERFACE_DECLARATION,
490 AstNodeType::TS_ENUM_DECLARATION,
491 AstNodeType::TS_TYPE_ALIAS_DECLARATION,
492 AstNodeType::TS_TYPE_PARAMETER_DECLARATION,
493 AstNodeType::TS_MODULE_DECLARATION,
494 AstNodeType::TS_CONSTRUCTOR_TYPE,
495 AstNodeType::TS_TYPE_ASSERTION,
496 AstNodeType::TS_AS_EXPRESSION,
497 AstNodeType::TS_NON_NULL_EXPRESSION,
498 AstNodeType::BINARY_EXPRESSION,
499 AstNodeType::FOR_IN_STATEMENT,
500 AstNodeType::FOR_OF_STATEMENT,
501 AstNodeType::NEW_EXPRESSION,
502 AstNodeType::TS_VOID_KEYWORD,
503 AstNodeType::TYPEOF_EXPRESSION,
504 AstNodeType::AWAIT_EXPRESSION,
505 AstNodeType::YIELD_EXPRESSION};
506
507 for (const auto type : declarationTypes) {
508 if (auto *declaration = FindNodeOfType(node, type, children)) {
509 return std::make_optional(declaration);
510 }
511 }
512 }
513 return std::nullopt;
514 }
515
GetAdjustedLocationForClass(AstNode * node,ArenaAllocator * allocator)516 std::optional<AstNode *> GetAdjustedLocationForClass(AstNode *node, ArenaAllocator *allocator)
517 {
518 if (node == nullptr || (!node->IsClassDeclaration() && !node->IsClassExpression())) {
519 return std::nullopt;
520 }
521 auto children = GetChildren(node, allocator);
522 return std::make_optional(FindFirstIdentifier(node, false, children));
523 }
524
GetAdjustedLocationForFunction(AstNode * node,ArenaAllocator * allocator)525 std::optional<AstNode *> GetAdjustedLocationForFunction(AstNode *node, ArenaAllocator *allocator)
526 {
527 if (node->IsIdentifier()) {
528 return std::make_optional(node);
529 }
530 if (node->IsFunctionDeclaration()) {
531 auto children = GetChildren(node, allocator);
532 return std::make_optional(FindFirstIdentifier(node, false, children));
533 }
534 if (auto *parent = node->Parent()) {
535 if (parent->IsFunctionDeclaration()) {
536 auto children = GetChildren(parent, allocator);
537 return std::make_optional(FindFirstIdentifier(parent, false, children));
538 }
539 }
540 return std::nullopt;
541 }
542
IsModifier(const AstNode * node)543 bool IsModifier(const AstNode *node)
544 {
545 if (node == nullptr) {
546 return false;
547 }
548 switch (node->Modifiers()) {
549 case ModifierFlags::ABSTRACT:
550 case ModifierFlags::ACCESS:
551 case ModifierFlags::ASYNC:
552 case ModifierFlags::CONST:
553 case ModifierFlags::DECLARE:
554 case ModifierFlags::DEFAULT_EXPORT:
555 case ModifierFlags::IN:
556 case ModifierFlags::EXPORT:
557 case ModifierFlags::PUBLIC:
558 case ModifierFlags::PRIVATE:
559 case ModifierFlags::PROTECTED:
560 case ModifierFlags::READONLY:
561 case ModifierFlags::STATIC:
562 case ModifierFlags::OUT:
563 case ModifierFlags::OVERRIDE:
564 return true;
565 default:
566 return false;
567 }
568 }
569
IsOuterExpression(const AstNode * node)570 bool IsOuterExpression(const AstNode *node)
571 {
572 if (node == nullptr) {
573 return false;
574 }
575 switch (node->Type()) {
576 case AstNodeType::TS_TYPE_ASSERTION:
577 case AstNodeType::TS_AS_EXPRESSION:
578 case AstNodeType::TS_NON_NULL_EXPRESSION:
579 return true;
580 default:
581 return false;
582 }
583 }
584
SkipOuterExpressions(AstNode * node)585 AstNode *SkipOuterExpressions(AstNode *node)
586 {
587 if (node == nullptr) {
588 return node;
589 }
590 if (node->IsExpression() && IsOuterExpression(node)) {
591 return node;
592 }
593 return node;
594 }
595
GetAdjustedLocationForHeritageClause(AstNode * node)596 std::optional<AstNode *> GetAdjustedLocationForHeritageClause(AstNode *node)
597 {
598 if (node == nullptr || node->Type() != AstNodeType::TS_INTERFACE_HERITAGE) {
599 return std::nullopt;
600 }
601 auto *expression = node->FindChild(
602 [](AstNode *child) { return child->IsExpression() || child->IsIdentifier() || child->IsTSTypeReference(); });
603 return expression != nullptr ? std::make_optional(expression) : std::nullopt;
604 }
605
CanHaveModifiers(const AstNode & node)606 bool CanHaveModifiers(const AstNode &node)
607 {
608 switch (node.Type()) {
609 case AstNodeType::CLASS_DECLARATION:
610 case AstNodeType::FUNCTION_DECLARATION:
611 case AstNodeType::METHOD_DEFINITION:
612 case AstNodeType::PROPERTY:
613 case AstNodeType::TS_CONSTRUCTOR_TYPE:
614 case AstNodeType::TS_INTERFACE_DECLARATION:
615 case AstNodeType::TS_TYPE_ALIAS_DECLARATION:
616 case AstNodeType::TS_ENUM_DECLARATION:
617 case AstNodeType::TS_MODULE_DECLARATION:
618 case AstNodeType::VARIABLE_DECLARATION:
619 return true;
620 default:
621 return false;
622 }
623 }
624
FindFirstIdentifier(AstNode * node,bool skipModifiers,const ArenaVector<AstNode * > & children)625 AstNode *FindFirstIdentifier(AstNode *node, bool skipModifiers, const ArenaVector<AstNode *> &children)
626 {
627 if (node->IsIdentifier() && (!skipModifiers || !IsModifier(node))) {
628 return node;
629 }
630 for (auto *child : children) {
631 if (child->IsIdentifier() && (!skipModifiers || !IsModifier(child))) {
632 return child;
633 }
634 }
635 return nullptr;
636 }
637
FindFirstExpression(AstNode * node,const ArenaVector<AstNode * > & children)638 AstNode *FindFirstExpression(AstNode *node, const ArenaVector<AstNode *> &children)
639 {
640 if (node->IsExpression()) {
641 return node;
642 }
643 for (auto *child : children) {
644 if (child->IsExpression()) {
645 return child;
646 }
647 }
648 return nullptr;
649 }
650
FindFirstExpressionAfter(AstNode * node,AstNode * after,const ArenaVector<AstNode * > & children)651 AstNode *FindFirstExpressionAfter(AstNode *node, AstNode *after, const ArenaVector<AstNode *> &children)
652 {
653 if (node->IsExpression() && node != after) {
654 return node;
655 }
656 bool foundAfter = false;
657 for (auto *child : children) {
658 if (child == after) {
659 foundAfter = true;
660 continue;
661 }
662 if (foundAfter && child->IsExpression()) {
663 return child;
664 }
665 }
666 return nullptr;
667 }
668
FindNodeOfType(AstNode * node,AstNodeType type,const ArenaVector<AstNode * > & children)669 AstNode *FindNodeOfType(AstNode *node, AstNodeType type, const ArenaVector<AstNode *> &children)
670 {
671 if (node->Type() == type) {
672 return node;
673 }
674 for (auto *child : children) {
675 if (child->Type() == type) {
676 return child;
677 }
678 }
679 return nullptr;
680 }
681
FindTypeReference(AstNode * node,const ArenaVector<AstNode * > & children)682 AstNode *FindTypeReference(AstNode *node, const ArenaVector<AstNode *> &children)
683 {
684 if (node != nullptr && node->IsTSTypeReference()) {
685 return node;
686 }
687 for (auto *child : children) {
688 if (child->IsTSTypeReference()) {
689 return child;
690 }
691 }
692 return nullptr;
693 }
694
FindTypeParameter(AstNode * node,const ArenaVector<AstNode * > & children)695 AstNode *FindTypeParameter(AstNode *node, const ArenaVector<AstNode *> &children)
696 {
697 if (node->IsTSTypeParameterDeclaration()) {
698 return node;
699 }
700
701 for (auto *child : children) {
702 if (child->IsTSTypeParameterDeclaration()) {
703 return child;
704 }
705 if (child->IsIdentifier() && child->AsIdentifier()->Name() == "T") {
706 return child;
707 }
708 }
709
710 return nullptr;
711 }
712
FindArrayType(AstNode * node,const ArenaVector<AstNode * > & children)713 AstNode *FindArrayType(AstNode *node, const ArenaVector<AstNode *> &children)
714 {
715 if (node->IsTSArrayType()) {
716 return node;
717 }
718 for (auto *child : children) {
719 if (child->IsTSArrayType()) {
720 return child;
721 }
722 }
723 return nullptr;
724 }
725
726 } // namespace ark::es2panda::lsp