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