IDLParser.cpp 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191
  1. /*
  2. * Copyright (c) 2020-2023, 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 "IDLParser.h"
  10. #include <AK/Assertions.h>
  11. #include <AK/LexicalPath.h>
  12. #include <AK/QuickSort.h>
  13. #include <LibCore/File.h>
  14. #include <LibFileSystem/FileSystem.h>
  15. [[noreturn]] static void report_parsing_error(StringView message, StringView filename, StringView input, size_t offset)
  16. {
  17. // FIXME: Spaghetti code ahead.
  18. size_t lineno = 1;
  19. size_t colno = 1;
  20. size_t start_line = 0;
  21. size_t line_length = 0;
  22. for (size_t index = 0; index < input.length(); ++index) {
  23. if (offset == index)
  24. colno = index - start_line + 1;
  25. if (input[index] == '\n') {
  26. if (index >= offset)
  27. break;
  28. start_line = index + 1;
  29. line_length = 0;
  30. ++lineno;
  31. } else {
  32. ++line_length;
  33. }
  34. }
  35. StringBuilder error_message;
  36. error_message.appendff("{}\n", input.substring_view(start_line, line_length));
  37. for (size_t i = 0; i < colno - 1; ++i)
  38. error_message.append(' ');
  39. error_message.append("\033[1;31m^\n"sv);
  40. error_message.appendff("{}:{}: error: {}\033[0m\n", filename, lineno, message);
  41. warnln("{}", error_message.string_view());
  42. exit(EXIT_FAILURE);
  43. }
  44. static ByteString convert_enumeration_value_to_cpp_enum_member(ByteString const& value, HashTable<ByteString>& names_already_seen)
  45. {
  46. StringBuilder builder;
  47. GenericLexer lexer { value };
  48. while (!lexer.is_eof()) {
  49. lexer.ignore_while([](auto c) { return is_ascii_space(c) || c == '-' || c == '_'; });
  50. auto word = lexer.consume_while([](auto c) { return is_ascii_alphanumeric(c); });
  51. if (!word.is_empty()) {
  52. builder.append(word.to_titlecase_string());
  53. } else {
  54. auto non_alnum_string = lexer.consume_while([](auto c) { return !is_ascii_alphanumeric(c); });
  55. if (!non_alnum_string.is_empty())
  56. builder.append('_');
  57. }
  58. }
  59. if (builder.is_empty())
  60. builder.append("Empty"sv);
  61. while (names_already_seen.contains(builder.string_view()))
  62. builder.append('_');
  63. names_already_seen.set(builder.string_view());
  64. return builder.to_byte_string();
  65. }
  66. namespace IDL {
  67. void Parser::assert_specific(char ch)
  68. {
  69. if (!lexer.consume_specific(ch))
  70. report_parsing_error(ByteString::formatted("expected '{}'", ch), filename, input, lexer.tell());
  71. }
  72. void Parser::consume_whitespace()
  73. {
  74. bool consumed = true;
  75. while (consumed) {
  76. consumed = lexer.consume_while(is_ascii_space).length() > 0;
  77. if (lexer.consume_specific("//"sv)) {
  78. lexer.consume_until('\n');
  79. lexer.ignore();
  80. consumed = true;
  81. }
  82. }
  83. }
  84. void Parser::assert_string(StringView expected)
  85. {
  86. if (!lexer.consume_specific(expected))
  87. report_parsing_error(ByteString::formatted("expected '{}'", expected), filename, input, lexer.tell());
  88. }
  89. HashMap<ByteString, ByteString> Parser::parse_extended_attributes()
  90. {
  91. HashMap<ByteString, ByteString> extended_attributes;
  92. for (;;) {
  93. consume_whitespace();
  94. if (lexer.consume_specific(']'))
  95. break;
  96. auto name = lexer.consume_until([](auto ch) { return ch == ']' || ch == '=' || ch == ','; });
  97. if (lexer.consume_specific('=')) {
  98. bool did_open_paren = false;
  99. auto value = lexer.consume_until(
  100. [&did_open_paren](auto ch) {
  101. if (ch == '(') {
  102. did_open_paren = true;
  103. return false;
  104. }
  105. if (did_open_paren)
  106. return ch == ')';
  107. return ch == ']' || ch == ',';
  108. });
  109. extended_attributes.set(name, value);
  110. } else {
  111. extended_attributes.set(name, {});
  112. }
  113. lexer.consume_specific(',');
  114. }
  115. consume_whitespace();
  116. return extended_attributes;
  117. }
  118. static HashTable<ByteString> import_stack;
  119. Optional<Interface&> Parser::resolve_import(auto path)
  120. {
  121. auto include_path = LexicalPath::join(import_base_path, path).string();
  122. if (!FileSystem::exists(include_path))
  123. report_parsing_error(ByteString::formatted("{}: No such file or directory", include_path), filename, input, lexer.tell());
  124. auto real_path_error_or = FileSystem::real_path(include_path);
  125. if (real_path_error_or.is_error())
  126. report_parsing_error(ByteString::formatted("Failed to resolve path {}: {}", include_path, real_path_error_or.error()), filename, input, lexer.tell());
  127. auto real_path = real_path_error_or.release_value();
  128. if (top_level_resolved_imports().contains(real_path))
  129. return *top_level_resolved_imports().find(real_path)->value;
  130. if (import_stack.contains(real_path))
  131. report_parsing_error(ByteString::formatted("Circular import detected: {}", include_path), filename, input, lexer.tell());
  132. import_stack.set(real_path);
  133. auto file_or_error = Core::File::open(real_path, Core::File::OpenMode::Read);
  134. if (file_or_error.is_error())
  135. report_parsing_error(ByteString::formatted("Failed to open {}: {}", real_path, file_or_error.error()), filename, input, lexer.tell());
  136. auto data_or_error = file_or_error.value()->read_until_eof();
  137. if (data_or_error.is_error())
  138. report_parsing_error(ByteString::formatted("Failed to read {}: {}", real_path, data_or_error.error()), filename, input, lexer.tell());
  139. auto& result = Parser(this, real_path, data_or_error.value(), import_base_path).parse();
  140. import_stack.remove(real_path);
  141. top_level_resolved_imports().set(real_path, &result);
  142. return result;
  143. }
  144. NonnullRefPtr<Type const> Parser::parse_type()
  145. {
  146. if (lexer.consume_specific('(')) {
  147. Vector<NonnullRefPtr<Type const>> union_member_types;
  148. union_member_types.append(parse_type());
  149. consume_whitespace();
  150. assert_string("or"sv);
  151. consume_whitespace();
  152. union_member_types.append(parse_type());
  153. consume_whitespace();
  154. while (lexer.consume_specific("or"sv)) {
  155. consume_whitespace();
  156. union_member_types.append(parse_type());
  157. consume_whitespace();
  158. }
  159. assert_specific(')');
  160. bool nullable = lexer.consume_specific('?');
  161. auto type = adopt_ref(*new UnionType("", nullable, move(union_member_types)));
  162. if (nullable) {
  163. if (type->number_of_nullable_member_types() > 0)
  164. report_parsing_error("nullable union type cannot contain another nullable type"sv, filename, input, lexer.tell());
  165. // FIXME: A nullable union type cannot include a dictionary type as one of its flattened member types.
  166. }
  167. return type;
  168. }
  169. bool unsigned_ = lexer.consume_specific("unsigned"sv);
  170. if (unsigned_)
  171. consume_whitespace();
  172. // FIXME: Actually treat "unrestricted" and normal floats/doubles differently.
  173. if (lexer.consume_specific("unrestricted"sv))
  174. consume_whitespace();
  175. auto name = lexer.consume_until([](auto ch) { return !is_ascii_alphanumeric(ch) && ch != '_'; });
  176. if (name.equals_ignoring_ascii_case("long"sv)) {
  177. consume_whitespace();
  178. if (lexer.consume_specific("long"sv))
  179. name = "long long"sv;
  180. }
  181. Vector<NonnullRefPtr<Type const>> parameters;
  182. bool is_parameterized_type = false;
  183. if (lexer.consume_specific('<')) {
  184. is_parameterized_type = true;
  185. parameters.append(parse_type());
  186. while (lexer.consume_specific(',')) {
  187. consume_whitespace();
  188. parameters.append(parse_type());
  189. }
  190. lexer.consume_specific('>');
  191. }
  192. auto nullable = lexer.consume_specific('?');
  193. StringBuilder builder;
  194. if (unsigned_)
  195. builder.append("unsigned "sv);
  196. builder.append(name);
  197. if (nullable) {
  198. // https://webidl.spec.whatwg.org/#dfn-nullable-type
  199. // The inner type must not be:
  200. // - any,
  201. if (name == "any"sv)
  202. report_parsing_error("'any' cannot be nullable"sv, filename, input, lexer.tell());
  203. // - a promise type,
  204. if (name == "Promise"sv)
  205. report_parsing_error("'Promise' cannot be nullable"sv, filename, input, lexer.tell());
  206. // - an observable array type,
  207. if (name == "ObservableArray")
  208. report_parsing_error("'ObservableArray' cannot be nullable"sv, filename, input, lexer.tell());
  209. // - another nullable type, or
  210. // - a union type that itself includes a nullable type or has a dictionary type as one of its flattened
  211. // member types
  212. // Note: This case is handled above
  213. }
  214. if (is_parameterized_type)
  215. return adopt_ref(*new ParameterizedType(builder.to_byte_string(), nullable, move(parameters)));
  216. return adopt_ref(*new Type(builder.to_byte_string(), nullable));
  217. }
  218. void Parser::parse_attribute(HashMap<ByteString, ByteString>& extended_attributes, Interface& interface)
  219. {
  220. bool inherit = lexer.consume_specific("inherit"sv);
  221. if (inherit)
  222. consume_whitespace();
  223. bool readonly = lexer.consume_specific("readonly"sv);
  224. if (readonly)
  225. consume_whitespace();
  226. if (lexer.consume_specific("attribute"sv))
  227. consume_whitespace();
  228. else
  229. report_parsing_error("expected 'attribute'"sv, filename, input, lexer.tell());
  230. auto type = parse_type();
  231. consume_whitespace();
  232. auto name = lexer.consume_until([](auto ch) { return is_ascii_space(ch) || ch == ';'; });
  233. consume_whitespace();
  234. assert_specific(';');
  235. auto name_as_string = name.to_byte_string();
  236. auto getter_callback_name = ByteString::formatted("{}_getter", name_as_string.to_snakecase());
  237. auto setter_callback_name = ByteString::formatted("{}_setter", name_as_string.to_snakecase());
  238. Attribute attribute {
  239. inherit,
  240. readonly,
  241. move(type),
  242. move(name_as_string),
  243. move(extended_attributes),
  244. move(getter_callback_name),
  245. move(setter_callback_name),
  246. };
  247. interface.attributes.append(move(attribute));
  248. }
  249. void Parser::parse_constant(Interface& interface)
  250. {
  251. lexer.consume_specific("const"sv);
  252. consume_whitespace();
  253. auto type = parse_type();
  254. consume_whitespace();
  255. auto name = lexer.consume_until([](auto ch) { return is_ascii_space(ch) || ch == '='; });
  256. consume_whitespace();
  257. lexer.consume_specific('=');
  258. consume_whitespace();
  259. auto value = lexer.consume_while([](auto ch) { return !is_ascii_space(ch) && ch != ';'; });
  260. consume_whitespace();
  261. assert_specific(';');
  262. Constant constant {
  263. move(type),
  264. move(name),
  265. move(value),
  266. };
  267. interface.constants.append(move(constant));
  268. }
  269. Vector<Parameter> Parser::parse_parameters()
  270. {
  271. consume_whitespace();
  272. Vector<Parameter> parameters;
  273. for (;;) {
  274. if (lexer.next_is(')'))
  275. break;
  276. HashMap<ByteString, ByteString> extended_attributes;
  277. if (lexer.consume_specific('['))
  278. extended_attributes = parse_extended_attributes();
  279. bool optional = lexer.consume_specific("optional"sv);
  280. if (optional)
  281. consume_whitespace();
  282. if (lexer.consume_specific('[')) {
  283. // Not explicitly forbidden by the grammar but unlikely to happen in practice - if it does,
  284. // we'll have to teach the parser how to merge two sets of extended attributes.
  285. VERIFY(extended_attributes.is_empty());
  286. extended_attributes = parse_extended_attributes();
  287. }
  288. auto type = parse_type();
  289. bool variadic = lexer.consume_specific("..."sv);
  290. consume_whitespace();
  291. auto name = lexer.consume_until([](auto ch) { return is_ascii_space(ch) || ch == ',' || ch == ')' || ch == '='; });
  292. Parameter parameter = { move(type), move(name), optional, {}, move(extended_attributes), variadic };
  293. consume_whitespace();
  294. if (variadic) {
  295. // Variadic parameters must be last and do not have default values.
  296. parameters.append(move(parameter));
  297. break;
  298. }
  299. if (lexer.next_is(')')) {
  300. parameters.append(move(parameter));
  301. break;
  302. }
  303. if (lexer.next_is('=') && optional) {
  304. assert_specific('=');
  305. consume_whitespace();
  306. auto default_value = lexer.consume_until([](auto ch) { return is_ascii_space(ch) || ch == ',' || ch == ')'; });
  307. parameter.optional_default_value = default_value;
  308. }
  309. parameters.append(move(parameter));
  310. if (lexer.next_is(')'))
  311. break;
  312. assert_specific(',');
  313. consume_whitespace();
  314. }
  315. return parameters;
  316. }
  317. Function Parser::parse_function(HashMap<ByteString, ByteString>& extended_attributes, Interface& interface, IsSpecialOperation is_special_operation)
  318. {
  319. auto position = lexer.current_position();
  320. bool static_ = false;
  321. if (lexer.consume_specific("static"sv)) {
  322. static_ = true;
  323. consume_whitespace();
  324. }
  325. auto return_type = parse_type();
  326. consume_whitespace();
  327. auto name = lexer.consume_until([](auto ch) { return is_ascii_space(ch) || ch == '('; });
  328. consume_whitespace();
  329. assert_specific('(');
  330. auto parameters = parse_parameters();
  331. assert_specific(')');
  332. consume_whitespace();
  333. assert_specific(';');
  334. Function function { move(return_type), name, move(parameters), move(extended_attributes), position, {}, false };
  335. // "Defining a special operation with an identifier is equivalent to separating the special operation out into its own declaration without an identifier."
  336. if (is_special_operation == IsSpecialOperation::No || (is_special_operation == IsSpecialOperation::Yes && !name.is_empty())) {
  337. if (!static_)
  338. interface.functions.append(function);
  339. else
  340. interface.static_functions.append(function);
  341. }
  342. return function;
  343. }
  344. void Parser::parse_constructor(HashMap<ByteString, ByteString>& extended_attributes, Interface& interface)
  345. {
  346. assert_string("constructor"sv);
  347. consume_whitespace();
  348. assert_specific('(');
  349. auto parameters = parse_parameters();
  350. assert_specific(')');
  351. consume_whitespace();
  352. assert_specific(';');
  353. interface.constructors.append(Constructor { interface.name, move(parameters), move(extended_attributes) });
  354. }
  355. void Parser::parse_stringifier(HashMap<ByteString, ByteString>& extended_attributes, Interface& interface)
  356. {
  357. assert_string("stringifier"sv);
  358. consume_whitespace();
  359. interface.has_stringifier = true;
  360. if (lexer.next_is("attribute"sv) || lexer.next_is("inherit"sv) || lexer.next_is("readonly"sv)) {
  361. parse_attribute(extended_attributes, interface);
  362. interface.stringifier_attribute = interface.attributes.last().name;
  363. } else {
  364. assert_specific(';');
  365. }
  366. }
  367. void Parser::parse_iterable(Interface& interface)
  368. {
  369. assert_string("iterable"sv);
  370. assert_specific('<');
  371. auto first_type = parse_type();
  372. if (lexer.next_is(',')) {
  373. if (interface.supports_indexed_properties())
  374. report_parsing_error("Interfaces with a pair iterator must not supported indexed properties."sv, filename, input, lexer.tell());
  375. assert_specific(',');
  376. consume_whitespace();
  377. auto second_type = parse_type();
  378. interface.pair_iterator_types = Tuple { move(first_type), move(second_type) };
  379. } else {
  380. if (!interface.supports_indexed_properties())
  381. report_parsing_error("Interfaces with a value iterator must supported indexed properties."sv, filename, input, lexer.tell());
  382. interface.value_iterator_type = move(first_type);
  383. }
  384. assert_specific('>');
  385. assert_specific(';');
  386. }
  387. void Parser::parse_getter(HashMap<ByteString, ByteString>& extended_attributes, Interface& interface)
  388. {
  389. assert_string("getter"sv);
  390. consume_whitespace();
  391. auto function = parse_function(extended_attributes, interface, IsSpecialOperation::Yes);
  392. if (function.parameters.size() != 1)
  393. report_parsing_error(ByteString::formatted("Named/indexed property getters must have only 1 parameter, got {} parameters.", function.parameters.size()), filename, input, lexer.tell());
  394. auto& identifier = function.parameters.first();
  395. if (identifier.type->is_nullable())
  396. report_parsing_error("identifier's type must not be nullable."sv, filename, input, lexer.tell());
  397. if (identifier.optional)
  398. report_parsing_error("identifier must not be optional."sv, filename, input, lexer.tell());
  399. // FIXME: Disallow variadic functions once they're supported.
  400. if (identifier.type->name() == "DOMString") {
  401. if (interface.named_property_getter.has_value())
  402. report_parsing_error("An interface can only have one named property getter."sv, filename, input, lexer.tell());
  403. interface.named_property_getter = move(function);
  404. } else if (identifier.type->name() == "unsigned long") {
  405. if (interface.indexed_property_getter.has_value())
  406. report_parsing_error("An interface can only have one indexed property getter."sv, filename, input, lexer.tell());
  407. interface.indexed_property_getter = move(function);
  408. } else {
  409. report_parsing_error(ByteString::formatted("Named/indexed property getter's identifier's type must be either 'DOMString' or 'unsigned long', got '{}'.", identifier.type->name()), filename, input, lexer.tell());
  410. }
  411. }
  412. void Parser::parse_setter(HashMap<ByteString, ByteString>& extended_attributes, Interface& interface)
  413. {
  414. assert_string("setter"sv);
  415. consume_whitespace();
  416. auto function = parse_function(extended_attributes, interface, IsSpecialOperation::Yes);
  417. if (function.parameters.size() != 2)
  418. report_parsing_error(ByteString::formatted("Named/indexed property setters must have only 2 parameters, got {} parameter(s).", function.parameters.size()), filename, input, lexer.tell());
  419. auto& identifier = function.parameters.first();
  420. if (identifier.type->is_nullable())
  421. report_parsing_error("identifier's type must not be nullable."sv, filename, input, lexer.tell());
  422. if (identifier.optional)
  423. report_parsing_error("identifier must not be optional."sv, filename, input, lexer.tell());
  424. // FIXME: Disallow variadic functions once they're supported.
  425. if (identifier.type->name() == "DOMString") {
  426. if (interface.named_property_setter.has_value())
  427. report_parsing_error("An interface can only have one named property setter."sv, filename, input, lexer.tell());
  428. if (!interface.named_property_getter.has_value())
  429. report_parsing_error("A named property setter must be accompanied by a named property getter."sv, filename, input, lexer.tell());
  430. interface.named_property_setter = move(function);
  431. } else if (identifier.type->name() == "unsigned long") {
  432. if (interface.indexed_property_setter.has_value())
  433. report_parsing_error("An interface can only have one indexed property setter."sv, filename, input, lexer.tell());
  434. if (!interface.indexed_property_getter.has_value())
  435. report_parsing_error("An indexed property setter must be accompanied by an indexed property getter."sv, filename, input, lexer.tell());
  436. interface.indexed_property_setter = move(function);
  437. } else {
  438. report_parsing_error(ByteString::formatted("Named/indexed property setter's identifier's type must be either 'DOMString' or 'unsigned long', got '{}'.", identifier.type->name()), filename, input, lexer.tell());
  439. }
  440. }
  441. void Parser::parse_deleter(HashMap<ByteString, ByteString>& extended_attributes, Interface& interface)
  442. {
  443. assert_string("deleter"sv);
  444. consume_whitespace();
  445. auto function = parse_function(extended_attributes, interface, IsSpecialOperation::Yes);
  446. if (function.parameters.size() != 1)
  447. report_parsing_error(ByteString::formatted("Named property deleter must have only 1 parameter, got {} parameters.", function.parameters.size()), filename, input, lexer.tell());
  448. auto& identifier = function.parameters.first();
  449. if (identifier.type->is_nullable())
  450. report_parsing_error("identifier's type must not be nullable."sv, filename, input, lexer.tell());
  451. if (identifier.optional)
  452. report_parsing_error("identifier must not be optional."sv, filename, input, lexer.tell());
  453. // FIXME: Disallow variadic functions once they're supported.
  454. if (identifier.type->name() == "DOMString") {
  455. if (interface.named_property_deleter.has_value())
  456. report_parsing_error("An interface can only have one named property deleter."sv, filename, input, lexer.tell());
  457. if (!interface.named_property_getter.has_value())
  458. report_parsing_error("A named property deleter must be accompanied by a named property getter."sv, filename, input, lexer.tell());
  459. interface.named_property_deleter = move(function);
  460. } else {
  461. report_parsing_error(ByteString::formatted("Named property deleter's identifier's type must be 'DOMString', got '{}'.", identifier.type->name()), filename, input, lexer.tell());
  462. }
  463. }
  464. void Parser::parse_interface(Interface& interface)
  465. {
  466. consume_whitespace();
  467. interface.name = lexer.consume_until([](auto ch) { return is_ascii_space(ch); });
  468. consume_whitespace();
  469. if (lexer.consume_specific(':')) {
  470. consume_whitespace();
  471. interface.parent_name = lexer.consume_until([](auto ch) { return is_ascii_space(ch); });
  472. consume_whitespace();
  473. }
  474. assert_specific('{');
  475. for (;;) {
  476. HashMap<ByteString, ByteString> extended_attributes;
  477. consume_whitespace();
  478. if (lexer.consume_specific('}')) {
  479. consume_whitespace();
  480. assert_specific(';');
  481. break;
  482. }
  483. if (lexer.consume_specific('[')) {
  484. extended_attributes = parse_extended_attributes();
  485. if (!interface.has_unscopable_member && extended_attributes.contains("Unscopable"))
  486. interface.has_unscopable_member = true;
  487. }
  488. if (lexer.next_is("constructor")) {
  489. parse_constructor(extended_attributes, interface);
  490. continue;
  491. }
  492. if (lexer.next_is("const")) {
  493. parse_constant(interface);
  494. continue;
  495. }
  496. if (lexer.next_is("stringifier")) {
  497. parse_stringifier(extended_attributes, interface);
  498. continue;
  499. }
  500. if (lexer.next_is("iterable")) {
  501. parse_iterable(interface);
  502. continue;
  503. }
  504. if (lexer.next_is("inherit") || lexer.next_is("readonly") || lexer.next_is("attribute")) {
  505. parse_attribute(extended_attributes, interface);
  506. continue;
  507. }
  508. if (lexer.next_is("getter")) {
  509. parse_getter(extended_attributes, interface);
  510. continue;
  511. }
  512. if (lexer.next_is("setter")) {
  513. parse_setter(extended_attributes, interface);
  514. continue;
  515. }
  516. if (lexer.next_is("deleter")) {
  517. parse_deleter(extended_attributes, interface);
  518. continue;
  519. }
  520. parse_function(extended_attributes, interface);
  521. }
  522. if (auto legacy_namespace = interface.extended_attributes.get("LegacyNamespace"sv); legacy_namespace.has_value())
  523. interface.namespaced_name = ByteString::formatted("{}.{}", *legacy_namespace, interface.name);
  524. else
  525. interface.namespaced_name = interface.name;
  526. interface.constructor_class = ByteString::formatted("{}Constructor", interface.name);
  527. interface.prototype_class = ByteString::formatted("{}Prototype", interface.name);
  528. interface.prototype_base_class = ByteString::formatted("{}Prototype", interface.parent_name.is_empty() ? "Object" : interface.parent_name);
  529. interface.global_mixin_class = ByteString::formatted("{}GlobalMixin", interface.name);
  530. consume_whitespace();
  531. }
  532. void Parser::parse_namespace(Interface& interface)
  533. {
  534. consume_whitespace();
  535. interface.name = lexer.consume_until([](auto ch) { return is_ascii_space(ch); });
  536. interface.is_namespace = true;
  537. consume_whitespace();
  538. assert_specific('{');
  539. for (;;) {
  540. consume_whitespace();
  541. if (lexer.consume_specific('}')) {
  542. consume_whitespace();
  543. assert_specific(';');
  544. break;
  545. }
  546. HashMap<ByteString, ByteString> extended_attributes;
  547. parse_function(extended_attributes, interface);
  548. }
  549. interface.namespace_class = ByteString::formatted("{}Namespace", interface.name);
  550. consume_whitespace();
  551. }
  552. void Parser::parse_enumeration(HashMap<ByteString, ByteString> extended_attributes, Interface& interface)
  553. {
  554. assert_string("enum"sv);
  555. consume_whitespace();
  556. Enumeration enumeration {};
  557. enumeration.extended_attributes = move(extended_attributes);
  558. auto name = lexer.consume_until([](auto ch) { return is_ascii_space(ch); });
  559. consume_whitespace();
  560. assert_specific('{');
  561. bool first = true;
  562. for (; !lexer.is_eof();) {
  563. consume_whitespace();
  564. if (lexer.next_is('}'))
  565. break;
  566. if (!first) {
  567. assert_specific(',');
  568. consume_whitespace();
  569. }
  570. assert_specific('"');
  571. auto string = lexer.consume_until('"');
  572. assert_specific('"');
  573. consume_whitespace();
  574. if (enumeration.values.contains(string))
  575. report_parsing_error(ByteString::formatted("Enumeration {} contains duplicate member '{}'", name, string), filename, input, lexer.tell());
  576. else
  577. enumeration.values.set(string);
  578. if (first)
  579. enumeration.first_member = move(string);
  580. first = false;
  581. }
  582. consume_whitespace();
  583. assert_specific('}');
  584. assert_specific(';');
  585. HashTable<ByteString> names_already_seen;
  586. for (auto& entry : enumeration.values)
  587. enumeration.translated_cpp_names.set(entry, convert_enumeration_value_to_cpp_enum_member(entry, names_already_seen));
  588. interface.enumerations.set(name, move(enumeration));
  589. consume_whitespace();
  590. }
  591. void Parser::parse_typedef(Interface& interface)
  592. {
  593. assert_string("typedef"sv);
  594. consume_whitespace();
  595. HashMap<ByteString, ByteString> extended_attributes;
  596. if (lexer.consume_specific('['))
  597. extended_attributes = parse_extended_attributes();
  598. auto type = parse_type();
  599. consume_whitespace();
  600. auto name = lexer.consume_until(';');
  601. assert_specific(';');
  602. interface.typedefs.set(name, Typedef { move(extended_attributes), move(type) });
  603. consume_whitespace();
  604. }
  605. void Parser::parse_dictionary(Interface& interface)
  606. {
  607. assert_string("dictionary"sv);
  608. consume_whitespace();
  609. Dictionary dictionary {};
  610. auto name = lexer.consume_until([](auto ch) { return is_ascii_space(ch); });
  611. consume_whitespace();
  612. if (lexer.consume_specific(':')) {
  613. consume_whitespace();
  614. dictionary.parent_name = lexer.consume_until([](auto ch) { return is_ascii_space(ch); });
  615. consume_whitespace();
  616. }
  617. assert_specific('{');
  618. for (;;) {
  619. consume_whitespace();
  620. if (lexer.consume_specific('}')) {
  621. consume_whitespace();
  622. assert_specific(';');
  623. break;
  624. }
  625. bool required = false;
  626. HashMap<ByteString, ByteString> extended_attributes;
  627. if (lexer.consume_specific("required"sv)) {
  628. required = true;
  629. consume_whitespace();
  630. }
  631. if (lexer.consume_specific('['))
  632. extended_attributes = parse_extended_attributes();
  633. auto type = parse_type();
  634. consume_whitespace();
  635. auto name = lexer.consume_until([](auto ch) { return is_ascii_space(ch) || ch == ';'; });
  636. consume_whitespace();
  637. Optional<StringView> default_value;
  638. if (lexer.consume_specific('=')) {
  639. VERIFY(!required);
  640. consume_whitespace();
  641. default_value = lexer.consume_until([](auto ch) { return is_ascii_space(ch) || ch == ';'; });
  642. consume_whitespace();
  643. }
  644. assert_specific(';');
  645. DictionaryMember member {
  646. required,
  647. move(type),
  648. name,
  649. move(extended_attributes),
  650. Optional<ByteString>(move(default_value)),
  651. };
  652. dictionary.members.append(move(member));
  653. }
  654. // dictionary members need to be evaluated in lexicographical order
  655. quick_sort(dictionary.members, [&](auto& one, auto& two) {
  656. return one.name < two.name;
  657. });
  658. interface.dictionaries.set(name, move(dictionary));
  659. consume_whitespace();
  660. }
  661. void Parser::parse_interface_mixin(Interface& interface)
  662. {
  663. auto mixin_interface_ptr = make<Interface>();
  664. auto& mixin_interface = *mixin_interface_ptr;
  665. VERIFY(top_level_interfaces().set(move(mixin_interface_ptr)) == AK::HashSetResult::InsertedNewEntry);
  666. mixin_interface.module_own_path = interface.module_own_path;
  667. mixin_interface.is_mixin = true;
  668. assert_string("interface"sv);
  669. consume_whitespace();
  670. assert_string("mixin"sv);
  671. auto offset = lexer.tell();
  672. parse_interface(mixin_interface);
  673. if (!mixin_interface.parent_name.is_empty())
  674. report_parsing_error("Mixin interfaces are not allowed to have inherited parents"sv, filename, input, offset);
  675. auto name = mixin_interface.name;
  676. interface.mixins.set(move(name), &mixin_interface);
  677. }
  678. void Parser::parse_callback_function(HashMap<ByteString, ByteString>& extended_attributes, Interface& interface)
  679. {
  680. assert_string("callback"sv);
  681. consume_whitespace();
  682. auto name = lexer.consume_until([](auto ch) { return is_ascii_space(ch); });
  683. consume_whitespace();
  684. assert_specific('=');
  685. consume_whitespace();
  686. auto return_type = parse_type();
  687. consume_whitespace();
  688. assert_specific('(');
  689. auto parameters = parse_parameters();
  690. assert_specific(')');
  691. consume_whitespace();
  692. assert_specific(';');
  693. interface.callback_functions.set(name, CallbackFunction { move(return_type), move(parameters), extended_attributes.contains("LegacyTreatNonObjectAsNull") });
  694. consume_whitespace();
  695. }
  696. void Parser::parse_non_interface_entities(bool allow_interface, Interface& interface)
  697. {
  698. consume_whitespace();
  699. while (!lexer.is_eof()) {
  700. HashMap<ByteString, ByteString> extended_attributes;
  701. if (lexer.consume_specific('['))
  702. extended_attributes = parse_extended_attributes();
  703. if (lexer.next_is("dictionary")) {
  704. parse_dictionary(interface);
  705. } else if (lexer.next_is("enum")) {
  706. parse_enumeration(extended_attributes, interface);
  707. } else if (lexer.next_is("typedef")) {
  708. parse_typedef(interface);
  709. } else if (lexer.next_is("interface mixin")) {
  710. parse_interface_mixin(interface);
  711. } else if (lexer.next_is("callback")) {
  712. parse_callback_function(extended_attributes, interface);
  713. } else if ((allow_interface && !lexer.next_is("interface") && !lexer.next_is("namespace")) || !allow_interface) {
  714. auto current_offset = lexer.tell();
  715. auto name = lexer.consume_until([](auto ch) { return is_ascii_space(ch); });
  716. consume_whitespace();
  717. if (lexer.consume_specific("includes"sv)) {
  718. consume_whitespace();
  719. auto mixin_name = lexer.consume_until([](auto ch) { return is_ascii_space(ch) || ch == ';'; });
  720. interface.included_mixins.ensure(name).set(mixin_name);
  721. consume_whitespace();
  722. assert_specific(';');
  723. consume_whitespace();
  724. } else {
  725. report_parsing_error("expected 'enum' or 'dictionary'"sv, filename, input, current_offset);
  726. }
  727. } else {
  728. interface.extended_attributes = move(extended_attributes);
  729. break;
  730. }
  731. }
  732. consume_whitespace();
  733. }
  734. static void resolve_union_typedefs(Interface& interface, UnionType& union_);
  735. static void resolve_typedef(Interface& interface, NonnullRefPtr<Type const>& type, HashMap<ByteString, ByteString>* extended_attributes = {})
  736. {
  737. if (is<ParameterizedType>(*type)) {
  738. auto& parameterized_type = const_cast<Type&>(*type).as_parameterized();
  739. auto& parameters = static_cast<Vector<NonnullRefPtr<Type const>>&>(parameterized_type.parameters());
  740. for (auto& parameter : parameters)
  741. resolve_typedef(interface, parameter);
  742. return;
  743. }
  744. // Resolve anonymous union types until we get named types that can be resolved in the next step.
  745. if (is<UnionType>(*type) && type->name().is_empty()) {
  746. resolve_union_typedefs(interface, const_cast<Type&>(*type).as_union());
  747. return;
  748. }
  749. auto it = interface.typedefs.find(type->name());
  750. if (it == interface.typedefs.end())
  751. return;
  752. bool nullable = type->is_nullable();
  753. type = it->value.type;
  754. const_cast<Type&>(*type).set_nullable(nullable);
  755. if (extended_attributes) {
  756. for (auto& attribute : it->value.extended_attributes)
  757. extended_attributes->set(attribute.key, attribute.value);
  758. }
  759. // Recursively resolve typedefs in unions after we resolved the type itself - e.g. for this:
  760. // typedef (A or B) Union1;
  761. // typedef (C or D) Union2;
  762. // typedef (Union1 or Union2) NestedUnion;
  763. // We run:
  764. // - resolve_typedef(NestedUnion) -> NestedUnion gets replaced by UnionType(Union1, Union2)
  765. // - resolve_typedef(Union1) -> Union1 gets replaced by UnionType(A, B)
  766. // - resolve_typedef(Union2) -> Union2 gets replaced by UnionType(C, D)
  767. // So whatever referenced NestedUnion ends up with the following resolved union:
  768. // UnionType(UnionType(A, B), UnionType(C, D))
  769. // Note that flattening unions is handled separately as per the spec.
  770. if (is<UnionType>(*type))
  771. resolve_union_typedefs(interface, const_cast<Type&>(*type).as_union());
  772. }
  773. static void resolve_union_typedefs(Interface& interface, UnionType& union_)
  774. {
  775. auto& member_types = static_cast<Vector<NonnullRefPtr<Type const>>&>(union_.member_types());
  776. for (auto& member_type : member_types)
  777. resolve_typedef(interface, member_type);
  778. }
  779. static void resolve_parameters_typedefs(Interface& interface, Vector<Parameter>& parameters)
  780. {
  781. for (auto& parameter : parameters)
  782. resolve_typedef(interface, parameter.type, &parameter.extended_attributes);
  783. }
  784. template<typename FunctionType>
  785. void resolve_function_typedefs(Interface& interface, FunctionType& function)
  786. {
  787. resolve_typedef(interface, function.return_type);
  788. resolve_parameters_typedefs(interface, function.parameters);
  789. }
  790. Interface& Parser::parse()
  791. {
  792. auto this_module_or_error = FileSystem::real_path(filename);
  793. if (this_module_or_error.is_error()) {
  794. report_parsing_error(ByteString::formatted("Failed to resolve path '{}': {}", filename, this_module_or_error.error()), filename, input, 0);
  795. VERIFY_NOT_REACHED();
  796. }
  797. auto this_module = this_module_or_error.release_value();
  798. auto interface_ptr = make<Interface>();
  799. auto& interface = *interface_ptr;
  800. VERIFY(top_level_interfaces().set(move(interface_ptr)) == AK::HashSetResult::InsertedNewEntry);
  801. interface.module_own_path = this_module;
  802. top_level_resolved_imports().set(this_module, &interface);
  803. Vector<Interface&> imports;
  804. {
  805. HashTable<ByteString> required_imported_paths;
  806. while (lexer.consume_specific("#import"sv)) {
  807. consume_whitespace();
  808. assert_specific('<');
  809. auto path = lexer.consume_until('>');
  810. lexer.ignore();
  811. auto maybe_interface = resolve_import(path);
  812. if (maybe_interface.has_value()) {
  813. for (auto& entry : maybe_interface.value().required_imported_paths)
  814. required_imported_paths.set(entry);
  815. imports.append(maybe_interface.release_value());
  816. }
  817. consume_whitespace();
  818. }
  819. interface.required_imported_paths = move(required_imported_paths);
  820. }
  821. parse_non_interface_entities(true, interface);
  822. if (lexer.consume_specific("interface"sv))
  823. parse_interface(interface);
  824. else if (lexer.consume_specific("namespace"sv))
  825. parse_namespace(interface);
  826. parse_non_interface_entities(false, interface);
  827. for (auto& import : imports) {
  828. // FIXME: Instead of copying every imported entity into the current interface, query imports directly
  829. for (auto& dictionary : import.dictionaries)
  830. interface.dictionaries.set(dictionary.key, dictionary.value);
  831. for (auto& enumeration : import.enumerations) {
  832. auto enumeration_copy = enumeration.value;
  833. enumeration_copy.is_original_definition = false;
  834. interface.enumerations.set(enumeration.key, move(enumeration_copy));
  835. }
  836. for (auto& typedef_ : import.typedefs)
  837. interface.typedefs.set(typedef_.key, typedef_.value);
  838. for (auto& mixin : import.mixins) {
  839. if (auto it = interface.mixins.find(mixin.key); it != interface.mixins.end() && it->value != mixin.value)
  840. report_parsing_error(ByteString::formatted("Mixin '{}' was already defined in {}", mixin.key, mixin.value->module_own_path), filename, input, lexer.tell());
  841. interface.mixins.set(mixin.key, mixin.value);
  842. }
  843. for (auto& callback_function : import.callback_functions)
  844. interface.callback_functions.set(callback_function.key, callback_function.value);
  845. }
  846. // Resolve mixins
  847. if (auto it = interface.included_mixins.find(interface.name); it != interface.included_mixins.end()) {
  848. for (auto& entry : it->value) {
  849. auto mixin_it = interface.mixins.find(entry);
  850. if (mixin_it == interface.mixins.end())
  851. report_parsing_error(ByteString::formatted("Mixin '{}' was never defined", entry), filename, input, lexer.tell());
  852. auto& mixin = mixin_it->value;
  853. interface.attributes.extend(mixin->attributes);
  854. interface.constants.extend(mixin->constants);
  855. interface.functions.extend(mixin->functions);
  856. interface.static_functions.extend(mixin->static_functions);
  857. if (interface.has_stringifier && mixin->has_stringifier)
  858. report_parsing_error(ByteString::formatted("Both interface '{}' and mixin '{}' have defined stringifier attributes", interface.name, mixin->name), filename, input, lexer.tell());
  859. if (mixin->has_stringifier) {
  860. interface.stringifier_attribute = mixin->stringifier_attribute;
  861. interface.has_stringifier = true;
  862. }
  863. if (mixin->has_unscopable_member)
  864. interface.has_unscopable_member = true;
  865. }
  866. }
  867. // Resolve typedefs
  868. for (auto& attribute : interface.attributes)
  869. resolve_typedef(interface, attribute.type, &attribute.extended_attributes);
  870. for (auto& constant : interface.constants)
  871. resolve_typedef(interface, constant.type);
  872. for (auto& constructor : interface.constructors)
  873. resolve_parameters_typedefs(interface, constructor.parameters);
  874. for (auto& function : interface.functions)
  875. resolve_function_typedefs(interface, function);
  876. for (auto& static_function : interface.static_functions)
  877. resolve_function_typedefs(interface, static_function);
  878. if (interface.value_iterator_type.has_value())
  879. resolve_typedef(interface, *interface.value_iterator_type);
  880. if (interface.pair_iterator_types.has_value()) {
  881. resolve_typedef(interface, interface.pair_iterator_types->get<0>());
  882. resolve_typedef(interface, interface.pair_iterator_types->get<1>());
  883. }
  884. if (interface.named_property_getter.has_value())
  885. resolve_function_typedefs(interface, *interface.named_property_getter);
  886. if (interface.named_property_setter.has_value())
  887. resolve_function_typedefs(interface, *interface.named_property_setter);
  888. if (interface.indexed_property_getter.has_value())
  889. resolve_function_typedefs(interface, *interface.indexed_property_getter);
  890. if (interface.indexed_property_setter.has_value())
  891. resolve_function_typedefs(interface, *interface.indexed_property_setter);
  892. if (interface.named_property_deleter.has_value())
  893. resolve_function_typedefs(interface, *interface.named_property_deleter);
  894. if (interface.named_property_getter.has_value())
  895. resolve_function_typedefs(interface, *interface.named_property_getter);
  896. for (auto& dictionary : interface.dictionaries) {
  897. for (auto& dictionary_member : dictionary.value.members)
  898. resolve_typedef(interface, dictionary_member.type, &dictionary_member.extended_attributes);
  899. }
  900. for (auto& callback_function : interface.callback_functions)
  901. resolve_function_typedefs(interface, callback_function.value);
  902. // Create overload sets
  903. for (auto& function : interface.functions) {
  904. auto& overload_set = interface.overload_sets.ensure(function.name);
  905. function.overload_index = overload_set.size();
  906. overload_set.append(function);
  907. }
  908. for (auto& overload_set : interface.overload_sets) {
  909. if (overload_set.value.size() == 1)
  910. continue;
  911. for (auto& overloaded_function : overload_set.value)
  912. overloaded_function.is_overloaded = true;
  913. }
  914. for (auto& function : interface.static_functions) {
  915. auto& overload_set = interface.static_overload_sets.ensure(function.name);
  916. function.overload_index = overload_set.size();
  917. overload_set.append(function);
  918. }
  919. for (auto& overload_set : interface.static_overload_sets) {
  920. if (overload_set.value.size() == 1)
  921. continue;
  922. for (auto& overloaded_function : overload_set.value)
  923. overloaded_function.is_overloaded = true;
  924. }
  925. // FIXME: Add support for overloading constructors
  926. // Check overload sets for repeated instances of the same function
  927. // as these will produce very cryptic errors if left alone.
  928. for (auto& overload_set : interface.overload_sets) {
  929. auto& functions = overload_set.value;
  930. for (size_t i = 0; i < functions.size(); ++i) {
  931. for (size_t j = i + 1; j < functions.size(); ++j) {
  932. if (functions[i].parameters.size() != functions[j].parameters.size())
  933. continue;
  934. auto same = true;
  935. for (size_t k = 0; k < functions[i].parameters.size(); ++k) {
  936. if (functions[i].parameters[k].type->is_distinguishable_from(interface, functions[j].parameters[k].type)) {
  937. same = false;
  938. break;
  939. }
  940. }
  941. if (same) {
  942. report_parsing_error(
  943. ByteString::formatted("Overload set '{}' contains multiple identical declarations", overload_set.key),
  944. filename,
  945. input,
  946. functions[j].source_position.offset);
  947. }
  948. }
  949. }
  950. }
  951. if (interface.will_generate_code())
  952. interface.required_imported_paths.set(this_module);
  953. interface.imported_modules = move(imports);
  954. if (top_level_parser() == this)
  955. VERIFY(import_stack.is_empty());
  956. return interface;
  957. }
  958. Parser::Parser(ByteString filename, StringView contents, ByteString import_base_path)
  959. : import_base_path(move(import_base_path))
  960. , filename(move(filename))
  961. , input(contents)
  962. , lexer(input)
  963. {
  964. }
  965. Parser::Parser(Parser* parent, ByteString filename, StringView contents, ByteString import_base_path)
  966. : import_base_path(move(import_base_path))
  967. , filename(move(filename))
  968. , input(contents)
  969. , lexer(input)
  970. , parent(parent)
  971. {
  972. }
  973. Parser* Parser::top_level_parser()
  974. {
  975. Parser* current = this;
  976. for (Parser* next = this; next; next = next->parent)
  977. current = next;
  978. return current;
  979. }
  980. HashMap<ByteString, Interface*>& Parser::top_level_resolved_imports()
  981. {
  982. return top_level_parser()->resolved_imports;
  983. }
  984. HashTable<NonnullOwnPtr<Interface>>& Parser::top_level_interfaces()
  985. {
  986. return top_level_parser()->interfaces;
  987. }
  988. Vector<ByteString> Parser::imported_files() const
  989. {
  990. return const_cast<Parser*>(this)->top_level_resolved_imports().keys();
  991. }
  992. }