• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #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