• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }