• 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 "string_completions.h"
17 #include "completions.h"
18 #include <optional>
19 #include <set>
20 #include <string>
21 #include <vector>
22 #include "ir/astNode.h"
23 
24 namespace ark::es2panda::lsp {
GetDeclarationFromParent(ir::AstNode * node)25 ir::AstNode *GetDeclarationFromParent(ir::AstNode *node)
26 {
27     // NOTE: After GL22929
28     (void)node;
29 
30     return nullptr;
31 }
32 
ControlTypeAndAddToEntry(std::string name,ir::AstNode * referencePart,std::vector<lsp::CompletionEntry> & entries,std::set<std::string> & keys)33 void ControlTypeAndAddToEntry(std::string name, ir::AstNode *referencePart, std::vector<lsp::CompletionEntry> &entries,
34                               std::set<std::string> &keys)
35 {
36     if (referencePart == nullptr) {
37         return;
38     }
39     auto type = std::string(referencePart->AsETSTypeReferencePart()->Name()->AsIdentifier()->Name());
40 
41     std::string insertText = name += std::string(": ") += type;
42     auto entry = lsp::CompletionEntry(name, CompletionEntryKind::TEXT, "", insertText);
43     keys.insert(name);
44     entries.push_back(entry);
45 }
46 
GetCompletionsFromBody(ArenaVector<ir::AstNode * > const & body,std::vector<lsp::CompletionEntry> & entries)47 void GetCompletionsFromBody(ArenaVector<ir::AstNode *> const &body, std::vector<lsp::CompletionEntry> &entries)
48 {
49     std::set<std::string> keys = {};
50     for (auto property : body) {
51         if (property->IsMethodDefinition()) {
52             auto methodDefinition = property->AsMethodDefinition();
53             auto name = std::string(methodDefinition->Key()->AsIdentifier()->Name());
54             if (name == "constructor" || keys.count(name) == 1 || name.empty()) {
55                 continue;
56             }
57 
58             ir::AstNode *referencePart = methodDefinition->Value()->FindChild(
59                 [](ir::AstNode *child) { return child->IsETSTypeReferencePart(); });
60 
61             ControlTypeAndAddToEntry(name, referencePart, entries, keys);
62         } else if (property->IsClassProperty()) {
63             auto classProperty = property->AsClassProperty();
64             auto name = std::string(classProperty->Key()->AsIdentifier()->Name());
65             if (name.empty() || keys.count(name) == 1) {
66                 continue;
67             }
68 
69             ir::AstNode *referencePart =
70                 classProperty->FindChild([](ir::AstNode *child) { return child->IsETSTypeReferencePart(); });
71 
72             ControlTypeAndAddToEntry(name, referencePart, entries, keys);
73         }
74     }
75 }
76 
GetCompletionInfo(ir::AstNode * node)77 ark::es2panda::lsp::CompletionInfo GetCompletionInfo(ir::AstNode *node)
78 {
79     std::vector<lsp::CompletionEntry> entries;
80     switch (node->Type()) {
81         case ir::AstNodeType::TS_INTERFACE_BODY: {
82             GetCompletionsFromBody(node->AsTSInterfaceBody()->Body(), entries);
83             break;
84         }
85         case ir::AstNodeType::TS_INTERFACE_DECLARATION: {
86             GetCompletionsFromBody(node->AsTSInterfaceDeclaration()->Body()->Body(), entries);
87             break;
88         }
89         case ir::AstNodeType::CLASS_DECLARATION: {
90             GetCompletionsFromBody(node->AsClassDeclaration()->Definition()->Body(), entries);
91             break;
92         }
93         default:
94             break;
95     }
96 
97     return ark::es2panda::lsp::CompletionInfo(entries);
98 }
99 
100 // NOTE: The API that calls this function already know the location of the completion request, should just
101 // pass the Node of the completion request position instead of send the location and we get the node from context
GetStringLiteralCompletions(ir::AstNode * cursor,ir::AstNode * declarationNode)102 std::optional<ark::es2panda::lsp::CompletionInfo> GetStringLiteralCompletions(ir::AstNode *cursor,
103                                                                               ir::AstNode *declarationNode)
104 {
105     if (cursor == nullptr || !cursor->IsStringLiteral() || declarationNode == nullptr) {
106         return std::nullopt;
107     }
108 
109     // Note: Should add more cases, like function declaration, Property Assignment, Element Access etc.
110     switch (declarationNode->Type()) {
111         case ir::AstNodeType::TS_INTERFACE_DECLARATION:
112         case ir::AstNodeType::TS_INTERFACE_BODY: {
113             return GetCompletionInfo(declarationNode);
114         }
115         case ir::AstNodeType::CLASS_DECLARATION: {
116             return GetCompletionInfo(declarationNode);
117         }
118         case ir::AstNodeType::FUNCTION_DECLARATION:
119             // Not Supported at the moment
120             return std::nullopt;
121         case ir::AstNodeType::TS_UNION_TYPE:
122         case ir::AstNodeType::ETS_UNION_TYPE:
123             // Not supported at the moment
124             return std::nullopt;
125         default:
126             return std::nullopt;
127     }
128     return std::nullopt;
129 }
130 
131 }  // namespace ark::es2panda::lsp
132