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_name_or_dotted_name_span.h" 17 #include "get_adjusted_location.h" 18 #include <cstddef> 19 20 namespace ark::es2panda::lsp { IsRightSideOfPropertyAccess(ir::AstNode * node)21bool IsRightSideOfPropertyAccess(ir::AstNode *node) 22 { 23 ir::AstNode *parent = node->Parent(); 24 25 if (parent == nullptr) { 26 return false; 27 } 28 29 if (parent->Type() == ir::AstNodeType::MEMBER_EXPRESSION) { 30 auto *memberExpr = static_cast<ir::MemberExpression *>(parent); 31 return memberExpr->Property() == node; 32 } 33 34 if (parent->Type() == ir::AstNodeType::CALL_EXPRESSION) { 35 auto *callExpr = static_cast<ir::CallExpression *>(parent); 36 ir::AstNode *callee = callExpr->Callee(); 37 38 if (callee->Type() == ir::AstNodeType::MEMBER_EXPRESSION) { 39 auto *memberExpr = static_cast<ir::MemberExpression *>(callee); 40 return memberExpr->Property() == node; 41 } 42 } 43 44 return false; 45 } 46 IsNameOfModuleDeclaration(ir::AstNode * node)47bool IsNameOfModuleDeclaration(ir::AstNode *node) 48 { 49 ir::AstNode *parent = node->Parent(); 50 if (parent == nullptr || parent->Type() != ir::AstNodeType::TS_MODULE_DECLARATION) { 51 return false; 52 } 53 54 auto *moduleDecl = static_cast<ir::TSModuleDeclaration *>(parent); 55 return moduleDecl->Name() == node; 56 } 57 IsRightSideOfQualifiedName(ir::AstNode * node)58bool IsRightSideOfQualifiedName(ir::AstNode *node) 59 { 60 ir::AstNode *parent = node->Parent(); 61 if (parent == nullptr || (parent->Type() != ir::AstNodeType::TS_QUALIFIED_NAME && 62 parent->Type() != ir::AstNodeType::MEMBER_EXPRESSION)) { 63 return false; 64 } 65 66 if (parent->Type() == ir::AstNodeType::TS_QUALIFIED_NAME) { 67 auto *qualifiedName = static_cast<ir::TSQualifiedName *>(parent); 68 return qualifiedName->Right() == node; 69 } 70 71 if (parent->Type() == ir::AstNodeType::MEMBER_EXPRESSION) { 72 auto *memberExpr = static_cast<ir::MemberExpression *>(parent); 73 return memberExpr->Property() == node; 74 } 75 76 return false; 77 } 78 AscendToRootName(ir::AstNode * node)79ir::AstNode *AscendToRootName(ir::AstNode *node) 80 { 81 while (node != nullptr) { 82 if (IsRightSideOfPropertyAccess(node) || IsRightSideOfQualifiedName(node)) { 83 node = node->Parent(); 84 continue; 85 } 86 87 if (!IsNameOfModuleDeclaration(node)) { 88 break; 89 } 90 91 ir::AstNode *parentDecl = node->Parent(); 92 if (parentDecl == nullptr || parentDecl->Parent() == nullptr) { 93 break; 94 } 95 96 if (parentDecl->Parent()->Type() != ir::AstNodeType::TS_MODULE_DECLARATION) { 97 break; 98 } 99 100 auto *grandParent = static_cast<ir::TSModuleDeclaration *>(parentDecl->Parent()); 101 if (grandParent->Body() != parentDecl) { 102 break; 103 } 104 105 node = const_cast<ir::AstNode *>(static_cast<const ir::AstNode *>(grandParent->Name())); 106 } 107 108 return node; 109 } 110 GetNameOrDottedNameSpanImpl(es2panda_Context * context,int startPos)111TextSpan *GetNameOrDottedNameSpanImpl(es2panda_Context *context, int startPos) 112 { 113 ir::AstNode *astNode = ark::es2panda::lsp::GetTouchingPropertyName(context, startPos); 114 if (astNode == nullptr) { 115 return nullptr; 116 } 117 118 switch (astNode->Type()) { 119 case ir::AstNodeType::TS_QUALIFIED_NAME: 120 case ir::AstNodeType::STRING_LITERAL: 121 case ir::AstNodeType::TS_BOOLEAN_KEYWORD: 122 case ir::AstNodeType::TS_NULL_KEYWORD: 123 case ir::AstNodeType::SUPER_EXPRESSION: 124 case ir::AstNodeType::THIS_EXPRESSION: 125 case ir::AstNodeType::TS_THIS_TYPE: 126 case ir::AstNodeType::IDENTIFIER: 127 break; 128 default: 129 return nullptr; 130 } 131 132 auto nodeForStartPos = AscendToRootName(astNode); 133 if (nodeForStartPos == nullptr) { 134 return nullptr; 135 } 136 size_t start = nodeForStartPos->Start().index; 137 size_t end = nodeForStartPos->End().index; 138 if (start >= end) { 139 return nullptr; 140 } 141 142 auto span = new TextSpan(start, end - start); 143 return span; 144 } 145 } // namespace ark::es2panda::lsp