1 /*
2 * Copyright (c) 2023 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 "tooling/client/manager/watch_manager.h"
17
18 #include "tooling/client/session/session.h"
19
20 using PtJson = panda::ecmascript::tooling::PtJson;
21 using Result = panda::ecmascript::tooling::Result;
22 namespace OHOS::ArkCompiler::Toolchain {
WatchManager(uint32_t sessionId)23 WatchManager::WatchManager(uint32_t sessionId)
24 : sessionId_(sessionId), runtimeClient_(sessionId)
25 {
26 }
27
SendRequestWatch(const int32_t & watchInfoIndex,const std::string & callFrameId)28 void WatchManager::SendRequestWatch(const int32_t &watchInfoIndex, const std::string &callFrameId)
29 {
30 Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
31 uint32_t id = session->GetMessageId();
32 watchInfoMap_.emplace(id, watchInfoIndex);
33
34 std::unique_ptr<PtJson> request = PtJson::CreateObject();
35 request->Add("id", id);
36 request->Add("method", "Debugger.evaluateOnCallFrame");
37
38 std::unique_ptr<PtJson> params = PtJson::CreateObject();
39 params->Add("callFrameId", callFrameId.c_str());
40 params->Add("expression", watchInfoList_[watchInfoIndex].c_str());
41 params->Add("objectGroup", "watch-group");
42 params->Add("includeCommandLineAPI", false);
43 params->Add("silent", true);
44 params->Add("returnByValue", false);
45 params->Add("generatePreview", false);
46 params->Add("throwOnSideEffect", false);
47 request->Add("params", params);
48
49 std::string message = request->Stringify();
50 if (session->ClientSendReq(message)) {
51 inputRowFlag_++;
52 session->GetDomainManager().SetDomainById(id, "Debugger");
53 }
54 return;
55 }
56
GetPropertiesCommand(const int32_t & watchInfoIndex,const std::string & objectId)57 void WatchManager::GetPropertiesCommand(const int32_t &watchInfoIndex, const std::string &objectId)
58 {
59 Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
60 uint32_t id = session->GetMessageId();
61 watchInfoMap_.emplace(id, watchInfoIndex);
62
63 std::unique_ptr<PtJson> request = PtJson::CreateObject();
64 request->Add("id", id);
65 request->Add("method", "Runtime.getProperties");
66
67 std::unique_ptr<PtJson> params = PtJson::CreateObject();
68 params->Add("accessorPropertiesOnly", false);
69 params->Add("generatePreview", true);
70 params->Add("objectId", objectId.c_str());
71 params->Add("ownProperties", true);
72 request->Add("params", params);
73
74 std::string message = request->Stringify();
75 if (session->ClientSendReq(message)) {
76 session->GetDomainManager().SetDomainById(id, "Debugger");
77 }
78 return;
79 }
80
RequestWatchInfo(const std::unique_ptr<PtJson> & json)81 void WatchManager::RequestWatchInfo(const std::unique_ptr<PtJson> &json)
82 {
83 Result ret = json->GetString("callFrameId", &callFrameId_);
84 if (ret != Result::SUCCESS) {
85 LOGE("arkdb: find callFrameId error");
86 return;
87 }
88 for (uint i = 0; i < watchInfoList_.size(); i++) {
89 SendRequestWatch(i, callFrameId_);
90 }
91 }
92
GetCallFrameId()93 std::string WatchManager::GetCallFrameId()
94 {
95 return callFrameId_;
96 }
97
GetWatchInfoSize()98 int WatchManager::GetWatchInfoSize()
99 {
100 return watchInfoList_.size();
101 }
102
AddWatchInfo(const std::string & watchInfo)103 void WatchManager::AddWatchInfo(const std::string& watchInfo)
104 {
105 watchInfoList_.emplace_back(watchInfo);
106 }
107
GetDebugState()108 bool WatchManager::GetDebugState()
109 {
110 return IsDebug_;
111 }
DebugFalseState()112 void WatchManager::DebugFalseState()
113 {
114 IsDebug_ = false;
115 }
DebugTrueState()116 void WatchManager::DebugTrueState()
117 {
118 IsDebug_ = true;
119 }
120
SetWatchInfoMap(const int & id,const int & index)121 void WatchManager::SetWatchInfoMap(const int &id, const int &index)
122 {
123 watchInfoMap_.emplace(id, index);
124 }
125
HandleWatchResult(const std::unique_ptr<PtJson> & json,int32_t id)126 bool WatchManager::HandleWatchResult(const std::unique_ptr<PtJson> &json, int32_t id)
127 {
128 Result ret;
129 std::unique_ptr<PtJson> result;
130 ret = json->GetObject("result", &result);
131 if (ret != Result::SUCCESS) {
132 LOGE("json parse result error");
133 return false;
134 }
135 std::unique_ptr<PtJson> watchResult;
136 ret = result->GetObject("result", &watchResult);
137 if (ret != Result::SUCCESS) {
138 ShowWatchResult2(id, std::move(json));
139 LOGE("json parse result error");
140 return false;
141 }
142 if (!ShowWatchResult(std::move(watchResult), id)) {
143 return false;
144 }
145 inputRowFlag_--;
146 if (inputRowFlag_ == 0) {
147 std::cout << ">>> ";
148 fflush(stdout);
149 isShowWatchInfo_ = true;
150 }
151 return true;
152 }
ShowWatchResult(const std::unique_ptr<PtJson> & result,int32_t id)153 bool WatchManager::ShowWatchResult(const std::unique_ptr<PtJson> &result, int32_t id)
154 {
155 std::string type;
156 Result ret = result->GetString("type", &type);
157 if (ret != Result::SUCCESS) {
158 LOGE("json parse type error");
159 return false;
160 }
161 if (inputRowFlag_ == GetWatchInfoSize() && isShowWatchInfo_) {
162 std::cout << "watch info :" << std::endl;
163 isShowWatchInfo_ = false;
164 }
165 if (type == "undefined") {
166 auto it = watchInfoMap_.find(id);
167 if (it == watchInfoMap_.end()) {
168 return false;
169 }
170 std::cout << " " << watchInfoList_[it->second] << " = undefined" << std::endl;
171 } else if (type == "object") {
172 std::string objectId;
173 ret = result->GetString("objectId", &objectId);
174 if (ret != Result::SUCCESS) {
175 LOGE("json parse object error");
176 return false;
177 }
178 auto it = watchInfoMap_.find(id);
179 if (it == watchInfoMap_.end()) {
180 return false;
181 }
182 GetPropertiesCommand(it->second, objectId);
183 inputRowFlag_++;
184 } else {
185 auto it = watchInfoMap_.find(id);
186 if (it == watchInfoMap_.end()) {
187 return false;
188 }
189 std::string description;
190 ret = result->GetString("description", &description);
191 if (ret != Result::SUCCESS) {
192 LOGE("json parse description error");
193 return false;
194 }
195 std::cout << " " << watchInfoList_[it->second] << " = " << description << std::endl;
196 }
197 watchInfoMap_.erase(id);
198 DebugTrueState();
199 return true;
200 }
201
OutputWatchResult(const std::unique_ptr<PtJson> & watchResult)202 void WatchManager::OutputWatchResult(const std::unique_ptr<PtJson> &watchResult)
203 {
204 for (int32_t i = 0; i < watchResult->GetSize(); i++) {
205 std::string name;
206 Result ret = watchResult->Get(i)->GetString("name", &name);
207 if (ret != Result::SUCCESS) {
208 LOGE("json parse name error");
209 continue;
210 }
211 std::unique_ptr<PtJson> value;
212 ret = watchResult->Get(i)->GetObject("value", &value);
213 if (ret != Result::SUCCESS) {
214 LOGE("json parse value error");
215 continue;
216 }
217 std::string description;
218 ret = value->GetString("description", &description);
219 if (ret != Result::SUCCESS) {
220 LOGE("json parse description error");
221 continue;
222 }
223 std::cout << name << " = " << description;
224 if (i < watchResult->GetSize() - 1) {
225 std::cout << ", ";
226 }
227 }
228 return;
229 }
230
ShowWatchResult2(const int & id,const std::unique_ptr<PtJson> & result)231 bool WatchManager::ShowWatchResult2(const int &id, const std::unique_ptr<PtJson> &result)
232 {
233 std::unique_ptr<PtJson> resultWatch;
234 Result ret = result->GetObject("result", &resultWatch);
235 if (ret != Result::SUCCESS) {
236 LOGE("json parse result error");
237 return false;
238 }
239 std::unique_ptr<PtJson> watchResult;
240 ret = resultWatch->GetArray("result", &watchResult);
241 if (ret != Result::SUCCESS) {
242 LOGE("json parse result error");
243 return false;
244 }
245 auto it = watchInfoMap_.find(id);
246 if (it == watchInfoMap_.end()) {
247 return false;
248 }
249 std::cout << " " << watchInfoList_[it->second] << " = { ";
250 OutputWatchResult(std::move(watchResult));
251 std::cout << " }" << std::endl;
252 inputRowFlag_--;
253 if (inputRowFlag_ == 0) {
254 std::cout << ">>> ";
255 fflush(stdout);
256 isShowWatchInfo_ = true;
257 }
258 DebugTrueState();
259 watchInfoMap_.erase(id);
260 return true;
261 }
262 }