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 #ifndef ES2PANDA_LSP_INCLUDE_SIGNATURE_HELP_H 17 #define ES2PANDA_LSP_INCLUDE_SIGNATURE_HELP_H 18 19 #include "create_type_help_items.h" 20 #include <optional> 21 #include <utility> 22 #include <variant> 23 #include <vector> 24 #include <cstddef> 25 #include "cancellation_token.h" 26 #include "ir/astNode.h" 27 #include "public/es2panda_lib.h" 28 #include "public/public.h" 29 #include "signature_help_items.h" 30 31 namespace ark::es2panda::lsp { 32 33 enum class SignatureHelpTriggerCharacter { 34 COMMA, // Represents "," 35 OPENPAREN, // Represents "(" 36 LESSTHAN // Represents "<" 37 }; 38 enum class SignatureHelpRetriggerCharacter { 39 COMMA, // Represents "," 40 OPENPAREN, // Represents "(" 41 LESSTHAN, // Represents "<" 42 CLOSEPAREN // Represents ")" 43 }; 44 45 enum CandidateOrTypeKind { CANDIDATE, TYPEENUM }; 46 struct TypeInfo { 47 private: 48 CandidateOrTypeKind kind_; 49 const ir::AstNode *symbol_; 50 51 public: TypeInfoTypeInfo52 TypeInfo(CandidateOrTypeKind kind, const ir::AstNode *symbol) : kind_(kind), symbol_(symbol) {} 53 SetKindTypeInfo54 void SetKind(CandidateOrTypeKind newKind) 55 { 56 kind_ = newKind; 57 } SetSymbolTypeInfo58 void SetSymbol(const ir::AstNode *newSymbol) 59 { 60 symbol_ = newSymbol; 61 } GetKindTypeInfo62 CandidateOrTypeKind GetKind() const 63 { 64 return kind_; 65 } GetSymbolTypeInfo66 const ir::AstNode *GetSymbol() const 67 { 68 return symbol_; 69 } 70 71 TypeInfo() = default; 72 }; 73 74 struct CandidateInfo { 75 private: 76 CandidateOrTypeKind kind_; 77 std::vector<checker::Signature *> signatures_; 78 checker::Signature *resolvedSignature_; 79 80 public: CandidateInfoCandidateInfo81 CandidateInfo(CandidateOrTypeKind kind, std::vector<checker::Signature *> &signatures, 82 checker::Signature *resolvedSignature) 83 : kind_(kind), signatures_(signatures), resolvedSignature_(resolvedSignature) 84 { 85 } 86 SetKindCandidateInfo87 void SetKind(CandidateOrTypeKind newKind) 88 { 89 kind_ = newKind; 90 } SetSignaturesCandidateInfo91 void SetSignatures(const std::vector<checker::Signature *> &newSignatures) 92 { 93 signatures_ = newSignatures; 94 } SetResolvedSignatureCandidateInfo95 void SetResolvedSignature(checker::Signature *newResolvedSignature) 96 { 97 resolvedSignature_ = newResolvedSignature; 98 } GetKindCandidateInfo99 CandidateOrTypeKind GetKind() const 100 { 101 return kind_; 102 } GetSignaturesCandidateInfo103 std::vector<checker::Signature *> &GetSignatures() 104 { 105 return signatures_; 106 } GetResolvedSignatureCandidateInfo107 checker::Signature *GetResolvedSignature() 108 { 109 return resolvedSignature_; 110 } CandidateInfoCandidateInfo111 CandidateInfo() : kind_(CandidateOrTypeKind::CANDIDATE), resolvedSignature_(nullptr) {} 112 }; 113 114 using InfoType = std::variant<struct CandidateInfo, struct TypeInfo>; 115 116 struct SignatureHelpInvokedReason { 117 private: 118 const char *kind_ = "invoked"; 119 SignatureHelpTriggerCharacter triggerCharacter_; 120 121 public: SignatureHelpInvokedReasonSignatureHelpInvokedReason122 explicit SignatureHelpInvokedReason(SignatureHelpTriggerCharacter trigger) : triggerCharacter_(trigger) {} SignatureHelpInvokedReasonSignatureHelpInvokedReason123 SignatureHelpInvokedReason() : triggerCharacter_(SignatureHelpTriggerCharacter::LESSTHAN) {} 124 GetKindSignatureHelpInvokedReason125 const char *GetKind() const 126 { 127 return kind_; 128 } 129 GetTriggerCharacterSignatureHelpInvokedReason130 SignatureHelpTriggerCharacter GetTriggerCharacter() const 131 { 132 return triggerCharacter_; 133 } 134 SetTriggerCharacterSignatureHelpInvokedReason135 void SetTriggerCharacter(SignatureHelpTriggerCharacter newTriggerCharacter) 136 { 137 triggerCharacter_ = newTriggerCharacter; 138 } 139 }; 140 141 struct SignatureHelpCharacterTypedReason { 142 private: 143 const char *kind_ = "characterTyped"; 144 SignatureHelpTriggerCharacter triggerCharacter_; 145 146 public: SignatureHelpCharacterTypedReasonSignatureHelpCharacterTypedReason147 explicit SignatureHelpCharacterTypedReason() : triggerCharacter_(SignatureHelpTriggerCharacter::LESSTHAN) {} 148 GetKindSignatureHelpCharacterTypedReason149 const char *GetKind() const 150 { 151 return kind_; 152 } GetTriggerCharacterSignatureHelpCharacterTypedReason153 SignatureHelpTriggerCharacter GetTriggerCharacter() const 154 { 155 return triggerCharacter_; 156 } SetTriggerCharacterSignatureHelpCharacterTypedReason157 void SetTriggerCharacter(SignatureHelpTriggerCharacter newTriggerCharacter) 158 { 159 triggerCharacter_ = newTriggerCharacter; 160 } SignatureHelpCharacterTypedReasonSignatureHelpCharacterTypedReason161 explicit SignatureHelpCharacterTypedReason(SignatureHelpTriggerCharacter trigger) : triggerCharacter_(trigger) {} 162 }; 163 164 struct SignatureHelpRetriggeredReason { 165 private: 166 const char *kind_ = "retrigger"; 167 SignatureHelpRetriggerCharacter triggerCharacter_; 168 169 public: SignatureHelpRetriggeredReasonSignatureHelpRetriggeredReason170 SignatureHelpRetriggeredReason() : triggerCharacter_(SignatureHelpRetriggerCharacter::LESSTHAN) {} SignatureHelpRetriggeredReasonSignatureHelpRetriggeredReason171 explicit SignatureHelpRetriggeredReason(SignatureHelpRetriggerCharacter trigger) : triggerCharacter_(trigger) {} 172 GetKindSignatureHelpRetriggeredReason173 const char *GetKind() const 174 { 175 return kind_; 176 } GetTriggerCharacterSignatureHelpRetriggeredReason177 SignatureHelpRetriggerCharacter GetTriggerCharacter() const 178 { 179 return triggerCharacter_; 180 } SetTriggerCharacterSignatureHelpRetriggeredReason181 void SetTriggerCharacter(SignatureHelpRetriggerCharacter newTriggerCharacter) 182 { 183 triggerCharacter_ = newTriggerCharacter; 184 } 185 }; 186 187 using SignatureHelpTriggerReason = 188 std::variant<struct SignatureHelpInvokedReason, struct SignatureHelpCharacterTypedReason, 189 struct SignatureHelpRetriggeredReason>; 190 191 struct ContextualSignatureLocationInfo { 192 private: 193 std::vector<ArgumentListInfo> list_; 194 size_t argumentIndex_; 195 size_t argumentCount_; 196 TextSpan argumentsSpan_ = {0, 0}; 197 198 public: ContextualSignatureLocationInfoContextualSignatureLocationInfo199 ContextualSignatureLocationInfo(std::vector<ArgumentListInfo> &list, const size_t argumentIndex, 200 const size_t argumentCount, const TextSpan argumentsSpan) 201 : list_(list), argumentIndex_(argumentIndex), argumentCount_(argumentCount), argumentsSpan_(argumentsSpan) 202 { 203 } 204 SetListContextualSignatureLocationInfo205 void SetList(const std::vector<ArgumentListInfo> &newList) 206 { 207 list_ = newList; 208 } SetArgumentIndexContextualSignatureLocationInfo209 void SetArgumentIndex(size_t newArgumentIndex) 210 { 211 argumentIndex_ = newArgumentIndex; 212 } SetArgumentCountContextualSignatureLocationInfo213 void SetArgumentCount(size_t newArgumentCount) 214 { 215 argumentCount_ = newArgumentCount; 216 } SetArgumentsSpanContextualSignatureLocationInfo217 void SetArgumentsSpan(TextSpan newArgumentsSpan) 218 { 219 argumentsSpan_ = newArgumentsSpan; 220 } GetListContextualSignatureLocationInfo221 const std::vector<ArgumentListInfo> &GetList() const 222 { 223 return list_; 224 } GetArgumentIndexContextualSignatureLocationInfo225 size_t GetArgumentIndex() const 226 { 227 return argumentIndex_; 228 } GetArgumentCountContextualSignatureLocationInfo229 size_t GetArgumentCount() const 230 { 231 return argumentCount_; 232 } GetArgumentsSpanContextualSignatureLocationInfo233 const TextSpan &GetArgumentsSpan() const 234 { 235 return argumentsSpan_; 236 } ContextualSignatureLocationInfoContextualSignatureLocationInfo237 ContextualSignatureLocationInfo() : argumentIndex_(0), argumentCount_(0) {} 238 }; 239 240 struct ContextualSignatureLocationInfoWithNode { 241 private: 242 ir::AstNode *node_; 243 size_t argumentIndex_; 244 size_t argumentCount_; 245 TextSpan argumentsSpan_ = {0, 0}; 246 247 public: ContextualSignatureLocationInfoWithNodeContextualSignatureLocationInfoWithNode248 ContextualSignatureLocationInfoWithNode(ir::AstNode *node, const size_t argumentIndex, const size_t argumentCount, 249 const TextSpan argumentsSpan) 250 : node_(node), argumentIndex_(argumentIndex), argumentCount_(argumentCount), argumentsSpan_(argumentsSpan) 251 { 252 } 253 SetNodeContextualSignatureLocationInfoWithNode254 void SetNode(ir::AstNode *newNode) 255 { 256 node_ = newNode; 257 } SetArgumentIndexContextualSignatureLocationInfoWithNode258 void SetArgumentIndex(size_t newArgumentIndex) 259 { 260 argumentIndex_ = newArgumentIndex; 261 } SetArgumentCountContextualSignatureLocationInfoWithNode262 void SetArgumentCount(size_t newArgumentCount) 263 { 264 argumentCount_ = newArgumentCount; 265 } SetArgumentsSpanContextualSignatureLocationInfoWithNode266 void SetArgumentsSpan(TextSpan newArgumentsSpan) 267 { 268 argumentsSpan_ = newArgumentsSpan; 269 } GetNodeContextualSignatureLocationInfoWithNode270 ir::AstNode *GetNode() const 271 { 272 return node_; 273 } GetArgumentIndexContextualSignatureLocationInfoWithNode274 size_t GetArgumentIndex() const 275 { 276 return argumentIndex_; 277 } GetArgumentCountContextualSignatureLocationInfoWithNode278 size_t GetArgumentCount() const 279 { 280 return argumentCount_; 281 } GetArgumentsSpanContextualSignatureLocationInfoWithNode282 const TextSpan &GetArgumentsSpan() const 283 { 284 return argumentsSpan_; 285 } 286 }; 287 288 bool IsSyntacticOwner(const ir::AstNode *node); 289 size_t GetArgumentCount(ir::AstNode *node, bool ignoreTrailingComma); 290 ir::AstNode *GetHighestBinary(const ir::AstNode *node); 291 TextSpan CreateTextSpanForNode(const ir::AstNode *node); 292 size_t CountBinaryExpressionParameters(ir::AstNode *node); 293 std::vector<ArgumentListInfo> GetArgumentOrParameterListAndIndex(ir::AstNode *node, 294 std::vector<ArgumentListInfo> &list); 295 std::optional<ContextualSignatureLocationInfo> GetContextualSignatureLocationInfo(ir::AstNode *node); 296 std::optional<ArgumentListInfo> GetImmediatelyContainingArgumentInfo(ir::AstNode *node, size_t position); 297 std::optional<ArgumentListInfo> TryGetParameterInfo(ir::AstNode *node); 298 std::optional<ArgumentListInfo> GetImmediatelyContainingArgumentOrContextualParameterInfo(ir::AstNode *node, 299 size_t position, 300 ir::AstNode *parent); 301 std::optional<ArgumentListInfo> GetContainingArgumentInfo(ir::AstNode *node, size_t position, bool isManuallyInvoked); 302 size_t GetArgumentIndexForTemplatePiece(size_t spanIndex, ir::AstNode *node, size_t position); 303 ir::AstNode *GetChildListThatStartsWithOpenerToken(ir::AstNode *parent, ir::AstNode *openerToken); 304 ir::AstNode *FindTokenOnLeftOfPosition(es2panda_Context *context, size_t position); 305 306 SignatureHelpItems GetSignatureHelpItems(es2panda_Context *ctx, size_t position, 307 SignatureHelpTriggerReason triggeredReason, 308 CancellationToken cancellationToken); 309 std::optional<InfoType> GetCandidateOrTypeInfo(const std::optional<ArgumentListInfo> info, ir::AstNode *parent, 310 const bool onlyUseSyntacticOwners); 311 checker::Signature *GetResolvedSignatureForSignatureHelp(const ir::AstNode *call, const ir::AstNode *parent, 312 std::vector<checker::Signature *> &candidates); 313 314 } // namespace ark::es2panda::lsp 315 316 #endif 317