Coverage Report

Created: 2025-12-18 07:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}