/src/serenity/Userland/Libraries/LibJS/Runtime/PropertyAttributes.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2020, Matthew Olsson <mattco@serenityos.org> |
3 | | * Copyright (c) 2021, Linus Groh <linusg@serenityos.org> |
4 | | * |
5 | | * SPDX-License-Identifier: BSD-2-Clause |
6 | | */ |
7 | | |
8 | | #pragma once |
9 | | |
10 | | #include <AK/ByteString.h> |
11 | | #include <AK/Format.h> |
12 | | #include <AK/Types.h> |
13 | | #include <AK/Vector.h> |
14 | | |
15 | | namespace JS { |
16 | | |
17 | | struct Attribute { |
18 | | enum { |
19 | | Writable = 1 << 0, |
20 | | Enumerable = 1 << 1, |
21 | | Configurable = 1 << 2, |
22 | | // AD-HOC: This is used for reporting unimplemented IDL interfaces. |
23 | | Unimplemented = 1 << 3, |
24 | | }; |
25 | | }; |
26 | | |
27 | | // 6.1.7.1 Property Attributes, https://tc39.es/ecma262/#sec-property-attributes |
28 | | class PropertyAttributes { |
29 | | public: |
30 | | PropertyAttributes(u8 bits = 0) |
31 | 502 | : m_bits(bits) |
32 | 502 | { |
33 | 502 | } |
34 | | |
35 | 0 | [[nodiscard]] bool is_writable() const { return m_bits & Attribute::Writable; } |
36 | 0 | [[nodiscard]] bool is_enumerable() const { return m_bits & Attribute::Enumerable; } |
37 | 0 | [[nodiscard]] bool is_configurable() const { return m_bits & Attribute::Configurable; } |
38 | 0 | [[nodiscard]] bool is_unimplemented() const { return m_bits & Attribute::Unimplemented; } |
39 | | |
40 | | void set_writable(bool writable = true) |
41 | 0 | { |
42 | 0 | if (writable) |
43 | 0 | m_bits |= Attribute::Writable; |
44 | 0 | else |
45 | 0 | m_bits &= ~Attribute::Writable; |
46 | 0 | } |
47 | | |
48 | | void set_enumerable(bool enumerable = true) |
49 | 0 | { |
50 | 0 | if (enumerable) |
51 | 0 | m_bits |= Attribute::Enumerable; |
52 | 0 | else |
53 | 0 | m_bits &= ~Attribute::Enumerable; |
54 | 0 | } |
55 | | |
56 | | void set_configurable(bool configurable = true) |
57 | 0 | { |
58 | 0 | if (configurable) |
59 | 0 | m_bits |= Attribute::Configurable; |
60 | 0 | else |
61 | 0 | m_bits &= ~Attribute::Configurable; |
62 | 0 | } |
63 | | |
64 | 0 | bool operator==(PropertyAttributes const& other) const { return m_bits == other.m_bits; } |
65 | | |
66 | 0 | [[nodiscard]] u8 bits() const { return m_bits; } |
67 | | |
68 | | private: |
69 | | u8 m_bits; |
70 | | }; |
71 | | |
72 | | PropertyAttributes const default_attributes = Attribute::Configurable | Attribute::Writable | Attribute::Enumerable; |
73 | | |
74 | | } |
75 | | |
76 | | namespace AK { |
77 | | |
78 | | template<> |
79 | | struct Formatter<JS::PropertyAttributes> : Formatter<StringView> { |
80 | | ErrorOr<void> format(FormatBuilder& builder, JS::PropertyAttributes const& property_attributes) |
81 | 0 | { |
82 | 0 | Vector<ByteString> parts; |
83 | 0 | parts.append(ByteString::formatted("[[Writable]]: {}", property_attributes.is_writable())); |
84 | 0 | parts.append(ByteString::formatted("[[Enumerable]]: {}", property_attributes.is_enumerable())); |
85 | 0 | parts.append(ByteString::formatted("[[Configurable]]: {}", property_attributes.is_configurable())); |
86 | 0 | return Formatter<StringView>::format(builder, ByteString::formatted("PropertyAttributes {{ {} }}", ByteString::join(", "sv, parts))); |
87 | 0 | } |
88 | | }; |
89 | | |
90 | | } |