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/variable_manager.h"
17
18 using PtJson = panda::ecmascript::tooling::PtJson;
19 namespace OHOS::ArkCompiler::Toolchain {
AddChild(std::unique_ptr<PropertyDescriptor> descriptor)20 void TreeNode::AddChild(std::unique_ptr<PropertyDescriptor> descriptor)
21 {
22 children.push_back(std::make_unique<TreeNode>(std::move(descriptor)));
23 }
24
AddChild(DescriptorMap descriptorMap)25 void TreeNode::AddChild(DescriptorMap descriptorMap)
26 {
27 children.push_back(std::make_unique<TreeNode>(std::move(descriptorMap)));
28 }
29
AddChild(std::unique_ptr<TreeNode> child)30 void TreeNode::AddChild(std::unique_ptr<TreeNode> child)
31 {
32 children.push_back(std::move(child));
33 }
34
Print(int depth) const35 void TreeNode::Print(int depth) const
36 {
37 int actualIndent = 0;
38 if (depth > 1) {
39 actualIndent = (depth - 1) * 4; // 4: four spaces
40 }
41 std::string indent(actualIndent, ' ');
42
43 if (std::holds_alternative<int32_t>(data)) {
44 std::cout << indent << "CallFrameId: " << std::get<int32_t>(data) << std::endl;
45 } else if (std::holds_alternative<std::map<int32_t, std::map<int32_t, std::string>>>(data)) {
46 const auto& outerMap = std::get<std::map<int32_t, std::map<int32_t, std::string>>>(data);
47 for (const auto& [key, innerMap] : outerMap) {
48 for (const auto& [innerKey, value] : innerMap) {
49 std::cout << key << ". " << value << std::endl;
50 }
51 }
52 } else if (std::holds_alternative<std::unique_ptr<PropertyDescriptor>>(data)) {
53 const auto &descriptor = std::get<std::unique_ptr<PropertyDescriptor>>(data);
54 if (descriptor && descriptor->GetValue()) {
55 if (descriptor->GetValue()->HasDescription()) {
56 std::cout << indent << " " << descriptor->GetName() << " = "
57 << descriptor->GetValue()->GetDescription() << std::endl;
58 } else {
59 std::cout << indent << " " << descriptor->GetName() << " = "
60 << descriptor->GetValue()->GetType() << std::endl;
61 }
62 }
63 } else if (std::holds_alternative<DescriptorMap>(data)) {
64 const auto &descriptorMap = std::get<DescriptorMap>(data);
65 for (const auto& [key, descriptor] : descriptorMap) {
66 std::cout << indent << key << ". ";
67 if (descriptor && descriptor->GetValue()) {
68 std::cout << descriptor->GetName() << " = " << descriptor->GetValue()->GetDescription() << std::endl;
69 }
70 }
71 }
72
73 for (const auto &child : children) {
74 child->Print(depth + 1);
75 }
76 }
77
Tree(const std::map<int32_t,std::map<int32_t,std::string>> & dataMap,int32_t index)78 Tree::Tree(const std::map<int32_t, std::map<int32_t, std::string>>& dataMap, int32_t index)
79 {
80 root_ = std::make_unique<TreeNode>(index);
81
82 auto it = dataMap.find(index);
83 if (it != dataMap.end()) {
84 for (const auto& [key, value] : it->second) {
85 std::map<int32_t, std::map<int32_t, std::string>> childData;
86 childData[index_] = {{key, value}};
87 root_->children.push_back(std::make_unique<TreeNode>(childData));
88 index_++;
89 }
90 }
91 }
92
PrintRootAndImmediateChildren() const93 void Tree::PrintRootAndImmediateChildren() const
94 {
95 if (std::holds_alternative<int32_t>(root_->data)) {
96 std::cout << "CallFrame ID: " << std::get<int32_t>(root_->data) << std::endl;
97 }
98
99 for (const auto& child : root_->children) {
100 if (std::holds_alternative<std::map<int32_t, std::map<int32_t, std::string>>>(child->data)) {
101 const auto& outerMap = std::get<std::map<int32_t, std::map<int32_t, std::string>>>(child->data);
102 for (const auto& [index, innerMap] : outerMap) {
103 std::cout << " Index: " << index << std::endl;
104 for (const auto& [objectId, type] : innerMap) {
105 std::cout << " Object ID: " << objectId << ", Type: " << type << std::endl;
106 }
107 }
108 }
109 }
110 }
111
Clear()112 void Tree::Clear()
113 {
114 if (root_ != nullptr) {
115 root_.reset();
116 }
117 }
118
Print() const119 void Tree::Print() const
120 {
121 if (root_) {
122 root_->Print();
123 }
124 }
125
FindNodeWithObjectId(int32_t objectId) const126 TreeNode* Tree::FindNodeWithObjectId(int32_t objectId) const
127 {
128 return FindNodeWithObjectIdRecursive(root_.get(), objectId);
129 }
130
AddVariableNode(TreeNode * parentNode,std::unique_ptr<PropertyDescriptor> descriptor)131 void Tree::AddVariableNode(TreeNode* parentNode, std::unique_ptr<PropertyDescriptor> descriptor)
132 {
133 if (!parentNode) {
134 return;
135 }
136 parentNode->AddChild(std::move(descriptor));
137 }
138
AddObjectNode(TreeNode * parentNode,std::unique_ptr<PropertyDescriptor> descriptor)139 void Tree::AddObjectNode(TreeNode* parentNode, std::unique_ptr<PropertyDescriptor> descriptor)
140 {
141 if (!parentNode) {
142 return;
143 }
144 DescriptorMap descriptorMap;
145 descriptorMap[index_] = std::move(descriptor);
146 parentNode->AddChild(std::move(descriptorMap));
147 index_++;
148 }
149
GetRoot() const150 TreeNode* Tree::GetRoot() const
151 {
152 return root_.get();
153 }
154
FindNodeWithObjectIdRecursive(TreeNode * node,int32_t objectId) const155 TreeNode* Tree::FindNodeWithObjectIdRecursive(TreeNode* node, int32_t objectId) const
156 {
157 if (!node) {
158 return nullptr;
159 }
160
161 if (std::holds_alternative<std::map<int32_t, std::map<int32_t, std::string>>>(node->data)) {
162 const auto& outerMap = std::get<std::map<int32_t, std::map<int32_t, std::string>>>(node->data);
163 for (const auto& [key, innerMap] : outerMap) {
164 if (innerMap.find(objectId) != innerMap.end()) {
165 return node;
166 }
167 }
168 } else if (std::holds_alternative<DescriptorMap>(node->data)) {
169 const auto& descriptorMap = std::get<DescriptorMap>(node->data);
170 for (const auto& [key, descriptor] : descriptorMap) {
171 if (descriptor && descriptor->GetValue() && descriptor->GetValue()->GetObjectId() == objectId) {
172 return node;
173 }
174 }
175 }
176
177 for (const auto& child : node->children) {
178 TreeNode* foundNode = FindNodeWithObjectIdRecursive(child.get(), objectId);
179 if (foundNode) {
180 return foundNode;
181 }
182 }
183
184 return nullptr;
185 }
186
FindNodeWithInnerKeyZero(TreeNode * node) const187 TreeNode* Tree::FindNodeWithInnerKeyZero(TreeNode* node) const
188 {
189 if (!node) {
190 return nullptr;
191 }
192
193 if (std::holds_alternative<std::map<int32_t, std::map<int32_t, std::string>>>(node->data)) {
194 const auto &outerMap = std::get<std::map<int32_t, std::map<int32_t, std::string>>>(node->data);
195 for (const auto &innerMapPair : outerMap) {
196 if (innerMapPair.second.find(0) != innerMapPair.second.end()) {
197 return node;
198 }
199 }
200 }
201
202 for (const auto &child : node->children) {
203 TreeNode* foundNode = FindNodeWithInnerKeyZero(child.get());
204 if (foundNode) {
205 return foundNode;
206 }
207 }
208
209 return nullptr;
210 }
FindNodeWithCondition() const211 TreeNode* Tree::FindNodeWithCondition() const
212 {
213 return FindNodeWithInnerKeyZero(root_.get());
214 }
215
FindObjectByIndex(int32_t index) const216 int32_t Tree::FindObjectByIndex(int32_t index) const
217 {
218 return FindObjectByIndexRecursive(root_.get(), index);
219 }
220
FindObjectByIndexRecursive(const TreeNode * node,int32_t index) const221 int32_t Tree::FindObjectByIndexRecursive(const TreeNode* node, int32_t index) const
222 {
223 if (!node) {
224 return 0;
225 }
226
227 if (std::holds_alternative<std::map<int32_t, std::map<int32_t, std::string>>>(node->data)) {
228 const auto &outerMap = std::get<std::map<int32_t, std::map<int32_t, std::string>>>(node->data);
229 auto it = outerMap.find(index);
230 if (it != outerMap.end() && !it->second.empty()) {
231 return it->second.begin()->first;
232 }
233 } else if (std::holds_alternative<DescriptorMap>(node->data)) {
234 const auto &descriptorMap = std::get<DescriptorMap>(node->data);
235 auto it = descriptorMap.find(index);
236 if (it != descriptorMap.end() && it->second && it->second->GetValue()) {
237 return it->second->GetValue()->GetObjectId();
238 }
239 }
240
241 for (const auto& child : node->children) {
242 int32_t result = FindObjectByIndexRecursive(child.get(), index);
243 if (result != 0) {
244 return result;
245 }
246 }
247
248 return 0;
249 }
250
SetHeapUsageInfo(std::unique_ptr<GetHeapUsageReturns> heapUsageReturns)251 void VariableManager::SetHeapUsageInfo(std::unique_ptr<GetHeapUsageReturns> heapUsageReturns)
252 {
253 heapUsageInfo_.SetUsedSize(heapUsageReturns->GetUsedSize());
254 heapUsageInfo_.SetTotalSize(heapUsageReturns->GetTotalSize());
255 }
256
ShowHeapUsageInfo() const257 void VariableManager::ShowHeapUsageInfo() const
258 {
259 std::cout << std::endl;
260 std::cout << "UsedSize is: " << heapUsageInfo_.GetUsedSize() << std::endl;
261 std::cout << "TotalSize is: " << std::fixed << std::setprecision(0) << heapUsageInfo_.GetTotalSize() << std::endl;
262 }
263
ShowVariableInfos() const264 void VariableManager::ShowVariableInfos() const
265 {
266 variableInfo_.Print();
267 }
268
ClearVariableInfo()269 void VariableManager::ClearVariableInfo()
270 {
271 variableInfo_.Clear();
272 }
InitializeTree(std::map<int32_t,std::map<int32_t,std::string>> dataMap,int index)273 void VariableManager::InitializeTree(std::map<int32_t, std::map<int32_t, std::string>> dataMap, int index)
274 {
275 variableInfo_ = Tree(dataMap, index);
276 }
277
PrintVariableInfo()278 void VariableManager::PrintVariableInfo()
279 {
280 variableInfo_.Print();
281 }
282
FindNodeWithObjectId(int32_t objectId)283 TreeNode* VariableManager::FindNodeWithObjectId(int32_t objectId)
284 {
285 return variableInfo_.FindNodeWithObjectId(objectId);
286 }
287
AddVariableInfo(TreeNode * parentNode,std::unique_ptr<PropertyDescriptor> variableInfo)288 void VariableManager::AddVariableInfo(TreeNode *parentNode, std::unique_ptr<PropertyDescriptor> variableInfo)
289 {
290 if (variableInfo && variableInfo->GetValue() && variableInfo->GetValue()->HasObjectId()) {
291 variableInfo_.AddObjectNode(parentNode, std::move(variableInfo));
292 } else {
293 variableInfo_.AddVariableNode(parentNode, std::move(variableInfo));
294 }
295 }
296
FindNodeObjectZero()297 TreeNode* VariableManager::FindNodeObjectZero()
298 {
299 return variableInfo_.FindNodeWithCondition();
300 }
301
FindObjectIdWithIndex(int index)302 int32_t VariableManager::FindObjectIdWithIndex(int index)
303 {
304 return variableInfo_.FindObjectByIndex(index);
305 }
306
Printinfo() const307 void VariableManager::Printinfo() const
308 {
309 variableInfo_.PrintRootAndImmediateChildren();
310 }
311 }