1 /**
2 * Copyright (c) 2024 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/inspector/types/object_preview.h"
17 #include "tooling/inspector/types/property_descriptor.h"
18
19 #include "utils/string_helpers.h"
20
21 namespace ark::tooling::inspector {
22
23 // Number of maximum count of properties that can be previewed.
24 static constexpr size_t PROPERTIES_NMB_LIMIT = 10;
25
26 namespace {
GetPropertyPreviewValue(const RemoteObjectType::TypeValue & remobjValue)27 std::optional<std::string> GetPropertyPreviewValue(const RemoteObjectType::TypeValue &remobjValue)
28 {
29 std::optional<std::string> propPreviewValue;
30
31 if (std::holds_alternative<std::nullptr_t>(remobjValue)) {
32 propPreviewValue.emplace("null");
33 } else if (auto boolean = std::get_if<bool>(&remobjValue)) {
34 propPreviewValue.emplace(*boolean ? "true" : "false");
35 } else if (auto number = std::get_if<RemoteObjectType::NumberT>(&remobjValue)) {
36 if (auto integer = std::get_if<int32_t>(number)) {
37 propPreviewValue.emplace(std::to_string(*integer));
38 } else if (auto floatingPoint = std::get_if<double>(number)) {
39 propPreviewValue.emplace(
40 ark::helpers::string::Format("%g", *floatingPoint)); // NOLINT(cppcoreguidelines-pro-type-vararg)
41 } else {
42 UNREACHABLE();
43 }
44 } else if (auto bigint = std::get_if<RemoteObjectType::BigIntT>(&remobjValue)) {
45 propPreviewValue.emplace(RemoteObject::GetDescription(*bigint));
46 } else if (auto string = std::get_if<std::string>(&remobjValue)) {
47 propPreviewValue.emplace(*string);
48 } else if (auto symbol = std::get_if<RemoteObjectType::SymbolT>(&remobjValue)) {
49 propPreviewValue.emplace(symbol->description);
50 } else if (auto object = std::get_if<RemoteObjectType::ObjectT>(&remobjValue)) {
51 propPreviewValue.emplace(RemoteObject::GetDescription(*object));
52 } else if (auto array = std::get_if<RemoteObjectType::ArrayT>(&remobjValue)) {
53 propPreviewValue.emplace(RemoteObject::GetDescription(*array));
54 } else if (auto function = std::get_if<RemoteObjectType::FunctionT>(&remobjValue)) {
55 propPreviewValue.emplace(function->name);
56 }
57
58 return propPreviewValue;
59 }
60 } // namespace
61
ObjectPreview(RemoteObjectType type,const std::vector<PropertyDescriptor> & properties)62 ObjectPreview::ObjectPreview(RemoteObjectType type, const std::vector<PropertyDescriptor> &properties)
63 : type_(std::move(type))
64 {
65 overflow_ = (properties.size() > PROPERTIES_NMB_LIMIT);
66
67 auto start = properties.begin();
68 auto end = start + std::min(properties.size(), PROPERTIES_NMB_LIMIT);
69
70 for (auto propertyIt = start; propertyIt != end; ++propertyIt) {
71 if (!propertyIt->IsEnumerable()) {
72 continue;
73 }
74
75 if (propertyIt->IsAccessor()) {
76 properties_.emplace_back(propertyIt->GetName(), RemoteObjectType::Accessor());
77 continue;
78 }
79
80 auto propPreviewValue = GetPropertyPreviewValue(propertyIt->GetValue().GetValue());
81
82 properties_.emplace_back(propertyIt->GetName(), propertyIt->GetValue().GetType(), std::move(*propPreviewValue));
83 }
84 }
85
Serialize(JsonObjectBuilder & builder) const86 void ObjectPreview::Serialize(JsonObjectBuilder &builder) const
87 {
88 type_.Serialize(builder);
89 builder.AddProperty("overflow", overflow_);
90
91 builder.AddProperty("properties", [&](JsonArrayBuilder &propertiesBuilder) {
92 for (auto &propertyPreview : properties_) {
93 propertiesBuilder.Add(propertyPreview);
94 }
95 });
96 }
97
98 } // namespace ark::tooling::inspector
99