/src/serenity/Userland/Libraries/LibJS/Runtime/RegExpLegacyStaticProperties.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2022, LI YUBEI <leeight@gmail.com> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #include <AK/Utf16View.h> |
8 | | #include <LibJS/Runtime/RegExpConstructor.h> |
9 | | #include <LibJS/Runtime/RegExpLegacyStaticProperties.h> |
10 | | #include <LibJS/Runtime/VM.h> |
11 | | |
12 | | namespace JS { |
13 | | |
14 | | void RegExpLegacyStaticProperties::invalidate() |
15 | 0 | { |
16 | 0 | m_input = {}; |
17 | 0 | m_last_match = {}; |
18 | 0 | m_last_match_string = {}; |
19 | 0 | m_last_paren = {}; |
20 | 0 | m_left_context = {}; |
21 | 0 | m_left_context_string = {}; |
22 | 0 | m_right_context = {}; |
23 | 0 | m_right_context_string = {}; |
24 | 0 | m_$1 = {}; |
25 | 0 | m_$2 = {}; |
26 | 0 | m_$3 = {}; |
27 | 0 | m_$4 = {}; |
28 | 0 | m_$5 = {}; |
29 | 0 | m_$6 = {}; |
30 | 0 | m_$7 = {}; |
31 | 0 | m_$8 = {}; |
32 | 0 | m_$9 = {}; |
33 | 0 | } |
34 | | |
35 | | // GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ), https://github.com/tc39/proposal-regexp-legacy-features#getlegacyregexpstaticproperty-c-thisvalue-internalslotname- |
36 | | ThrowCompletionOr<Value> get_legacy_regexp_static_property(VM& vm, RegExpConstructor& constructor, Value this_value, Optional<Utf16String> const& (RegExpLegacyStaticProperties::*property_getter)() const) |
37 | 0 | { |
38 | | // 1. Assert C is an object that has an internal slot named internalSlotName. |
39 | | |
40 | | // 2. If SameValue(C, thisValue) is false, throw a TypeError exception. |
41 | 0 | if (!same_value(&constructor, this_value)) |
42 | 0 | return vm.throw_completion<TypeError>(ErrorType::GetLegacyRegExpStaticPropertyThisValueMismatch); |
43 | | |
44 | | // 3. Let val be the value of the internal slot of C named internalSlotName. |
45 | 0 | auto val = (constructor.legacy_static_properties().*property_getter)(); |
46 | | |
47 | | // 4. If val is empty, throw a TypeError exception. |
48 | 0 | if (!val.has_value()) |
49 | 0 | return vm.throw_completion<TypeError>(ErrorType::GetLegacyRegExpStaticPropertyValueEmpty); |
50 | | |
51 | | // 5. Return val. |
52 | 0 | return PrimitiveString::create(vm, val.release_value()); |
53 | 0 | } |
54 | | |
55 | | // SetLegacyRegExpStaticProperty( C, thisValue, internalSlotName, val ), https://github.com/tc39/proposal-regexp-legacy-features#setlegacyregexpstaticproperty-c-thisvalue-internalslotname-val- |
56 | | ThrowCompletionOr<void> set_legacy_regexp_static_property(VM& vm, RegExpConstructor& constructor, Value this_value, void (RegExpLegacyStaticProperties::*property_setter)(Utf16String), Value value) |
57 | 0 | { |
58 | | // 1. Assert C is an object that has an internal slot named internalSlotName. |
59 | | |
60 | | // 2. If SameValue(C, thisValue) is false, throw a TypeError exception. |
61 | 0 | if (!same_value(&constructor, this_value)) |
62 | 0 | return vm.throw_completion<TypeError>(ErrorType::SetLegacyRegExpStaticPropertyThisValueMismatch); |
63 | | |
64 | | // 3. Let strVal be ? ToString(val). |
65 | 0 | auto str_value = TRY(value.to_utf16_string(vm)); |
66 | | |
67 | | // 4. Set the value of the internal slot of C named internalSlotName to strVal. |
68 | 0 | (constructor.legacy_static_properties().*property_setter)(str_value); |
69 | |
|
70 | 0 | return {}; |
71 | 0 | } |
72 | | |
73 | | // UpdateLegacyRegExpStaticProperties ( C, S, startIndex, endIndex, capturedValues ), https://github.com/tc39/proposal-regexp-legacy-features#updatelegacyregexpstaticproperties--c-s-startindex-endindex-capturedvalues- |
74 | | void update_legacy_regexp_static_properties(RegExpConstructor& constructor, Utf16String const& string, size_t start_index, size_t end_index, Vector<Utf16String> const& captured_values) |
75 | 0 | { |
76 | 0 | auto& legacy_static_properties = constructor.legacy_static_properties(); |
77 | | |
78 | | // 1. Assert: C is an Object that has a [[RegExpInput]] internal slot. |
79 | | // 2. Assert: Type(S) is String. |
80 | | |
81 | | // 3. Let len be the number of code units in S. |
82 | 0 | auto len = string.length_in_code_units(); |
83 | | |
84 | | // 4. Assert: startIndex and endIndex are integers such that 0 ≤ startIndex ≤ endIndex ≤ len. |
85 | 0 | VERIFY(start_index <= end_index); |
86 | 0 | VERIFY(end_index <= len); |
87 | | |
88 | | // 5. Assert: capturedValues is a List of Strings. |
89 | | |
90 | | // 6. Let n be the number of elements in capturedValues. |
91 | 0 | auto group_count = captured_values.size(); |
92 | | |
93 | | // 7. Set the value of C’s [[RegExpInput]] internal slot to S. |
94 | 0 | legacy_static_properties.set_input(string); |
95 | | |
96 | | // 8. Set the value of C’s [[RegExpLastMatch]] internal slot to a String whose length is endIndex - startIndex and containing the code units from S with indices startIndex through endIndex - 1, in ascending order. |
97 | 0 | auto last_match = string.view().substring_view(start_index, end_index - start_index); |
98 | 0 | legacy_static_properties.set_last_match(last_match); |
99 | | |
100 | | // 9. If n > 0, set the value of C’s [[RegExpLastParen]] internal slot to the last element of capturedValues. |
101 | 0 | if (group_count > 0) { |
102 | 0 | auto item = captured_values[group_count - 1]; |
103 | 0 | legacy_static_properties.set_last_paren(item); |
104 | 0 | } |
105 | | // 10. Else, set the value of C’s [[RegExpLastParen]] internal slot to the empty String. |
106 | 0 | else { |
107 | 0 | legacy_static_properties.set_last_paren(Utf16String::create()); |
108 | 0 | } |
109 | | |
110 | | // 11. Set the value of C’s [[RegExpLeftContext]] internal slot to a String whose length is startIndex and containing the code units from S with indices 0 through startIndex - 1, in ascending order. |
111 | 0 | auto left_context = string.view().substring_view(0, start_index); |
112 | 0 | legacy_static_properties.set_left_context(left_context); |
113 | | |
114 | | // 12. Set the value of C’s [[RegExpRightContext]] internal slot to a String whose length is len - endIndex and containing the code units from S with indices endIndex through len - 1, in ascending order. |
115 | 0 | auto right_context = string.view().substring_view(end_index, len - end_index); |
116 | 0 | legacy_static_properties.set_right_context(right_context); |
117 | | |
118 | | // 13. For each integer i such that 1 ≤ i ≤ 9 |
119 | 0 | for (size_t i = 1; i <= 9; i++) { |
120 | | // i. If i ≤ n, set the value of C’s [[RegExpPareni]] internal slot to the ith element of capturedValues. |
121 | | // ii. Else, set the value of C’s [[RegExpPareni]] internal slot to the empty String. |
122 | 0 | auto value = (i <= group_count) ? captured_values[i - 1] : Utf16String::create(); |
123 | |
|
124 | 0 | if (i == 1) { |
125 | 0 | legacy_static_properties.set_$1(move(value)); |
126 | 0 | } else if (i == 2) { |
127 | 0 | legacy_static_properties.set_$2(move(value)); |
128 | 0 | } else if (i == 3) { |
129 | 0 | legacy_static_properties.set_$3(move(value)); |
130 | 0 | } else if (i == 4) { |
131 | 0 | legacy_static_properties.set_$4(move(value)); |
132 | 0 | } else if (i == 5) { |
133 | 0 | legacy_static_properties.set_$5(move(value)); |
134 | 0 | } else if (i == 6) { |
135 | 0 | legacy_static_properties.set_$6(move(value)); |
136 | 0 | } else if (i == 7) { |
137 | 0 | legacy_static_properties.set_$7(move(value)); |
138 | 0 | } else if (i == 8) { |
139 | 0 | legacy_static_properties.set_$8(move(value)); |
140 | 0 | } else if (i == 9) { |
141 | 0 | legacy_static_properties.set_$9(move(value)); |
142 | 0 | } |
143 | 0 | } |
144 | 0 | } |
145 | | |
146 | | // InvalidateLegacyRegExpStaticProperties ( C ), https://github.com/tc39/proposal-regexp-legacy-features#invalidatelegacyregexpstaticproperties--c |
147 | | void invalidate_legacy_regexp_static_properties(RegExpConstructor& constructor) |
148 | 0 | { |
149 | | // 1. Assert: C is an Object that has a [[RegExpInput]] internal slot. |
150 | | |
151 | | // 2. Set the value of the following internal slots of C to empty: |
152 | 0 | constructor.legacy_static_properties().invalidate(); |
153 | 0 | } |
154 | | |
155 | | } |