2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/*
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * All rights reserved.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * Redistribution and use in source and binary forms, with or without
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * modification, are permitted provided that the following conditions are met:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * 1. Redistributions of source code must retain the above copyright notice, this
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *    list of conditions and the following disclaimer.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * 2. Redistributions in binary form must reproduce the above copyright notice,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *    this list of conditions and the following disclaimer in the documentation
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *    and/or other materials provided with the distribution.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <AK/ByteBuffer.h>
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include <AK/GenericLexer.h>
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 12:59:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include <AK/HashMap.h>
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-26 19:37:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include <AK/LexicalPath.h>
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <AK/StringBuilder.h>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <LibCore/ArgsParser.h>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <LibCore/File.h>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <ctype.h>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:19:29 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static String snake_name(const StringView& title_name)
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    StringBuilder builder;
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:19:29 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    bool first = true;
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 11:39:32 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    bool last_was_uppercase = false;
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:19:29 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    for (auto ch : title_name) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if (isupper(ch)) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 11:39:32 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            if (!first && !last_was_uppercase)
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:19:29 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                builder.append('_');
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            builder.append(tolower(ch));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        } else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            builder.append(ch);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:19:29 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        first = false;
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 11:39:32 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        last_was_uppercase = isupper(ch);
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return builder.to_string();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-09 17:10:41 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static String make_input_acceptable_cpp(const String& input)
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 13:23:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-09 17:10:41 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    if (input == "class" || input == "template" || input == "for") {
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 13:23:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        StringBuilder builder;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        builder.append(input);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        builder.append('_');
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return builder.to_string();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-09 17:10:41 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    String input_without_dashes = input;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    input_without_dashes.replace("-", "_");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return input_without_dashes;
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 13:23:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								namespace IDL {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								struct Type {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    String name;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    bool nullable { false };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								struct Parameter {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    Type type;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    String name;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								struct Function {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    Type return_type;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    String name;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    Vector<Parameter> parameters;
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 12:59:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    HashMap<String, String> extended_attributes;
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    size_t length() const
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        // FIXME: Take optional arguments into account
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return parameters.size();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								struct Attribute {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    bool readonly { false };
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 15:37:13 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    bool unsigned_ { false };
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    Type type;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    String name;
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 12:59:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    HashMap<String, String> extended_attributes;
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // Added for convenience after parsing
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    String getter_callback_name;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    String setter_callback_name;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								struct Interface {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    String name;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    String parent_name;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    Vector<Attribute> attributes;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    Vector<Function> functions;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // Added for convenience after parsing
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    String wrapper_class;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    String wrapper_base_class;
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-26 19:37:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    String fully_qualified_name;
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-11 00:07:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static OwnPtr<Interface> parse_interface(const StringView& input)
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    auto interface = make<Interface>();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    GenericLexer lexer(input);
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    auto assert_specific = [&](char ch) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        auto consumed = lexer.consume();
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if (consumed != ch) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            dbg() << "Expected '" << ch << "' at offset " << lexer.tell() << " but got '" << consumed << "'";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            ASSERT_NOT_REACHED();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    auto consume_whitespace = [&] {
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        lexer.consume_while([](char ch) { return isspace(ch); });
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    auto assert_string = [&](const StringView& expected) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        bool saw_expected = lexer.consume_specific(expected);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        ASSERT(saw_expected);
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    assert_string("interface");
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    consume_whitespace();
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    interface->name = lexer.consume_until([](auto ch) { return isspace(ch); });
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    consume_whitespace();
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    if (lexer.consume_specific(':')) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        consume_whitespace();
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        interface->parent_name = lexer.consume_until([](auto ch) { return isspace(ch); });
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        consume_whitespace();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    assert_specific('{');
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    auto parse_type = [&] {
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        auto name = lexer.consume_until([](auto ch) { return isspace(ch) || ch == '?'; });
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        auto nullable = lexer.consume_specific('?');
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return Type { name, nullable };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 12:59:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    auto parse_attribute = [&](HashMap<String, String>& extended_attributes) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        bool readonly = lexer.consume_specific("readonly");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if (readonly)
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            consume_whitespace();
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if (lexer.consume_specific("attribute"))
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            consume_whitespace();
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        bool unsigned_ = lexer.consume_specific("unsigned");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if (unsigned_)
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 15:37:13 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            consume_whitespace();
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        auto type = parse_type();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        consume_whitespace();
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        auto name = lexer.consume_until([](auto ch) { return isspace(ch) || ch == ';'; });
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        consume_whitespace();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        assert_specific(';');
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        Attribute attribute;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        attribute.readonly = readonly;
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 15:37:13 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        attribute.unsigned_ = unsigned_;
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        attribute.type = type;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        attribute.name = name;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        attribute.getter_callback_name = String::format("%s_getter", snake_name(attribute.name).characters());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        attribute.setter_callback_name = String::format("%s_setter", snake_name(attribute.name).characters());
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 12:59:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        attribute.extended_attributes = move(extended_attributes);
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        interface->attributes.append(move(attribute));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 12:59:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    auto parse_function = [&](HashMap<String, String>& extended_attributes) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        auto return_type = parse_type();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        consume_whitespace();
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        auto name = lexer.consume_until([](auto ch) { return isspace(ch) || ch == '('; });
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        consume_whitespace();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        assert_specific('(');
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        Vector<Parameter> parameters;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        for (;;) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            if (lexer.consume_specific(')'))
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-22 18:39:22 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                break;
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            auto type = parse_type();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            consume_whitespace();
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            auto name = lexer.consume_until([](auto ch) { return isspace(ch) || ch == ',' || ch == ')'; });
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            parameters.append({ move(type), move(name) });
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            if (lexer.consume_specific(')'))
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                break;
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            assert_specific(',');
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            consume_whitespace();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        consume_whitespace();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        assert_specific(';');
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 12:59:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        interface->functions.append(Function { return_type, name, move(parameters), move(extended_attributes) });
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    auto parse_extended_attributes = [&] {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        HashMap<String, String> extended_attributes;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        for (;;) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            consume_whitespace();
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            if (lexer.consume_specific(']'))
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 12:59:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                break;
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            auto name = lexer.consume_until([](auto ch) { return ch == ']' || ch == '=' || ch == ','; });
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if (lexer.consume_specific('=')) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                auto value = lexer.consume_until([](auto ch) { return ch == ']' || ch == ','; });
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 12:59:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                extended_attributes.set(name, value);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            } else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                extended_attributes.set(name, {});
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        consume_whitespace();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return extended_attributes;
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    for (;;) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 12:59:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        HashMap<String, String> extended_attributes;
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        consume_whitespace();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if (lexer.consume_specific('}'))
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if (lexer.consume_specific('[')) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 12:59:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            extended_attributes = parse_extended_attributes();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-21 09:51:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if (lexer.next_is("readonly") || lexer.next_is("attribute")) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 12:59:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            parse_attribute(extended_attributes);
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            continue;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 12:59:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        parse_function(extended_attributes);
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    interface->wrapper_class = String::format("%sWrapper", interface->name.characters());
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 12:27:41 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    interface->wrapper_base_class = String::format("%sWrapper", interface->parent_name.is_empty() ? "" : interface->parent_name.characters());
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return interface;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static void generate_header(const IDL::Interface&);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static void generate_implementation(const IDL::Interface&);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								int main(int argc, char** argv)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    Core::ArgsParser args_parser;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    const char* path = nullptr;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    bool header_mode = false;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    bool implementation_mode = false;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    args_parser.add_option(header_mode, "Generate the wrapper .h file", "header", 'H');
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    args_parser.add_option(implementation_mode, "Generate the wrapper .cpp file", "implementation", 'I');
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    args_parser.add_positional_argument(path, "IDL file", "idl-file");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    args_parser.parse(argc, argv);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    auto file_or_error = Core::File::open(path, Core::IODevice::ReadOnly);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if (file_or_error.is_error()) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        fprintf(stderr, "Cannot open %s\n", path);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return 1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-26 19:37:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    LexicalPath lexical_path(path);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    auto namespace_ = lexical_path.parts().at(lexical_path.parts().size() - 2);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    auto data = file_or_error.value()->read_all();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    auto interface = IDL::parse_interface(data);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if (!interface) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        fprintf(stderr, "Cannot parse %s\n", path);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return 1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-10-02 20:57:28 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    if (namespace_.is_one_of("DOM", "HTML", "UIEvents", "HighResolutionTime", "SVG")) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-26 19:37:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        StringBuilder builder;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        builder.append(namespace_);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        builder.append("::");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        builder.append(interface->name);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        interface->fully_qualified_name = builder.to_string();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    } else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        interface->fully_qualified_name = interface->name;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#if 0
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    dbg() << "Attributes:";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    for (auto& attribute : interface->attributes) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        dbg() << "  " << (attribute.readonly ? "Readonly " : "")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								              << attribute.type.name << (attribute.type.nullable ? "?" : "")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								              << " " << attribute.name;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    dbg() << "Functions:";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    for (auto& function : interface->functions) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        dbg() << "  " << function.return_type.name << (function.return_type.nullable ? "?" : "")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								              << " " << function.name;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        for (auto& parameter : function.parameters) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            dbg() << "    " << parameter.type.name << (parameter.type.nullable ? "?" : "") << " " << parameter.name;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#endif
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if (header_mode)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        generate_header(*interface);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if (implementation_mode)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        generate_implementation(*interface);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 15:57:10 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static bool should_emit_wrapper_factory(const IDL::Interface& interface)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // FIXME: This is very hackish.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if (interface.name == "EventTarget")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return false;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if (interface.name == "Node")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return false;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if (interface.name == "Text")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return false;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if (interface.name == "Document")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return false;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if (interface.name == "DocumentType")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return false;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if (interface.name.ends_with("Element"))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return false;
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 16:10:48 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    if (interface.name.ends_with("Event"))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return false;
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 15:57:10 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    return true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-22 18:39:22 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static bool is_wrappable_type(const IDL::Type& type)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if (type.name == "Node")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if (type.name == "Document")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if (type.name == "Text")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if (type.name == "DocumentType")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if (type.name.ends_with("Element"))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if (type.name == "ImageData")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return false;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static void generate_header(const IDL::Interface& interface)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    auto& wrapper_class = interface.wrapper_class;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    auto& wrapper_base_class = interface.wrapper_base_class;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "#pragma once";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibWeb/Bindings/Wrapper.h>";
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-26 15:08:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // FIXME: This is very strange.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "#if __has_include(<LibWeb/DOM/" << interface.name << ".h>)";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibWeb/DOM/" << interface.name << ".h>";
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-28 17:21:23 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "#elif __has_include(<LibWeb/HTML/" << interface.name << ".h>)";
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-26 15:08:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibWeb/HTML/" << interface.name << ".h>";
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-28 17:21:23 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "#elif __has_include(<LibWeb/UIEvents/" << interface.name << ".h>)";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibWeb/UIEvents/" << interface.name << ".h>";
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 18:19:18 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "#elif __has_include(<LibWeb/HighResolutionTime/" << interface.name << ".h>)";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibWeb/HighResolutionTime/" << interface.name << ".h>";
							 | 
						
					
						
							
								
									
										
										
										
											2020-10-02 20:57:28 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "#elif __has_include(<LibWeb/SVG/" << interface.name << ".h>)";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibWeb/SVG/" << interface.name << ".h>";
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-26 15:08:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "#endif";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 12:27:41 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    if (wrapper_base_class != "Wrapper")
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "#include <LibWeb/Bindings/" << wrapper_base_class << ".h>";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-26 19:37:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "namespace Web::Bindings {";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "class " << wrapper_class << " : public " << wrapper_base_class << " {";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 15:14:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "    JS_OBJECT(" << wrapper_class << ", " << wrapper_base_class << ");";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "public:";
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-26 19:37:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "    " << wrapper_class << "(JS::GlobalObject&, " << interface.fully_qualified_name << "&);";
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-22 17:50:18 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "    virtual void initialize(JS::GlobalObject&) override;";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "    virtual ~" << wrapper_class << "() override;";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 12:27:41 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    if (wrapper_base_class == "Wrapper") {
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-26 19:37:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        out() << "    " << interface.fully_qualified_name << "& impl() { return *m_impl; }";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "    const " << interface.fully_qualified_name << "& impl() const { return *m_impl; }";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    } else {
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-26 19:37:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        out() << "    " << interface.fully_qualified_name << "& impl() { return static_cast<" << interface.fully_qualified_name << "&>(" << wrapper_base_class << "::impl()); }";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "    const " << interface.fully_qualified_name << "& impl() const { return static_cast<const " << interface.fully_qualified_name << "&>(" << wrapper_base_class << "::impl()); }";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:19:29 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    auto is_foo_wrapper_name = snake_name(String::format("Is%s", wrapper_class.characters()));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "    virtual bool " << is_foo_wrapper_name << "() const final { return true; }";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "private:";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    for (auto& function : interface.functions) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "    JS_DECLARE_NATIVE_FUNCTION(" << snake_name(function.name) << ");";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    for (auto& attribute : interface.attributes) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "    JS_DECLARE_NATIVE_GETTER(" << snake_name(attribute.name) << "_getter);";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if (!attribute.readonly)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "    JS_DECLARE_NATIVE_SETTER(" << snake_name(attribute.name) << "_setter);";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 12:27:41 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    if (wrapper_base_class == "Wrapper") {
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-26 19:37:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        out() << "    NonnullRefPtr<" << interface.fully_qualified_name << "> m_impl;";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 12:27:41 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "};";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 15:57:10 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if (should_emit_wrapper_factory(interface)) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-26 19:37:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        out() << wrapper_class << "* wrap(JS::GlobalObject&, " << interface.fully_qualified_name << "&);";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 15:57:10 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "}";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void generate_implementation(const IDL::Interface& interface)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    auto& wrapper_class = interface.wrapper_class;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    auto& wrapper_base_class = interface.wrapper_base_class;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <AK/FlyString.h>";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibJS/Runtime/Array.h>";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibJS/Runtime/Value.h>";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibJS/Runtime/GlobalObject.h>";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibJS/Runtime/Error.h>";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 12:27:41 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibJS/Runtime/Function.h>";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 15:57:10 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibJS/Runtime/Uint8ClampedArray.h>";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibWeb/Bindings/NodeWrapperFactory.h>";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibWeb/Bindings/" << wrapper_class << ".h>";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibWeb/DOM/Element.h>";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 12:27:41 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibWeb/DOM/EventListener.h>";
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-22 18:26:33 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibWeb/HTML/HTMLElement.h>";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibWeb/Origin.h>";
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-17 19:14:30 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibWeb/Bindings/CommentWrapper.h>";
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-27 05:04:26 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibWeb/Bindings/DocumentWrapper.h>";
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-17 19:14:30 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibWeb/Bindings/DocumentFragmentWrapper.h>";
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-18 21:17:17 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibWeb/Bindings/DocumentTypeWrapper.h>";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-22 18:39:22 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibWeb/Bindings/HTMLCanvasElementWrapper.h>";
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-17 19:14:30 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibWeb/Bindings/HTMLHeadElementWrapper.h>";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-22 18:39:22 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibWeb/Bindings/HTMLImageElementWrapper.h>";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibWeb/Bindings/ImageDataWrapper.h>";
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-17 19:14:30 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibWeb/Bindings/TextWrapper.h>";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 15:37:13 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibWeb/Bindings/CanvasRenderingContext2DWrapper.h>";
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-22 18:26:33 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "#include <LibWeb/Bindings/WindowObject.h>";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-26 19:37:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    // FIXME: This is a total hack until we can figure out the namespace for a given type somehow.
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-28 18:20:36 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "using namespace Web::DOM;";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "using namespace Web::HTML;";
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-26 19:37:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "namespace Web::Bindings {";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // Implementation: Wrapper constructor
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-26 19:37:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << wrapper_class << "::" << wrapper_class << "(JS::GlobalObject& global_object, " << interface.fully_qualified_name << "& impl)";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 12:27:41 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    if (wrapper_base_class == "Wrapper") {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "    : Wrapper(*global_object.object_prototype())";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "    , m_impl(impl)";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    } else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "    : " << wrapper_base_class << "(global_object, impl)";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "{";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "}";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // Implementation: Wrapper initialize()
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-22 17:50:18 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "void " << wrapper_class << "::initialize(JS::GlobalObject& global_object)";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "{";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "    [[maybe_unused]] u8 default_attributes = JS::Attribute::Enumerable | JS::Attribute::Configurable;";
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-22 17:50:18 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    out() << "    " << wrapper_base_class << "::initialize(global_object);";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    for (auto& attribute : interface.attributes) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "    define_native_property(\"" << attribute.name << "\", " << attribute.getter_callback_name << ", " << (attribute.readonly ? "nullptr" : attribute.setter_callback_name) << ", default_attributes);";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    for (auto& function : interface.functions) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "    define_native_function(\"" << function.name << "\", " << snake_name(function.name) << ", " << function.length() << ", default_attributes);";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "}";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // Implementation: Wrapper destructor
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << wrapper_class << "::~" << wrapper_class << "()";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "{";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "}";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // Implementation: impl_from()
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 15:26:09 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    if (!interface.attributes.is_empty() || !interface.functions.is_empty()) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-27 18:36:49 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        out() << "static " << interface.fully_qualified_name << "* impl_from(JS::VM& vm, JS::GlobalObject& global_object)";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 15:26:09 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        out() << "{";
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-27 18:36:49 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        out() << "    auto* this_object = vm.this_value(global_object).to_object(global_object);";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 15:26:09 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        out() << "    if (!this_object)";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "        return {};";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "    if (!this_object->inherits(\"" << wrapper_class << "\")) {";
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-27 18:36:49 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        out() << "        vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotA, \"" << interface.fully_qualified_name << "\");";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 15:26:09 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        out() << "        return nullptr;";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "    }";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "    return &static_cast<" << wrapper_class << "*>(this_object)->impl();";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "}";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 11:39:32 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    auto generate_to_cpp = [&](auto& parameter, auto& js_name, auto& js_suffix, auto cpp_name, bool return_void = false) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        auto generate_return = [&] {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if (return_void)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                out() << "        return;";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                out() << "        return {};";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if (parameter.type.name == "DOMString") {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-27 18:36:49 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            out() << "    auto " << cpp_name << " = " << js_name << js_suffix << ".to_string(global_object);";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "    if (vm.exception())";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 11:39:32 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            generate_return();
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 12:27:41 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        } else if (parameter.type.name == "EventListener") {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "    if (!" << js_name << js_suffix << ".is_function()) {";
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-27 18:36:49 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            out() << "        vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotA, \"Function\");";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 12:27:41 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            generate_return();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "    }";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "    auto " << cpp_name << " = adopt(*new EventListener(JS::make_handle(&" << js_name << js_suffix << ".as_function())));";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-22 18:39:22 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        } else if (is_wrappable_type(parameter.type)) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-27 18:36:49 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            out() << "    auto " << cpp_name << "_object = " << js_name << js_suffix << ".to_object(global_object);";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "    if (vm.exception())";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 11:39:32 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            generate_return();
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 15:14:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            out() << "    if (!" << cpp_name << "_object->inherits(\"" << parameter.type.name << "Wrapper\")) {";
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-27 18:36:49 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            out() << "        vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotA, \"" << parameter.type.name << "\");";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 11:39:32 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            generate_return();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "    }";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "    auto& " << cpp_name << " = static_cast<" << parameter.type.name << "Wrapper*>(" << cpp_name << "_object)->impl();";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-22 18:39:22 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        } else if (parameter.type.name == "double") {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-27 18:36:49 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            out() << "    auto " << cpp_name << " = " << js_name << js_suffix << ".to_double(global_object);";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "    if (vm.exception())";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-22 18:39:22 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            generate_return();
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-11 17:51:10 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        } else if (parameter.type.name == "boolean") {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "    auto " << cpp_name << " = " << js_name << js_suffix << ".to_boolean();";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-22 18:39:22 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        } else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            dbg() << "Unimplemented JS-to-C++ conversion: " << parameter.type.name;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            ASSERT_NOT_REACHED();
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 11:39:32 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    auto generate_arguments = [&](auto& parameters, auto& arguments_builder, bool return_void = false) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        Vector<String> parameter_names;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        size_t argument_index = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        for (auto& parameter : parameters) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            parameter_names.append(snake_name(parameter.name));
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-27 18:36:49 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            out() << "    auto arg" << argument_index << " = vm.argument(" << argument_index << ");";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 11:39:32 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            generate_to_cpp(parameter, "arg", argument_index, snake_name(parameter.name), return_void);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            ++argument_index;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        arguments_builder.join(", ", parameter_names);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    auto generate_return_statement = [&](auto& return_type) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 11:39:32 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if (return_type.name == "void") {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "    return JS::js_undefined();";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if (return_type.nullable) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 11:39:32 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            if (return_type.name == "DOMString") {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                out() << "    if (retval.is_null())";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            } else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                out() << "    if (!retval)";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "        return JS::js_null();";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if (return_type.name == "DOMString") {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-27 18:36:49 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            out() << "    return JS::js_string(vm, retval);";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        } else if (return_type.name == "ArrayFromVector") {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            // FIXME: Remove this fake type hack once it's no longer needed.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            //        Basically once we have NodeList we can throw this out.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "    auto* new_array = JS::Array::create(global_object);";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "    for (auto& element : retval) {";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-23 16:57:39 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            out() << "        new_array->indexed_properties().append(wrap(global_object, element));";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "    }";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "    return new_array;";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 16:10:48 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        } else if (return_type.name == "long" || return_type.name == "double") {
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 15:37:13 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            out() << "    return JS::Value(retval);";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 15:57:10 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        } else if (return_type.name == "Uint8ClampedArray") {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "    return retval;";
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-18 09:49:51 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        } else if (return_type.name == "boolean") {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-11 17:51:10 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            out() << "    return JS::Value(retval);";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        } else {
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-23 16:57:39 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            out() << "    return wrap(global_object, const_cast<" << return_type.name << "&>(*retval));";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // Implementation: Attributes
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    for (auto& attribute : interface.attributes) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 11:39:32 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        out() << "JS_DEFINE_NATIVE_GETTER(" << wrapper_class << "::" << attribute.getter_callback_name << ")";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "{";
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-27 18:36:49 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        out() << "    auto* impl = impl_from(vm, global_object);";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "    if (!impl)";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "        return {};";
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 12:59:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-22 18:26:33 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if (attribute.extended_attributes.contains("ReturnNullIfCrossOrigin")) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "    if (!impl->may_access_from_origin(static_cast<WindowObject&>(global_object).origin()))";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "        return JS::js_null();";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 12:59:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if (attribute.extended_attributes.contains("Reflect")) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 13:23:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            auto attribute_name = attribute.extended_attributes.get("Reflect").value();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if (attribute_name.is_null())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                attribute_name = attribute.name;
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-09 17:10:41 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            attribute_name = make_input_acceptable_cpp(attribute_name);
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 13:23:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            out() << "    auto retval = impl->attribute(HTML::AttributeNames::" << attribute_name << ");";
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 12:59:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        } else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "    auto retval = impl->" << snake_name(attribute.name) << "();";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        generate_return_statement(attribute.type);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "}";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 11:39:32 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if (!attribute.readonly) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "JS_DEFINE_NATIVE_SETTER(" << wrapper_class << "::" << attribute.setter_callback_name << ")";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "{";
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-27 18:36:49 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            out() << "    auto* impl = impl_from(vm, global_object);";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 11:39:32 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            out() << "    if (!impl)";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "        return;";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            generate_to_cpp(attribute, "value", "", "cpp_value", true);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 12:59:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            if (attribute.extended_attributes.contains("Reflect")) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 13:23:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                auto attribute_name = attribute.extended_attributes.get("Reflect").value();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if (attribute_name.is_null())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    attribute_name = attribute.name;
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-09 17:10:41 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                attribute_name = make_input_acceptable_cpp(attribute_name);
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 13:23:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                out() << "    impl->set_attribute(HTML::AttributeNames::" << attribute_name << ", cpp_value);";
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-24 12:59:47 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            } else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                out() << "    impl->set_" << snake_name(attribute.name) << "(cpp_value);";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            }
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 11:39:32 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            out() << "}";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // Implementation: Functions
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    for (auto& function : interface.functions) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "JS_DEFINE_NATIVE_FUNCTION(" << wrapper_class << "::" << snake_name(function.name) << ")";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "{";
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-27 18:36:49 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        out() << "    auto* impl = impl_from(vm, global_object);";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "    if (!impl)";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "        return {};";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-22 18:39:22 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if (function.length() > 0) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-27 18:36:49 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            out() << "    if (vm.argument_count() < " << function.length() << ") {";
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-17 19:14:30 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            if (function.length() == 1)
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-27 18:36:49 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                out() << "        vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountOne, \"" << function.name << "\");";
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-17 19:14:30 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            else
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-27 18:36:49 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                out() << "        vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountMany, \"" << function.name << "\", \"" << function.length() << "\");";
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-25 12:52:32 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            out() << "        return {};";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "    }";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-22 18:39:22 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        StringBuilder arguments_builder;
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 11:39:32 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        generate_arguments(function.parameters, arguments_builder);
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if (function.return_type.name != "void") {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "    auto retval = impl->" << snake_name(function.name) << "(" << arguments_builder.to_string() << ");";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        } else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            out() << "    impl->" << snake_name(function.name) << "(" << arguments_builder.to_string() << ");";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        generate_return_statement(function.return_type);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        out() << "}";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 15:57:10 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    // Implementation: Wrapper factory
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if (should_emit_wrapper_factory(interface)) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-07-26 19:37:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        out() << wrapper_class << "* wrap(JS::GlobalObject& global_object, " << interface.fully_qualified_name << "& impl)";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 15:57:10 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        out() << "{";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-23 16:57:39 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        out() << "    return static_cast<" << wrapper_class << "*>(wrap_impl(global_object, impl));";
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-21 15:57:10 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        out() << "}";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-20 22:09:38 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    out() << "}";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 |