2022-10-17 00:59:27 +00:00
/*
* Copyright ( c ) 2022 , LI YUBEI < leeight @ gmail . com >
*
* SPDX - License - Identifier : BSD - 2 - Clause
*/
2022-11-23 11:45:58 +00:00
# include <AK/Utf16View.h>
2022-10-17 00:59:27 +00:00
# include <LibJS/Runtime/RegExpConstructor.h>
# include <LibJS/Runtime/RegExpLegacyStaticProperties.h>
# include <LibJS/Runtime/VM.h>
namespace JS {
void RegExpLegacyStaticProperties : : invalidate ( )
{
m_input = { } ;
m_last_match = { } ;
m_last_paren = { } ;
m_left_context = { } ;
m_right_context = { } ;
m_ $ 1 = { } ;
m_ $ 2 = { } ;
m_ $ 3 = { } ;
m_ $ 4 = { } ;
m_ $ 5 = { } ;
m_ $ 6 = { } ;
m_ $ 7 = { } ;
m_ $ 8 = { } ;
m_ $ 9 = { } ;
}
// GetLegacyRegExpStaticProperty( C, thisValue, internalSlotName ), https://github.com/tc39/proposal-regexp-legacy-features#getlegacyregexpstaticproperty-c-thisvalue-internalslotname-
2022-10-19 13:35:35 +00:00
ThrowCompletionOr < Value > get_legacy_regexp_static_property ( VM & vm , RegExpConstructor & constructor , Value this_value , Optional < Utf16String > const & ( RegExpLegacyStaticProperties : : * property_getter ) ( ) const )
2022-10-17 00:59:27 +00:00
{
// 1. Assert C is an object that has an internal slot named internalSlotName.
// 2. If SameValue(C, thisValue) is false, throw a TypeError exception.
if ( ! same_value ( & constructor , this_value ) )
return vm . throw_completion < TypeError > ( ErrorType : : GetLegacyRegExpStaticPropertyThisValueMismatch ) ;
// 3. Let val be the value of the internal slot of C named internalSlotName.
auto val = ( constructor . legacy_static_properties ( ) . * property_getter ) ( ) ;
// 4. If val is empty, throw a TypeError exception.
if ( ! val . has_value ( ) )
return vm . throw_completion < TypeError > ( ErrorType : : GetLegacyRegExpStaticPropertyValueEmpty ) ;
// 5. Return val.
2022-12-06 22:17:27 +00:00
return PrimitiveString : : create ( vm , val . release_value ( ) ) ;
2022-10-17 00:59:27 +00:00
}
// SetLegacyRegExpStaticProperty( C, thisValue, internalSlotName, val ), https://github.com/tc39/proposal-regexp-legacy-features#setlegacyregexpstaticproperty-c-thisvalue-internalslotname-val-
2022-10-19 13:35:35 +00:00
ThrowCompletionOr < void > set_legacy_regexp_static_property ( VM & vm , RegExpConstructor & constructor , Value this_value , void ( RegExpLegacyStaticProperties : : * property_setter ) ( Utf16String ) , Value value )
2022-10-17 00:59:27 +00:00
{
// 1. Assert C is an object that has an internal slot named internalSlotName.
// 2. If SameValue(C, thisValue) is false, throw a TypeError exception.
if ( ! same_value ( & constructor , this_value ) )
return vm . throw_completion < TypeError > ( ErrorType : : SetLegacyRegExpStaticPropertyThisValueMismatch ) ;
// 3. Let strVal be ? ToString(val).
2022-10-19 13:35:35 +00:00
auto str_value = TRY ( value . to_utf16_string ( vm ) ) ;
2022-10-17 00:59:27 +00:00
// 4. Set the value of the internal slot of C named internalSlotName to strVal.
( constructor . legacy_static_properties ( ) . * property_setter ) ( str_value ) ;
return { } ;
}
// UpdateLegacyRegExpStaticProperties ( C, S, startIndex, endIndex, capturedValues ), https://github.com/tc39/proposal-regexp-legacy-features#updatelegacyregexpstaticproperties--c-s-startindex-endindex-capturedvalues-
2023-08-08 16:54:20 +00:00
void update_legacy_regexp_static_properties ( RegExpConstructor & constructor , Utf16String const & string , size_t start_index , size_t end_index , Vector < Utf16String > const & captured_values )
2022-10-17 00:59:27 +00:00
{
auto & legacy_static_properties = constructor . legacy_static_properties ( ) ;
// 1. Assert: C is an Object that has a [[RegExpInput]] internal slot.
// 2. Assert: Type(S) is String.
// 3. Let len be the number of code units in S.
auto len = string . length_in_code_units ( ) ;
// 4. Assert: startIndex and endIndex are integers such that 0 ≤ startIndex ≤ endIndex ≤ len.
VERIFY ( start_index < = end_index ) ;
VERIFY ( end_index < = len ) ;
// 5. Assert: capturedValues is a List of Strings.
// 6. Let n be the number of elements in capturedValues.
auto group_count = captured_values . size ( ) ;
// 7. Set the value of C’ s [[RegExpInput]] internal slot to S.
2022-10-19 13:35:35 +00:00
legacy_static_properties . set_input ( string ) ;
2022-10-17 00:59:27 +00:00
// 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.
auto last_match = string . view ( ) . substring_view ( start_index , end_index - start_index ) ;
2023-08-08 16:54:20 +00:00
legacy_static_properties . set_last_match ( Utf16String : : create ( last_match ) ) ;
2022-10-17 00:59:27 +00:00
// 9. If n > 0, set the value of C’ s [[RegExpLastParen]] internal slot to the last element of capturedValues.
if ( group_count > 0 ) {
auto item = captured_values [ group_count - 1 ] ;
legacy_static_properties . set_last_paren ( item ) ;
}
// 10. Else, set the value of C’ s [[RegExpLastParen]] internal slot to the empty String.
else {
2023-08-08 16:54:20 +00:00
legacy_static_properties . set_last_paren ( Utf16String : : create ( ) ) ;
2022-10-17 00:59:27 +00:00
}
// 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.
auto left_context = string . view ( ) . substring_view ( 0 , start_index ) ;
2023-08-08 16:54:20 +00:00
legacy_static_properties . set_left_context ( Utf16String : : create ( left_context ) ) ;
2022-10-17 00:59:27 +00:00
// 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.
auto right_context = string . view ( ) . substring_view ( end_index , len - end_index ) ;
2023-08-08 16:54:20 +00:00
legacy_static_properties . set_right_context ( Utf16String : : create ( right_context ) ) ;
2022-10-17 00:59:27 +00:00
// 13. For each integer i such that 1 ≤ i ≤ 9
for ( size_t i = 1 ; i < = 9 ; i + + ) {
2023-01-07 17:24:05 +00:00
// i. If i ≤ n, set the value of C’ s [[RegExpPareni]] internal slot to the ith element of capturedValues.
// ii. Else, set the value of C’ s [[RegExpPareni]] internal slot to the empty String.
2023-08-08 16:54:20 +00:00
auto value = ( i < = group_count ) ? captured_values [ i - 1 ] : Utf16String : : create ( ) ;
2022-10-17 00:59:27 +00:00
if ( i = = 1 ) {
2023-01-07 17:24:05 +00:00
legacy_static_properties . set_ $ 1 ( move ( value ) ) ;
2022-10-17 00:59:27 +00:00
} else if ( i = = 2 ) {
2023-01-07 17:24:05 +00:00
legacy_static_properties . set_ $ 2 ( move ( value ) ) ;
2022-10-17 00:59:27 +00:00
} else if ( i = = 3 ) {
2023-01-07 17:24:05 +00:00
legacy_static_properties . set_ $ 3 ( move ( value ) ) ;
2022-10-17 00:59:27 +00:00
} else if ( i = = 4 ) {
2023-01-07 17:24:05 +00:00
legacy_static_properties . set_ $ 4 ( move ( value ) ) ;
2022-10-17 00:59:27 +00:00
} else if ( i = = 5 ) {
2023-01-07 17:24:05 +00:00
legacy_static_properties . set_ $ 5 ( move ( value ) ) ;
2022-10-17 00:59:27 +00:00
} else if ( i = = 6 ) {
2023-01-07 17:24:05 +00:00
legacy_static_properties . set_ $ 6 ( move ( value ) ) ;
2022-10-17 00:59:27 +00:00
} else if ( i = = 7 ) {
2023-01-07 17:24:05 +00:00
legacy_static_properties . set_ $ 7 ( move ( value ) ) ;
2022-10-17 00:59:27 +00:00
} else if ( i = = 8 ) {
2023-01-07 17:24:05 +00:00
legacy_static_properties . set_ $ 8 ( move ( value ) ) ;
2022-10-17 00:59:27 +00:00
} else if ( i = = 9 ) {
2023-01-07 17:24:05 +00:00
legacy_static_properties . set_ $ 9 ( move ( value ) ) ;
2022-10-17 00:59:27 +00:00
}
}
}
// InvalidateLegacyRegExpStaticProperties ( C ), https://github.com/tc39/proposal-regexp-legacy-features#invalidatelegacyregexpstaticproperties--c
void invalidate_legacy_regexp_static_properties ( RegExpConstructor & constructor )
{
// 1. Assert: C is an Object that has a [[RegExpInput]] internal slot.
// 2. Set the value of the following internal slots of C to empty:
constructor . legacy_static_properties ( ) . invalidate ( ) ;
}
}