• 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 "lsp/include/register_code_fix/ui_plugin_suggest.h"
17 #include <iostream>
18 #include <string>
19 #include "lsp/include/code_fix_provider.h"
20 #include "lsp/include/internal_api.h"
21 
22 namespace ark::es2panda::lsp {
23 const int G_UI_PLUGIN_SUGGEST_CODE = 4000;  // change this to the error code you want to handle
24 
UIPluginSuggest()25 UIPluginSuggest::UIPluginSuggest()
26 {
27     const char *uiPluginSuggestId = "UIPluginSuggest";
28     SetErrorCodes({G_UI_PLUGIN_SUGGEST_CODE});
29     SetFixIds({uiPluginSuggestId});
30 }
31 
GetTextChangesFromSuggestions(const ark::es2panda::util::Diagnostic * diag,size_t pos,bool isAll)32 std::vector<TextChange> GetTextChangesFromSuggestions(const ark::es2panda::util::Diagnostic *diag, size_t pos,
33                                                       bool isAll)
34 {
35     std::vector<TextChange> textChanges;
36     if (!diag->HasSuggestions()) {
37         return textChanges;
38     }
39     for (auto suggestion : diag->Suggestion()) {
40         auto sourceStart = suggestion->SourceRange()->start.index;
41         auto sourceEnd = suggestion->SourceRange()->end.index;
42         auto span = TextSpan(sourceStart, sourceEnd - sourceStart);
43         if (isAll) {
44             textChanges.emplace_back(TextChange(span, suggestion->SubstitutionCode()));
45         } else if (pos >= sourceStart && pos <= sourceEnd) {
46             textChanges.emplace_back(TextChange(span, suggestion->SubstitutionCode()));
47         }
48     }
49     return textChanges;
50 }
51 
GetUIPluginCodeFixesByDiagType(public_lib::Context * ctx,size_t pos,util::DiagnosticType type,bool isAll)52 std::vector<FileTextChanges> GetUIPluginCodeFixesByDiagType(public_lib::Context *ctx, size_t pos,
53                                                             util::DiagnosticType type, bool isAll)
54 {
55     auto filename = ctx->sourceFileName;
56     std::vector<FileTextChanges> res;
57     const auto &diagnostics = ctx->diagnosticEngine->GetDiagnosticStorage(type);
58     auto diagnosticStorage = reinterpret_cast<const ark::es2panda::util::DiagnosticStorage *>(&diagnostics);
59     // NOLINTNEXTLINE(modernize-loop-convert,-warnings-as-errors)
60     for (size_t i = 0; i < diagnosticStorage->size(); ++i) {
61         auto diag = reinterpret_cast<const ark::es2panda::util::Diagnostic *>(&(*(*diagnosticStorage)[i]));
62         auto textChanges = GetTextChangesFromSuggestions(diag, pos, isAll);
63         FileTextChanges fileTextChanges(filename, textChanges);
64         res.emplace_back(fileTextChanges);
65     }
66     return res;
67 }
68 
GetUIPluginCodeFixes(es2panda_Context * context,size_t pos,bool isAll)69 std::vector<FileTextChanges> UIPluginSuggest::GetUIPluginCodeFixes(es2panda_Context *context, size_t pos, bool isAll)
70 {
71     if (context == nullptr) {
72         return {};
73     }
74     auto ctx = reinterpret_cast<public_lib::Context *>(context);
75     std::vector<FileTextChanges> res;
76     auto errorFixes = GetUIPluginCodeFixesByDiagType(ctx, pos, util::DiagnosticType::PLUGIN_ERROR, isAll);
77     res.insert(res.end(), errorFixes.begin(), errorFixes.end());
78     auto warningFixes = GetUIPluginCodeFixesByDiagType(ctx, pos, util::DiagnosticType::PLUGIN_WARNING, isAll);
79     res.insert(res.end(), warningFixes.begin(), warningFixes.end());
80     return res;
81 }
82 
GetCodeActions(const CodeFixContext & context)83 std::vector<CodeFixAction> UIPluginSuggest::GetCodeActions(const CodeFixContext &context)
84 {
85     std::vector<CodeFixAction> returnedActions;
86     auto changes = GetUIPluginCodeFixes(context.context, context.span.start, false);
87     if (!changes.empty()) {
88         CodeFixAction codeAction;
89         codeAction.fixName = "Fix";
90         codeAction.description = "Fix Description";
91         codeAction.changes = changes;
92         codeAction.fixId = "UI_PLUGIN_SUGGEST";
93         codeAction.fixAllDescription = "Fix All Description";
94         InstallPackageAction codeActionCommand;
95         codeActionCommand.file = reinterpret_cast<public_lib::Context *>(context.context)->sourceFileName;
96         codeActionCommand.packageName = "";
97         codeAction.commands.push_back(codeActionCommand);
98         returnedActions.push_back(codeAction);
99     }
100     return returnedActions;
101 }
102 
GetAllCodeActions(const CodeFixAllContext & codeFixAll)103 CombinedCodeActions UIPluginSuggest::GetAllCodeActions(const CodeFixAllContext &codeFixAll)
104 {
105     CombinedCodeActions combinedCodeActions;
106     auto changes = GetUIPluginCodeFixes(codeFixAll.context, 0, true);
107     combinedCodeActions.changes = changes;
108     InstallPackageAction codeActionCommand;
109     codeActionCommand.file = reinterpret_cast<public_lib::Context *>(codeFixAll.context)->sourceFileName;
110     codeActionCommand.packageName = "";
111     combinedCodeActions.commands.push_back(codeActionCommand);
112 
113     return combinedCodeActions;
114 }
115 // NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp)
116 AutoCodeFixRegister<UIPluginSuggest> g_uiPluginSuggest("UIPluginSuggest");
117 }  // namespace ark::es2panda::lsp
118