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 21using PtJson = panda::ecmascript::tooling::PtJson; 22using Result = panda::ecmascript::tooling::Result; 23namespace OHOS::ArkCompiler::Toolchain { 24WatchManager::WatchManager(uint32_t sessionId) 25 : sessionId_(sessionId), runtimeClient_(sessionId) 26{ 27} 28 29void 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 58void 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 82void 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 94std::string WatchManager::GetCallFrameId() 95{ 96 return callFrameId_; 97} 98 99int WatchManager::GetWatchInfoSize() 100{ 101 return watchInfoList_.size(); 102} 103 104void WatchManager::AddWatchInfo(const std::string& watchInfo) 105{ 106 watchInfoList_.emplace_back(watchInfo); 107} 108 109bool WatchManager::GetDebugState() 110{ 111 return IsDebug_; 112} 113void WatchManager::DebugFalseState() 114{ 115 IsDebug_ = false; 116} 117void WatchManager::DebugTrueState() 118{ 119 IsDebug_ = true; 120} 121 122void WatchManager::SetWatchInfoMap(const int &id, const int &index) 123{ 124 watchInfoMap_.emplace(id, index); 125} 126 127bool 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} 154bool 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 203void 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 232bool 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}