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 "internal_api.h"
17 #include "rename.h"
18 #include "public/public.h"
19 #include "script_element_kind.h"
20 #include "compiler/lowering/util.h"
21
22 namespace ark::es2panda::lsp {
GetTargetTokenKindIfETSType(ir::AstNodeType type)23 std::tuple<bool, CompletionEntryKind> GetTargetTokenKindIfETSType(ir::AstNodeType type)
24 {
25 switch (type) {
26 case ir::AstNodeType::ETS_NULL_TYPE:
27 case ir::AstNodeType::ETS_UNDEFINED_TYPE:
28 case ir::AstNodeType::ETS_NEVER_TYPE:
29 case ir::AstNodeType::ETS_STRING_LITERAL_TYPE:
30 return std::make_tuple(true, CompletionEntryKind::VALUE);
31 case ir::AstNodeType::ETS_PRIMITIVE_TYPE:
32 case ir::AstNodeType::ETS_CLASS_LITERAL:
33 case ir::AstNodeType::ETS_KEYOF_TYPE:
34 return std::make_tuple(true, CompletionEntryKind::KEYWORD);
35 case ir::AstNodeType::ETS_NEW_ARRAY_INSTANCE_EXPRESSION:
36 case ir::AstNodeType::ETS_NEW_MULTI_DIM_ARRAY_INSTANCE_EXPRESSION:
37 case ir::AstNodeType::ETS_NEW_CLASS_INSTANCE_EXPRESSION:
38 case ir::AstNodeType::ETS_PARAMETER_EXPRESSION:
39 case ir::AstNodeType::ETS_TUPLE:
40 return std::make_tuple(true, CompletionEntryKind::OPERATOR);
41 case ir::AstNodeType::ETS_FUNCTION_TYPE:
42 return std::make_tuple(true, CompletionEntryKind::FUNCTION);
43 case ir::AstNodeType::ETS_PACKAGE_DECLARATION:
44 case ir::AstNodeType::ETS_IMPORT_DECLARATION:
45 case ir::AstNodeType::ETS_MODULE:
46 return std::make_tuple(true, CompletionEntryKind::MODULE);
47 case ir::AstNodeType::ETS_TYPE_REFERENCE:
48 case ir::AstNodeType::ETS_TYPE_REFERENCE_PART:
49 return std::make_tuple(true, CompletionEntryKind::REFERENCE);
50 case ir::AstNodeType::ETS_WILDCARD_TYPE:
51 return std::make_tuple(true, CompletionEntryKind::TEXT);
52 case ir::AstNodeType::ETS_UNION_TYPE:
53 return std::make_tuple(true, CompletionEntryKind::TYPE_PARAMETER);
54 default:
55 break;
56 }
57 return std::make_tuple(false, CompletionEntryKind::ALIAS_TYPE);
58 }
59
IsTSParameterKind(ir::AstNodeType type)60 bool IsTSParameterKind(ir::AstNodeType type)
61 {
62 switch (type) {
63 case ir::AstNodeType::TS_ARRAY_TYPE:
64 case ir::AstNodeType::TS_UNION_TYPE:
65 case ir::AstNodeType::TS_INTERSECTION_TYPE:
66 case ir::AstNodeType::TS_LITERAL_TYPE:
67 case ir::AstNodeType::TS_MAPPED_TYPE:
68 case ir::AstNodeType::TS_THIS_TYPE:
69 case ir::AstNodeType::TS_TYPE_PARAMETER:
70 case ir::AstNodeType::TS_TYPE_PARAMETER_DECLARATION:
71 case ir::AstNodeType::TS_TYPE_PARAMETER_INSTANTIATION:
72 case ir::AstNodeType::TS_TYPE_PREDICATE:
73 case ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION:
74 case ir::AstNodeType::TS_TYPE_REFERENCE:
75 case ir::AstNodeType::TS_INDEXED_ACCESS_TYPE:
76 case ir::AstNodeType::TS_TUPLE_TYPE:
77 return true;
78 default:
79 break;
80 }
81 return false;
82 }
83
IsTSMoudleKind(ir::AstNodeType type)84 bool IsTSMoudleKind(ir::AstNodeType type)
85 {
86 switch (type) {
87 case ir::AstNodeType::TS_IMPORT_TYPE:
88 case ir::AstNodeType::TS_MODULE_BLOCK:
89 case ir::AstNodeType::TS_EXTERNAL_MODULE_REFERENCE:
90 case ir::AstNodeType::TS_MODULE_DECLARATION:
91 case ir::AstNodeType::TS_IMPORT_EQUALS_DECLARATION:
92 return true;
93 default:
94 break;
95 }
96 return false;
97 }
98
GetTargetTokenKindIfTSType(ir::AstNodeType type)99 std::tuple<bool, CompletionEntryKind> GetTargetTokenKindIfTSType(ir::AstNodeType type)
100 {
101 auto reuslt = std::make_tuple(false, CompletionEntryKind::ALIAS_TYPE);
102 if (IsValidAncestorType(type)) {
103 reuslt = std::make_tuple(true, CompletionEntryKind::KEYWORD);
104 } else if (IsTSParameterKind(type)) {
105 reuslt = std::make_tuple(true, CompletionEntryKind::TYPE_PARAMETER);
106 } else if (IsTSMoudleKind(type)) {
107 reuslt = std::make_tuple(true, CompletionEntryKind::MODULE);
108 }
109 switch (type) {
110 case ir::AstNodeType::TS_ENUM_DECLARATION:
111 return std::make_tuple(true, CompletionEntryKind::ENUM);
112 case ir::AstNodeType::TS_ENUM_MEMBER:
113 return std::make_tuple(true, CompletionEntryKind::ENUM_MEMBER);
114 case ir::AstNodeType::TS_NON_NULL_EXPRESSION:
115 case ir::AstNodeType::TS_TYPE_OPERATOR:
116 case ir::AstNodeType::TS_AS_EXPRESSION:
117 return std::make_tuple(true, CompletionEntryKind::OPERATOR);
118 case ir::AstNodeType::TS_TYPE_LITERAL:
119 return std::make_tuple(true, CompletionEntryKind::VALUE);
120 case ir::AstNodeType::TS_PROPERTY_SIGNATURE:
121 return std::make_tuple(true, CompletionEntryKind::PROPERTY);
122 case ir::AstNodeType::TS_METHOD_SIGNATURE:
123 return std::make_tuple(true, CompletionEntryKind::METHOD);
124 case ir::AstNodeType::TS_FUNCTION_TYPE:
125 return std::make_tuple(true, CompletionEntryKind::FUNCTION);
126 case ir::AstNodeType::TS_CONSTRUCTOR_TYPE:
127 return std::make_tuple(true, CompletionEntryKind::CONSTRUCTOR);
128 case ir::AstNodeType::TS_NAMED_TUPLE_MEMBER:
129 return std::make_tuple(true, CompletionEntryKind::VALUE);
130 case ir::AstNodeType::TS_INTERFACE_DECLARATION:
131 case ir::AstNodeType::TS_INTERFACE_BODY:
132 case ir::AstNodeType::TS_INTERFACE_HERITAGE:
133 return std::make_tuple(true, CompletionEntryKind::INTERFACE);
134 case ir::AstNodeType::TS_SIGNATURE_DECLARATION:
135 case ir::AstNodeType::TS_PARENT_TYPE:
136 case ir::AstNodeType::TS_INFER_TYPE:
137 case ir::AstNodeType::TS_CONDITIONAL_TYPE:
138 case ir::AstNodeType::TS_PARAMETER_PROPERTY:
139 case ir::AstNodeType::TS_QUALIFIED_NAME:
140 case ir::AstNodeType::TS_INDEX_SIGNATURE:
141 case ir::AstNodeType::TS_TYPE_QUERY:
142 case ir::AstNodeType::TS_CLASS_IMPLEMENTS:
143 case ir::AstNodeType::TS_TYPE_ASSERTION:
144 return std::make_tuple(true, CompletionEntryKind::TEXT);
145 default:
146 break;
147 }
148 return reuslt;
149 }
150
IsExpress(ir::AstNodeType type)151 bool IsExpress(ir::AstNodeType type)
152 {
153 switch (type) {
154 case ir::AstNodeType::ARROW_FUNCTION_EXPRESSION:
155 case ir::AstNodeType::AWAIT_EXPRESSION:
156 case ir::AstNodeType::BINARY_EXPRESSION:
157 case ir::AstNodeType::CALL_EXPRESSION:
158 case ir::AstNodeType::CHAIN_EXPRESSION:
159 case ir::AstNodeType::CLASS_EXPRESSION:
160 case ir::AstNodeType::CONDITIONAL_EXPRESSION:
161 case ir::AstNodeType::DIRECT_EVAL:
162 case ir::AstNodeType::FUNCTION_EXPRESSION:
163 case ir::AstNodeType::MEMBER_EXPRESSION:
164 case ir::AstNodeType::META_PROPERTY_EXPRESSION:
165 case ir::AstNodeType::NEW_EXPRESSION:
166 case ir::AstNodeType::OMITTED_EXPRESSION:
167 case ir::AstNodeType::PREFIX_ASSERTION_EXPRESSION:
168 case ir::AstNodeType::SEQUENCE_EXPRESSION:
169 case ir::AstNodeType::SUPER_EXPRESSION:
170 case ir::AstNodeType::TAGGED_TEMPLATE_EXPRESSION:
171 case ir::AstNodeType::THIS_EXPRESSION:
172 case ir::AstNodeType::TYPEOF_EXPRESSION:
173 case ir::AstNodeType::UNARY_EXPRESSION:
174 case ir::AstNodeType::UPDATE_EXPRESSION:
175 case ir::AstNodeType::YIELD_EXPRESSION:
176 case ir::AstNodeType::BLOCK_EXPRESSION:
177 return true;
178 default:
179 break;
180 }
181 return false;
182 }
183
IsStatement(ir::AstNodeType type)184 bool IsStatement(ir::AstNodeType type)
185 {
186 switch (type) {
187 case ir::AstNodeType::ASSERT_STATEMENT:
188 case ir::AstNodeType::CONTINUE_STATEMENT:
189 case ir::AstNodeType::IF_STATEMENT:
190 case ir::AstNodeType::DEBUGGER_STATEMENT:
191 case ir::AstNodeType::DO_WHILE_STATEMENT:
192 case ir::AstNodeType::EMPTY_STATEMENT:
193 case ir::AstNodeType::EXPRESSION_STATEMENT:
194 case ir::AstNodeType::BLOCK_STATEMENT:
195 case ir::AstNodeType::BREAK_STATEMENT:
196 case ir::AstNodeType::CATCH_CLAUSE:
197 case ir::AstNodeType::FOR_IN_STATEMENT:
198 case ir::AstNodeType::FOR_OF_STATEMENT:
199 case ir::AstNodeType::FOR_UPDATE_STATEMENT:
200 case ir::AstNodeType::REEXPORT_STATEMENT:
201 case ir::AstNodeType::RETURN_STATEMENT:
202 case ir::AstNodeType::LABELLED_STATEMENT:
203 case ir::AstNodeType::SWITCH_CASE_STATEMENT:
204 case ir::AstNodeType::SWITCH_STATEMENT:
205 case ir::AstNodeType::THROW_STATEMENT:
206 case ir::AstNodeType::TRY_STATEMENT:
207 case ir::AstNodeType::WHILE_STATEMENT:
208 return true;
209 default:
210 break;
211 }
212 return false;
213 }
214
IsLiteral(ir::AstNodeType type)215 bool IsLiteral(ir::AstNodeType type)
216 {
217 switch (type) {
218 case ir::AstNodeType::BIGINT_LITERAL:
219 case ir::AstNodeType::BOOLEAN_LITERAL:
220 case ir::AstNodeType::CHAR_LITERAL:
221 case ir::AstNodeType::NULL_LITERAL:
222 case ir::AstNodeType::UNDEFINED_LITERAL:
223 case ir::AstNodeType::NUMBER_LITERAL:
224 case ir::AstNodeType::REGEXP_LITERAL:
225 case ir::AstNodeType::STRING_LITERAL:
226 case ir::AstNodeType::TEMPLATE_LITERAL:
227 return true;
228 default:
229 break;
230 }
231 return false;
232 }
233
IsModule(ir::AstNodeType type)234 bool IsModule(ir::AstNodeType type)
235 {
236 switch (type) {
237 case ir::AstNodeType::EXPORT_ALL_DECLARATION:
238 case ir::AstNodeType::EXPORT_DEFAULT_DECLARATION:
239 case ir::AstNodeType::EXPORT_NAMED_DECLARATION:
240 case ir::AstNodeType::EXPORT_SPECIFIER:
241 case ir::AstNodeType::IMPORT_DECLARATION:
242 case ir::AstNodeType::IMPORT_EXPRESSION:
243 case ir::AstNodeType::IMPORT_DEFAULT_SPECIFIER:
244 case ir::AstNodeType::IMPORT_NAMESPACE_SPECIFIER:
245 case ir::AstNodeType::IMPORT_SPECIFIER:
246 return true;
247 default:
248 break;
249 }
250 return false;
251 }
252
GetTargetTokenKind(const ir::AstNode * node)253 CompletionEntryKind GetTargetTokenKind(const ir::AstNode *node)
254 {
255 CompletionEntryKind normalResult = CompletionEntryKind::ALIAS_TYPE;
256 if (node == nullptr) {
257 return normalResult;
258 }
259 auto type = node->Type();
260 if (IsExpress(type)) {
261 normalResult = CompletionEntryKind::OPERATOR;
262 } else if (IsStatement(type)) {
263 normalResult = CompletionEntryKind::SNIPPET;
264 } else if (IsLiteral(type)) {
265 normalResult = CompletionEntryKind::VALUE;
266 } else if (IsModule(type)) {
267 normalResult = CompletionEntryKind::MODULE;
268 }
269 switch (type) {
270 case ir::AstNodeType::CLASS_DEFINITION:
271 case ir::AstNodeType::CLASS_DECLARATION:
272 return CompletionEntryKind::CLASS;
273 case ir::AstNodeType::CLASS_PROPERTY:
274 case ir::AstNodeType::PROPERTY:
275 return CompletionEntryKind::FIELD;
276 case ir::AstNodeType::FUNCTION_DECLARATION:
277 case ir::AstNodeType::SCRIPT_FUNCTION:
278 return CompletionEntryKind::FUNCTION;
279 case ir::AstNodeType::METHOD_DEFINITION: {
280 auto kind = node->AsMethodDefinition()->Kind();
281 return (kind == ir::MethodDefinitionKind::CONSTRUCTOR) ? CompletionEntryKind::CONSTRUCTOR
282 : CompletionEntryKind::METHOD;
283 }
284 case ir::AstNodeType::NAMED_TYPE:
285 return CompletionEntryKind::TYPE_PARAMETER;
286 case ir::AstNodeType::STRUCT_DECLARATION:
287 return CompletionEntryKind::STRUCT;
288 case ir::AstNodeType::VARIABLE_DECLARATION:
289 case ir::AstNodeType::VARIABLE_DECLARATOR:
290 return CompletionEntryKind::VARIABLE;
291 default:
292 auto etsResult = GetTargetTokenKindIfETSType(type);
293 if (std::get<0>(etsResult)) {
294 return std::get<1>(etsResult);
295 }
296 auto tsResult = GetTargetTokenKindIfTSType(type);
297 if (std::get<0>(tsResult)) {
298 return std::get<1>(tsResult);
299 }
300 }
301 return normalResult;
302 }
303
GetAliasDeclFromCurrentToken(const ir::AstNode * node)304 const ir::TSTypeAliasDeclaration *GetAliasDeclFromCurrentToken(const ir::AstNode *node)
305 {
306 if (node == nullptr) {
307 return nullptr;
308 }
309 const ir::TSTypeAliasDeclaration *aliasDecl = nullptr;
310 if (node->IsTSTypeAliasDeclaration()) {
311 aliasDecl = node->AsTSTypeAliasDeclaration();
312 } else if (node->IsIdentifier()) {
313 auto decl = compiler::DeclarationFromIdentifier(node->AsIdentifier());
314 if (decl == nullptr) {
315 return nullptr;
316 }
317 aliasDecl = decl->AsTSTypeAliasDeclaration();
318 }
319 return aliasDecl;
320 }
321
GetAliasScriptElementKindImpl(es2panda_Context * context,size_t position)322 CompletionEntryKind GetAliasScriptElementKindImpl(es2panda_Context *context, size_t position)
323 {
324 auto touchingToken = GetTouchingToken(context, position, false);
325 auto aliasDecl = GetAliasDeclFromCurrentToken(touchingToken);
326 if (aliasDecl == nullptr) {
327 return CompletionEntryKind::TEXT;
328 }
329 auto typeAnnotation = aliasDecl->TypeAnnotation();
330 if (typeAnnotation == nullptr) {
331 return CompletionEntryKind::ALIAS_TYPE;
332 }
333 if (typeAnnotation->IsETSTypeReference()) {
334 auto part = typeAnnotation->AsETSTypeReference()->Part()->AsETSTypeReferencePart();
335 if (part == nullptr) {
336 return CompletionEntryKind::ALIAS_TYPE;
337 }
338 auto targetIdent = part->GetIdent();
339 auto decl = compiler::DeclarationFromIdentifier(targetIdent);
340 if (compiler::ClassDefinitionIsEnumTransformed(decl)) {
341 return CompletionEntryKind::ENUM;
342 }
343 return GetTargetTokenKind(decl);
344 }
345 return GetTargetTokenKind(typeAnnotation);
346 }
347 } // namespace ark::es2panda::lsp
348