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