mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 18:42:43 +00:00 
			
		
		
		
	LibWeb: Add support for the Promise<T> IDL type to WrapperGenerator
This includes parsing parameterized types (foo<T>) as well as generating the appropriate code in generate_wrap_statement() and generate_to_cpp().
This commit is contained in:
		
							parent
							
								
									7afd215e95
								
							
						
					
					
						commit
						661dd32432
					
				
					 1 changed files with 25 additions and 8 deletions
				
			
		|  | @ -83,6 +83,7 @@ static size_t get_function_length(FunctionType& function) | ||||||
| 
 | 
 | ||||||
| struct Type { | struct Type { | ||||||
|     String name; |     String name; | ||||||
|  |     Vector<String> parameters; | ||||||
|     bool nullable { false }; |     bool nullable { false }; | ||||||
|     bool is_string() const { return name.is_one_of("ByteString", "CSSOMString", "DOMString", "USVString"); } |     bool is_string() const { return name.is_one_of("ByteString", "CSSOMString", "DOMString", "USVString"); } | ||||||
| }; | }; | ||||||
|  | @ -259,16 +260,25 @@ static NonnullOwnPtr<Interface> parse_interface(StringView filename, StringView | ||||||
|         interface->extended_attributes = parse_extended_attributes(); |         interface->extended_attributes = parse_extended_attributes(); | ||||||
| 
 | 
 | ||||||
|     auto parse_type = [&] { |     auto parse_type = [&] { | ||||||
|  |         auto consume_name = [&] { | ||||||
|  |             return lexer.consume_until([](auto ch) { return !isalnum(ch) && ch != '_'; }); | ||||||
|  |         }; | ||||||
|         bool unsigned_ = lexer.consume_specific("unsigned"); |         bool unsigned_ = lexer.consume_specific("unsigned"); | ||||||
|         if (unsigned_) |         if (unsigned_) | ||||||
|             consume_whitespace(); |             consume_whitespace(); | ||||||
|         auto name = lexer.consume_until([](auto ch) { return !isalnum(ch) && ch != '_'; }); |         auto name = consume_name(); | ||||||
|  |         Vector<String> parameters; | ||||||
|  |         if (lexer.consume_specific('<')) { | ||||||
|  |             // TODO: Parse multiple parameters if necessary
 | ||||||
|  |             parameters.append(consume_name()); | ||||||
|  |             lexer.consume_specific('>'); | ||||||
|  |         } | ||||||
|         auto nullable = lexer.consume_specific('?'); |         auto nullable = lexer.consume_specific('?'); | ||||||
|         StringBuilder builder; |         StringBuilder builder; | ||||||
|         if (unsigned_) |         if (unsigned_) | ||||||
|             builder.append("unsigned "); |             builder.append("unsigned "); | ||||||
|         builder.append(name); |         builder.append(name); | ||||||
|         return Type { builder.to_string(), nullable }; |         return Type { builder.to_string(), parameters, nullable }; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     auto parse_attribute = [&](HashMap<String, String>& extended_attributes) { |     auto parse_attribute = [&](HashMap<String, String>& extended_attributes) { | ||||||
|  | @ -1071,6 +1081,18 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter | ||||||
|     } else { |     } else { | ||||||
|         return JS::js_undefined(); |         return JS::js_undefined(); | ||||||
|     } |     } | ||||||
|  | )~~~"); | ||||||
|  |     } else if (parameter.type.name == "Promise") { | ||||||
|  |         // NOTE: It's not clear to me where the implicit wrapping of non-Promise values in a resolved
 | ||||||
|  |         // Promise is defined in the spec; https://webidl.spec.whatwg.org/#idl-promise doesn't say
 | ||||||
|  |         // anything of this sort. Both Gecko and Blink do it, however, so I'm sure it's correct.
 | ||||||
|  |         scoped_generator.append(R"~~~( | ||||||
|  |     if (!@js_name@@js_suffix@.is_object() || !is<JS::Promise>(@js_name@@js_suffix@.as_object())) { | ||||||
|  |         auto* new_promise = JS::Promise::create(global_object); | ||||||
|  |         new_promise->fulfill(@js_name@@js_suffix@); | ||||||
|  |         @js_name@@js_suffix@ = new_promise; | ||||||
|  |     } | ||||||
|  |     auto @cpp_name@ = JS::make_handle(&static_cast<JS::Promise&>(@js_name@@js_suffix@.as_object())); | ||||||
| )~~~"); | )~~~"); | ||||||
|     } else if (parameter.type.name == "any") { |     } else if (parameter.type.name == "any") { | ||||||
|         if (!optional) { |         if (!optional) { | ||||||
|  | @ -1247,7 +1269,7 @@ static void generate_wrap_statement(SourceGenerator& generator, String const& va | ||||||
|         scoped_generator.append(R"~~~( |         scoped_generator.append(R"~~~( | ||||||
|     @result_expression@ JS::Value((i32)@value@); |     @result_expression@ JS::Value((i32)@value@); | ||||||
| )~~~"); | )~~~"); | ||||||
|     } else if (type.name == "Uint8ClampedArray" || type.name == "any") { |     } else if (type.name == "Location" || type.name == "Promise" || type.name == "Uint8ClampedArray" || type.name == "any") { | ||||||
|         scoped_generator.append(R"~~~( |         scoped_generator.append(R"~~~( | ||||||
|     @result_expression@ @value@; |     @result_expression@ @value@; | ||||||
| )~~~"); | )~~~"); | ||||||
|  | @ -1257,11 +1279,6 @@ static void generate_wrap_statement(SourceGenerator& generator, String const& va | ||||||
|         @result_expression@ JS::js_null(); |         @result_expression@ JS::js_null(); | ||||||
|     else |     else | ||||||
|         @result_expression@ @value@.callback.cell(); |         @result_expression@ @value@.callback.cell(); | ||||||
| )~~~"); |  | ||||||
|     } else if (type.name == "Location") { |  | ||||||
|         // Location is special cased as it is already a JS::Object.
 |  | ||||||
|         scoped_generator.append(R"~~~( |  | ||||||
|     @result_expression@ JS::Value(@value@); |  | ||||||
| )~~~"); | )~~~"); | ||||||
|     } else { |     } else { | ||||||
|         scoped_generator.append(R"~~~( |         scoped_generator.append(R"~~~( | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Linus Groh
						Linus Groh