• 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 #include "completions_details.h"
17 #include "internal_api.h"
18 #include "compiler/lowering/util.h"
19 #include "ir/astNode.h"
20 #include "public/public.h"
21 #include <algorithm>
22 #include <cstddef>
23 #include <string>
24 #include "generated/tokenType.h"
25 #include <cstdio>
26 #include "public/es2panda_lib.h"
27 #include "lexer/token/letters.h"
28 #include "api.h"
29 #include "quick_info.h"
30 #include "suggestion_diagnostics.h"
31 
32 namespace ark::es2panda::lsp::details {
33 
GetDisplayPartAndKind(ir::AstNode * node,std::vector<SymbolDisplayPart> & displayParts,std::string & kind,std::string & kindModifiers)34 void GetDisplayPartAndKind(ir::AstNode *node, std::vector<SymbolDisplayPart> &displayParts, std::string &kind,
35                            std::string &kindModifiers)
36 {
37     if (IsClass(node)) {
38         displayParts = ark::es2panda::lsp::CreateDisplayForClass(node);
39         kind = "class";
40     } else if (node->Type() == ir::AstNodeType::ETS_PARAMETER_EXPRESSION) {
41         displayParts = ark::es2panda::lsp::CreateDisplayForETSParameterExpression(node);
42         kind = "parameter";
43     } else if (node->Type() == ir::AstNodeType::CLASS_PROPERTY) {
44         // After enum refactoring, enum declaration is transformed to a class declaration
45         if (compiler::ClassDefinitionIsEnumTransformed(node->Parent())) {
46             auto enumDecl = node->Parent()->AsClassDefinition()->OrigEnumDecl()->AsTSEnumDeclaration();
47             auto enumMember = GetEnumMemberByName(enumDecl, node->AsClassProperty()->Key()->AsIdentifier()->Name());
48             displayParts = ark::es2panda::lsp::CreateDisplayForEnumMember(enumMember);
49             kind = "enum member";
50         } else {
51             displayParts = ark::es2panda::lsp::CreateDisplayForClassProperty(node, kindModifiers);
52             kind = "property";
53         }
54     } else if (node->Type() == ir::AstNodeType::TS_INTERFACE_DECLARATION) {
55         displayParts = ark::es2panda::lsp::CreateDisplayForInterface(node);
56         kind = "interface";
57     } else if (node->Type() == ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION) {
58         displayParts = ark::es2panda::lsp::CreateDisplayForTypeAlias(node);
59         kind = "type alias";
60     } else if (node->Type() == ir::AstNodeType::TS_ENUM_DECLARATION) {
61         displayParts = ark::es2panda::lsp::CreateDisplayForEnum(node);
62         kind = "enum";
63     } else if (node->Type() == ir::AstNodeType::IMPORT_DECLARATION) {
64         displayParts = CreateDisplayForImportDeclaration(node);
65         kind = "import";
66     } else if (node->Type() == ir::AstNodeType::TS_TYPE_PARAMETER) {
67         displayParts = ark::es2panda::lsp::CreateDisplayForTypeParameter(node);
68         kind = "type parameter";
69     } else if (node->Type() == ir::AstNodeType::METHOD_DEFINITION) {
70         displayParts = ark::es2panda::lsp::CreateDisplayForMethodDefinition(node, kindModifiers);
71         kind = "function";
72         if (node->Parent() != nullptr && node->Parent()->Type() == ir::AstNodeType::TS_INTERFACE_BODY) {
73             kind = "property";
74         }
75     }
76 }
77 
GetCompletionEntryDetails(ir::AstNode * node,const std::string & entryName,const std::string & fileName)78 CompletionEntryDetails GetCompletionEntryDetails(ir::AstNode *node, const std::string &entryName,
79                                                  const std::string &fileName)
80 {
81     if (node == nullptr) {
82         return CompletionEntryDetails();
83     }
84     auto kindModifiers = GetKindModifiers(node);
85     std::vector<SymbolDisplayPart> displayParts;
86 
87     std::string kind;
88     std::vector<SymbolDisplayPart> document;
89     std::vector<SymbolDisplayPart> source;
90     std::vector<SymbolDisplayPart> sourceDisplay;
91 
92     GetDisplayPartAndKind(node, displayParts, kind, kindModifiers);
93 
94     return CompletionEntryDetails(entryName, kind, kindModifiers, displayParts, document, source, sourceDisplay,
95                                   fileName);
96 }
97 
GetCompletionEntryDetailsImpl(es2panda_Context * context,size_t position,const char * fileName,const char * entryName)98 CompletionEntryDetails GetCompletionEntryDetailsImpl(es2panda_Context *context, size_t position, const char *fileName,
99                                                      const char *entryName)
100 {
101     if (context == nullptr) {
102         return CompletionEntryDetails();
103     }
104     auto touchingToken = GetTouchingToken(context, position, false);
105     if (touchingToken == nullptr || touchingToken->IsProgram()) {
106         return CompletionEntryDetails();
107     }
108     auto ctx = reinterpret_cast<public_lib::Context *>(context);
109     auto ast = ctx->parserProgram->Ast();
110     auto leIdentifier =
111         ast->FindChild([entryName](ir::AstNode *node) { return HasPropertyAccessExpressionWithName(node, entryName); });
112     if (leIdentifier == nullptr || !leIdentifier->IsIdentifier()) {
113         return CompletionEntryDetails();
114     }
115     auto targetNode = compiler::DeclarationFromIdentifier(leIdentifier->AsIdentifier());
116     if (targetNode == nullptr) {
117         return CompletionEntryDetails();
118     }
119     return GetCompletionEntryDetails(targetNode, entryName, fileName);
120 }
121 
122 }  // namespace ark::es2panda::lsp::details