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_COMPLETIONS_H 17 #define ES2PANDA_LSP_COMPLETIONS_H 18 19 #include "public/es2panda_lib.h" 20 #include <memory> 21 #include <string> 22 #include <utility> 23 #include <vector> 24 #include <optional> 25 #include "checker/checker.h" 26 #include "util/arktsconfig.h" 27 28 namespace ark::es2panda::lsp { 29 30 enum class CompletionEntryKind { 31 TEXT = 1, 32 METHOD = 2, 33 FUNCTION = 3, 34 CONSTRUCTOR = 4, 35 FIELD = 5, 36 VARIABLE = 6, 37 CLASS = 7, 38 INTERFACE = 8, 39 MODULE = 9, 40 PROPERTY = 10, 41 UNIT = 11, 42 VALUE = 12, 43 ENUM = 13, 44 KEYWORD = 14, 45 SNIPPET = 15, 46 COLOR = 16, 47 FILE = 17, 48 REFERENCE = 18, 49 FOLDER = 19, 50 ENUM_MEMBER = 20, 51 CONSTANT = 21, 52 STRUCT = 22, 53 EVENT = 23, 54 OPERATOR = 24, 55 TYPE_PARAMETER = 25, 56 ALIAS_TYPE = 26 57 }; 58 59 namespace sort_text { 60 constexpr std::string_view LOCAL_DECLARATION_PRIORITY = "10"; 61 constexpr std::string_view LOCATION_PRIORITY = "11"; 62 constexpr std::string_view OPTIONAL_MEMBER = "12"; 63 constexpr std::string_view MEMBER_DECLARED_BY_SPREAD_ASSIGNMENT = "13"; 64 constexpr std::string_view SUGGESTED_CLASS_MEMBERS = "14"; 65 constexpr std::string_view GLOBALS_OR_KEYWORDS = "15"; 66 constexpr std::string_view AUTO_IMPORT_SUGGESTIONS = "16"; 67 constexpr std::string_view CLASS_MEMBER_SNIPPETS = "17"; 68 } // namespace sort_text 69 70 enum class ResolutionStatus { RESOLVED, UNRESOLVED }; 71 struct CompletionEntryData { 72 private: 73 const char *fileName_; 74 std::string namedExport_; 75 std::string importDeclaration_; 76 std::string completionName_; 77 ResolutionStatus status_; 78 79 public: 80 explicit CompletionEntryData(const char *fileName = "", std::string namedExport = "", 81 std::string importDeclaration = "", std::string completionName = "", 82 ResolutionStatus status = ResolutionStatus::UNRESOLVED) fileName_CompletionEntryData83 : fileName_(fileName), 84 namedExport_(std::move(namedExport)), 85 importDeclaration_(std::move(importDeclaration)), 86 completionName_(std::move(completionName)), 87 status_(status) 88 { 89 } 90 GetFileNameCompletionEntryData91 const char *GetFileName() 92 { 93 return fileName_; 94 } 95 GetNamedExportCompletionEntryData96 const std::string &GetNamedExport() 97 { 98 return namedExport_; 99 } 100 GetImportDeclarationCompletionEntryData101 const std::string &GetImportDeclaration() 102 { 103 return importDeclaration_; 104 } 105 GetStatusCompletionEntryData106 ResolutionStatus GetStatus() 107 { 108 return status_; 109 } 110 }; 111 struct CompletionEntry { 112 private: 113 std::string name_; 114 CompletionEntryKind kind_; 115 std::string sortText_; 116 // This is what the Client uses 117 std::string insertText_; 118 std::optional<CompletionEntryData> data_; 119 120 public: 121 explicit CompletionEntry(std::string name = "", CompletionEntryKind kind = CompletionEntryKind::TEXT, 122 std::string sortText = "", std::string insertText = "", 123 std::optional<CompletionEntryData> data = std::nullopt) name_CompletionEntry124 : name_(std::move(name)), 125 kind_(kind), 126 sortText_(std::move(sortText)), 127 insertText_(std::move(insertText)), 128 data_(std::move(data)) 129 { 130 } GetSortTextCompletionEntry131 std::string GetSortText() const 132 { 133 return sortText_; 134 } GetInsertTextCompletionEntry135 std::string GetInsertText() const 136 { 137 return insertText_; 138 } GetCompletionKindCompletionEntry139 CompletionEntryKind GetCompletionKind() const 140 { 141 return kind_; 142 } GetNameCompletionEntry143 std::string GetName() const 144 { 145 return name_; 146 } 147 bool operator==(const CompletionEntry &other) const 148 { 149 return name_ == other.name_ && kind_ == other.kind_ && sortText_ == other.sortText_ && 150 insertText_ == other.insertText_; 151 } 152 bool operator!=(const CompletionEntry &other) const 153 { 154 return !(*this == other); 155 } GetSortTextCompletionEntry156 std::string GetSortText() 157 { 158 return sortText_; 159 } GetCompletionEntryDataCompletionEntry160 std::optional<CompletionEntryData> GetCompletionEntryData() 161 { 162 return data_; 163 } 164 }; 165 166 enum class CompletionDataKind { DATA, KEYWORDS }; 167 168 struct Request { 169 CompletionDataKind kind; 170 std::vector<CompletionEntry> keywordCompletions; 171 }; 172 173 struct LabelDetails { 174 private: 175 std::optional<std::string> detail_; 176 std::optional<std::string> description_; 177 }; 178 179 struct CompletionInfo { 180 private: 181 std::vector<CompletionEntry> entries_; 182 183 public: entries_CompletionInfo184 explicit CompletionInfo(std::vector<CompletionEntry> entries = {}) : entries_(std::move(entries)) {} 185 GetEntriesCompletionInfo186 std::vector<CompletionEntry> &GetEntries() 187 { 188 return entries_; 189 } 190 }; 191 192 std::vector<CompletionEntry> AllKeywordsCompletions(); 193 std::vector<CompletionEntry> GetKeywordCompletions(const std::string &input); 194 std::vector<CompletionEntry> GetMemberCompletions(es2panda_Context *context, size_t position); 195 Request KeywordCompletionData(const std::string &input); 196 std::string ToLowerCase(const std::string &str); 197 std::vector<CompletionEntry> GetCompletionsAtPositionImpl(es2panda_Context *context, size_t position); 198 ArenaVector<varbinder::Scope *> BuildScopePath(varbinder::Scope *startScope, ArenaAllocator *allocator); 199 CompletionEntry ProcessAutoImportForEntry(CompletionEntry &entry); 200 201 std::optional<CompletionEntryData> GetAutoImportCompletionEntry(ark::es2panda::lsp::CompletionEntryData *data, 202 const std::shared_ptr<ArkTsConfig> &config, 203 const std::string &name); 204 std::optional<CompletionEntryData> CompletionEntryDataToOriginInfo(ark::es2panda::lsp::CompletionEntryData *data, 205 const std::shared_ptr<ArkTsConfig> &config, 206 const std::string &name); 207 std::optional<bool> IsCompletionEntryDataResolved(ark::es2panda::lsp::CompletionEntryData *data, 208 const std::shared_ptr<ArkTsConfig> &config); 209 std::vector<ir::AstNode *> FilterFromBody(const ark::ArenaVector<ir::AstNode *> &bodyNodes, 210 const std::string &triggerWord); 211 212 bool StartsWith(const std::string &str, const std::string &prefix); 213 bool IsDefinedClassOrStruct(ir::AstNode *preNode); 214 std::shared_ptr<ArkTsConfig> GetArkTsConfigFromFile(const char *fileName); 215 std::vector<CompletionEntry> GetPropertyCompletions(ir::AstNode *preNode, const std::string &triggerWord); 216 std::string GetClassPropertyName(ir::AstNode *node); 217 ir::AstNode *GetIdentifierFromTSInterfaceHeritage(ir::AstNode *node); 218 219 } // namespace ark::es2panda::lsp 220 #endif 221