mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 16:52:43 +00:00 
			
		
		
		
	LibJS: Make RegExp.prototype.flags spec-compliant
This should be using the individual flag boolean properties rather than the [[OriginalFlags]] internal slot. Use an enumerator macro here for brevity, this will be useful for other things as well. :^)
This commit is contained in:
		
							parent
							
								
									5cb45e4feb
								
							
						
					
					
						commit
						ee66eaa1b0
					
				
					 3 changed files with 38 additions and 15 deletions
				
			
		|  | @ -92,6 +92,14 @@ | |||
|     __JS_ENUMERATE(toPrimitive, to_primitive)                \ | ||||
|     __JS_ENUMERATE(toStringTag, to_string_tag) | ||||
| 
 | ||||
| #define JS_ENUMERATE_REGEXP_FLAGS                           \ | ||||
|     __JS_ENUMERATE(global, global, g, Global)               \ | ||||
|     __JS_ENUMERATE(ignoreCase, ignore_case, i, Insensitive) \ | ||||
|     __JS_ENUMERATE(multiline, multiline, m, Multiline)      \ | ||||
|     __JS_ENUMERATE(dotAll, dot_all, s, SingleLine)          \ | ||||
|     __JS_ENUMERATE(unicode, unicode, u, Unicode)            \ | ||||
|     __JS_ENUMERATE(sticky, sticky, y, Sticky) | ||||
| 
 | ||||
| namespace JS { | ||||
| 
 | ||||
| class ASTNode; | ||||
|  |  | |||
|  | @ -62,6 +62,16 @@ RegExpPrototype::~RegExpPrototype() | |||
| { | ||||
| } | ||||
| 
 | ||||
| static Object* this_object_from(VM& vm, GlobalObject& global_object) | ||||
| { | ||||
|     auto this_value = vm.this_value(global_object); | ||||
|     if (!this_value.is_object()) { | ||||
|         vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObject, this_value.to_string_without_side_effects()); | ||||
|         return {}; | ||||
|     } | ||||
|     return &this_value.as_object(); | ||||
| } | ||||
| 
 | ||||
| static RegExpObject* regexp_object_from(VM& vm, GlobalObject& global_object) | ||||
| { | ||||
|     auto* this_object = vm.this_value(global_object).to_object(global_object); | ||||
|  | @ -85,25 +95,20 @@ JS_DEFINE_NATIVE_GETTER(RegExpPrototype::dot_all) | |||
| 
 | ||||
| JS_DEFINE_NATIVE_GETTER(RegExpPrototype::flags) | ||||
| { | ||||
|     auto regexp_object = regexp_object_from(vm, global_object); | ||||
|     if (!regexp_object) | ||||
|     auto this_object = this_object_from(vm, global_object); | ||||
|     if (!this_object) | ||||
|         return {}; | ||||
| 
 | ||||
|     auto flags = regexp_object->declared_options(); | ||||
|     StringBuilder builder(8); | ||||
| 
 | ||||
|     if (flags.has_flag_set(ECMAScriptFlags::Global)) | ||||
|         builder.append('g'); | ||||
|     if (flags.has_flag_set(ECMAScriptFlags::Insensitive)) | ||||
|         builder.append('i'); | ||||
|     if (flags.has_flag_set(ECMAScriptFlags::Multiline)) | ||||
|         builder.append('m'); | ||||
|     if (flags.has_flag_set(ECMAScriptFlags::SingleLine)) | ||||
|         builder.append('s'); | ||||
|     if (flags.has_flag_set(ECMAScriptFlags::Unicode)) | ||||
|         builder.append('u'); | ||||
|     if (flags.has_flag_set(ECMAScriptFlags::Sticky)) | ||||
|         builder.append('y'); | ||||
| #define __JS_ENUMERATE(flagName, flag_name, flag_char, ECMAScriptFlagName)                \ | ||||
|     auto flag_##flag_name = this_object->get(vm.names.flagName).value_or(js_undefined()); \ | ||||
|     if (vm.exception())                                                                   \ | ||||
|         return {};                                                                        \ | ||||
|     if (flag_##flag_name.to_boolean())                                                    \ | ||||
|         builder.append(#flag_char); | ||||
|     JS_ENUMERATE_REGEXP_FLAGS | ||||
| #undef __JS_ENUMERATE | ||||
| 
 | ||||
|     return js_string(vm, builder.to_string()); | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,10 @@ | |||
| test("basic functionality", () => { | ||||
|     expect(/foo/.flags).toBe(""); | ||||
|     expect(/foo/g.flags).toBe("g"); | ||||
|     expect(/foo/i.flags).toBe("i"); | ||||
|     expect(/foo/m.flags).toBe("m"); | ||||
|     expect(/foo/s.flags).toBe("s"); | ||||
|     expect(/foo/u.flags).toBe("u"); | ||||
|     expect(/foo/y.flags).toBe("y"); | ||||
|     expect(/foo/sgimyu.flags).toBe("gimsuy"); | ||||
| }); | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Linus Groh
						Linus Groh