main.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  4. * Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
  5. * Copyright (c) 2022, Ali Mohammad Pur <mpfard@serenityos.org>
  6. *
  7. * SPDX-License-Identifier: BSD-2-Clause
  8. */
  9. #include <AK/Debug.h>
  10. #include <AK/LexicalPath.h>
  11. #include <LibCore/ArgsParser.h>
  12. #include <LibCore/File.h>
  13. #include <LibIDL/IDLParser.h>
  14. #include <LibIDL/Types.h>
  15. extern Vector<StringView> s_header_search_paths;
  16. namespace IDL {
  17. void generate_constructor_header(IDL::Interface const&);
  18. void generate_constructor_implementation(IDL::Interface const&);
  19. void generate_prototype_header(IDL::Interface const&);
  20. void generate_prototype_implementation(IDL::Interface const&);
  21. void generate_iterator_prototype_header(IDL::Interface const&);
  22. void generate_iterator_prototype_implementation(IDL::Interface const&);
  23. }
  24. int main(int argc, char** argv)
  25. {
  26. Core::ArgsParser args_parser;
  27. StringView path;
  28. StringView import_base_path;
  29. bool constructor_header_mode = false;
  30. bool constructor_implementation_mode = false;
  31. bool prototype_header_mode = false;
  32. bool prototype_implementation_mode = false;
  33. bool iterator_prototype_header_mode = false;
  34. bool iterator_prototype_implementation_mode = false;
  35. args_parser.add_option(constructor_header_mode, "Generate the constructor .h file", "constructor-header", 'C');
  36. args_parser.add_option(constructor_implementation_mode, "Generate the constructor .cpp file", "constructor-implementation", 'O');
  37. args_parser.add_option(prototype_header_mode, "Generate the prototype .h file", "prototype-header", 'P');
  38. args_parser.add_option(prototype_implementation_mode, "Generate the prototype .cpp file", "prototype-implementation", 'R');
  39. args_parser.add_option(iterator_prototype_header_mode, "Generate the iterator prototype .h file", "iterator-prototype-header", 0);
  40. args_parser.add_option(iterator_prototype_implementation_mode, "Generate the iterator prototype .cpp file", "iterator-prototype-implementation", 0);
  41. args_parser.add_option(Core::ArgsParser::Option {
  42. .argument_mode = Core::ArgsParser::OptionArgumentMode::Required,
  43. .help_string = "Add a header search path passed to the compiler",
  44. .long_name = "header-include-path",
  45. .short_name = 'i',
  46. .value_name = "path",
  47. .accept_value = [&](char const* s) {
  48. s_header_search_paths.append({ s, strlen(s) });
  49. return true;
  50. },
  51. });
  52. args_parser.add_positional_argument(path, "IDL file", "idl-file");
  53. args_parser.add_positional_argument(import_base_path, "Import base path", "import-base-path", Core::ArgsParser::Required::No);
  54. args_parser.parse(argc, argv);
  55. auto file_or_error = Core::File::open(path, Core::OpenMode::ReadOnly);
  56. if (file_or_error.is_error()) {
  57. warnln("Failed to open {}: {}", path, file_or_error.error());
  58. return 1;
  59. }
  60. LexicalPath lexical_path(path);
  61. auto& namespace_ = lexical_path.parts_view().at(lexical_path.parts_view().size() - 2);
  62. auto data = file_or_error.value()->read_all();
  63. if (import_base_path.is_null())
  64. import_base_path = lexical_path.dirname();
  65. IDL::Parser parser(path, data, import_base_path);
  66. auto& interface = parser.parse();
  67. static constexpr Array libweb_interface_namespaces = {
  68. "CSS"sv,
  69. "Crypto"sv,
  70. "DOM"sv,
  71. "DOMParsing"sv,
  72. "Encoding"sv,
  73. "Fetch"sv,
  74. "FileAPI"sv,
  75. "Geometry"sv,
  76. "HTML"sv,
  77. "HighResolutionTime"sv,
  78. "IntersectionObserver"sv,
  79. "NavigationTiming"sv,
  80. "RequestIdleCallback"sv,
  81. "ResizeObserver"sv,
  82. "SVG"sv,
  83. "Selection"sv,
  84. "UIEvents"sv,
  85. "URL"sv,
  86. "WebGL"sv,
  87. "WebIDL"sv,
  88. "WebSockets"sv,
  89. "XHR"sv,
  90. };
  91. if (libweb_interface_namespaces.span().contains_slow(namespace_)) {
  92. StringBuilder builder;
  93. builder.append(namespace_);
  94. builder.append("::"sv);
  95. builder.append(interface.name);
  96. interface.fully_qualified_name = builder.to_string();
  97. } else {
  98. interface.fully_qualified_name = interface.name;
  99. }
  100. if constexpr (BINDINGS_GENERATOR_DEBUG) {
  101. dbgln("Attributes:");
  102. for (auto& attribute : interface.attributes) {
  103. dbgln(" {}{}{}{} {}",
  104. attribute.inherit ? "inherit " : "",
  105. attribute.readonly ? "readonly " : "",
  106. attribute.type->name(),
  107. attribute.type->is_nullable() ? "?" : "",
  108. attribute.name);
  109. }
  110. dbgln("Functions:");
  111. for (auto& function : interface.functions) {
  112. dbgln(" {}{} {}",
  113. function.return_type->name(),
  114. function.return_type->is_nullable() ? "?" : "",
  115. function.name);
  116. for (auto& parameter : function.parameters) {
  117. dbgln(" {}{} {}",
  118. parameter.type->name(),
  119. parameter.type->is_nullable() ? "?" : "",
  120. parameter.name);
  121. }
  122. }
  123. dbgln("Static Functions:");
  124. for (auto& function : interface.static_functions) {
  125. dbgln(" static {}{} {}",
  126. function.return_type->name(),
  127. function.return_type->is_nullable() ? "?" : "",
  128. function.name);
  129. for (auto& parameter : function.parameters) {
  130. dbgln(" {}{} {}",
  131. parameter.type->name(),
  132. parameter.type->is_nullable() ? "?" : "",
  133. parameter.name);
  134. }
  135. }
  136. }
  137. if (constructor_header_mode)
  138. IDL::generate_constructor_header(interface);
  139. if (constructor_implementation_mode)
  140. IDL::generate_constructor_implementation(interface);
  141. if (prototype_header_mode)
  142. IDL::generate_prototype_header(interface);
  143. if (prototype_implementation_mode)
  144. IDL::generate_prototype_implementation(interface);
  145. if (iterator_prototype_header_mode)
  146. IDL::generate_iterator_prototype_header(interface);
  147. if (iterator_prototype_implementation_mode)
  148. IDL::generate_iterator_prototype_implementation(interface);
  149. return 0;
  150. }