Types.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. /*
  2. * Copyright (c) 2020-2023, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2021, 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. * Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
  7. *
  8. * SPDX-License-Identifier: BSD-2-Clause
  9. */
  10. #pragma once
  11. #include <AK/ByteString.h>
  12. #include <AK/HashMap.h>
  13. #include <AK/NonnullRefPtr.h>
  14. #include <AK/SourceGenerator.h>
  15. #include <AK/StringBuilder.h>
  16. #include <AK/Tuple.h>
  17. #include <AK/TypeCasts.h>
  18. namespace IDL {
  19. template<typename FunctionType>
  20. static size_t get_function_shortest_length(FunctionType& function)
  21. {
  22. size_t length = 0;
  23. for (auto& parameter : function.parameters) {
  24. if (!parameter.optional && !parameter.variadic)
  25. length++;
  26. }
  27. return length;
  28. }
  29. enum class SequenceStorageType {
  30. Vector, // Used to safely store non-JS values
  31. MarkedVector, // Used to safely store JS::Value and anything that inherits JS::Cell, e.g. JS::Object
  32. };
  33. struct CppType {
  34. ByteString name;
  35. SequenceStorageType sequence_storage_type;
  36. };
  37. class ParameterizedType;
  38. class UnionType;
  39. class Interface;
  40. class Type : public RefCounted<Type> {
  41. public:
  42. enum class Kind {
  43. Plain, // AKA, Type.
  44. Parameterized,
  45. Union,
  46. };
  47. Type(ByteString name, bool nullable)
  48. : m_kind(Kind::Plain)
  49. , m_name(move(name))
  50. , m_nullable(nullable)
  51. {
  52. }
  53. Type(Kind kind, ByteString name, bool nullable)
  54. : m_kind(kind)
  55. , m_name(move(name))
  56. , m_nullable(nullable)
  57. {
  58. }
  59. virtual ~Type() = default;
  60. Kind kind() const { return m_kind; }
  61. bool is_plain() const { return m_kind == Kind::Plain; }
  62. bool is_parameterized() const { return m_kind == Kind::Parameterized; }
  63. ParameterizedType const& as_parameterized() const;
  64. ParameterizedType& as_parameterized();
  65. bool is_union() const { return m_kind == Kind::Union; }
  66. UnionType const& as_union() const;
  67. UnionType& as_union();
  68. ByteString const& name() const { return m_name; }
  69. bool is_nullable() const { return m_nullable; }
  70. void set_nullable(bool value) { m_nullable = value; }
  71. // https://webidl.spec.whatwg.org/#dfn-includes-a-nullable-type
  72. bool includes_nullable_type() const;
  73. // -> https://webidl.spec.whatwg.org/#dfn-includes-undefined
  74. bool includes_undefined() const;
  75. Type const& innermost_type() const
  76. {
  77. // From step 4 of https://webidl.spec.whatwg.org/#dfn-distinguishable
  78. // "Consider the two "innermost" types derived by taking each type’s inner type if it is an annotated type, and then taking its inner type inner type if the result is a nullable type."
  79. // FIXME: Annotated types.
  80. VERIFY(!is_union());
  81. return *this;
  82. }
  83. // https://webidl.spec.whatwg.org/#idl-any
  84. bool is_any() const { return is_plain() && m_name == "any"; }
  85. // https://webidl.spec.whatwg.org/#idl-undefined
  86. bool is_undefined() const { return is_plain() && m_name == "undefined"; }
  87. // https://webidl.spec.whatwg.org/#idl-boolean
  88. bool is_boolean() const { return is_plain() && m_name == "boolean"; }
  89. // https://webidl.spec.whatwg.org/#idl-bigint
  90. bool is_bigint() const { return is_plain() && m_name == "bigint"; }
  91. // https://webidl.spec.whatwg.org/#idl-object
  92. bool is_object() const { return is_plain() && m_name == "object"; }
  93. // https://webidl.spec.whatwg.org/#idl-symbol
  94. bool is_symbol() const { return is_plain() && m_name == "symbol"; }
  95. bool is_string() const { return is_plain() && m_name.is_one_of("ByteString", "CSSOMString", "DOMString", "USVString"); }
  96. // https://webidl.spec.whatwg.org/#dfn-integer-type
  97. bool is_integer() const { return is_plain() && m_name.is_one_of("byte", "octet", "short", "unsigned short", "long", "unsigned long", "long long", "unsigned long long"); }
  98. // https://webidl.spec.whatwg.org/#dfn-numeric-type
  99. bool is_numeric() const { return is_plain() && (is_integer() || m_name.is_one_of("float", "unrestricted float", "double", "unrestricted double")); }
  100. // https://webidl.spec.whatwg.org/#dfn-primitive-type
  101. bool is_primitive() const { return is_plain() && (is_numeric() || is_boolean() || m_name == "bigint"); }
  102. // https://webidl.spec.whatwg.org/#idl-sequence
  103. bool is_sequence() const { return is_parameterized() && m_name == "sequence"; }
  104. // https://webidl.spec.whatwg.org/#dfn-distinguishable
  105. bool is_distinguishable_from(Interface const&, Type const& other) const;
  106. bool is_json(Interface const&) const;
  107. private:
  108. Kind m_kind;
  109. ByteString m_name;
  110. bool m_nullable { false };
  111. };
  112. struct Parameter {
  113. NonnullRefPtr<Type const> type;
  114. ByteString name;
  115. bool optional { false };
  116. Optional<ByteString> optional_default_value;
  117. HashMap<ByteString, ByteString> extended_attributes;
  118. bool variadic { false };
  119. };
  120. struct Function {
  121. NonnullRefPtr<Type const> return_type;
  122. ByteString name;
  123. Vector<Parameter> parameters;
  124. HashMap<ByteString, ByteString> extended_attributes;
  125. LineTrackingLexer::Position source_position;
  126. size_t overload_index { 0 };
  127. bool is_overloaded { false };
  128. size_t shortest_length() const { return get_function_shortest_length(*this); }
  129. };
  130. struct Constructor {
  131. ByteString name;
  132. Vector<Parameter> parameters;
  133. HashMap<ByteString, ByteString> extended_attributes;
  134. size_t shortest_length() const { return get_function_shortest_length(*this); }
  135. };
  136. struct Constant {
  137. NonnullRefPtr<Type const> type;
  138. ByteString name;
  139. ByteString value;
  140. };
  141. struct Attribute {
  142. bool inherit { false };
  143. bool readonly { false };
  144. NonnullRefPtr<Type const> type;
  145. ByteString name;
  146. HashMap<ByteString, ByteString> extended_attributes;
  147. // Added for convenience after parsing
  148. ByteString getter_callback_name;
  149. ByteString setter_callback_name;
  150. };
  151. struct DictionaryMember {
  152. bool required { false };
  153. NonnullRefPtr<Type const> type;
  154. ByteString name;
  155. HashMap<ByteString, ByteString> extended_attributes;
  156. Optional<ByteString> default_value;
  157. };
  158. struct Dictionary {
  159. ByteString parent_name;
  160. Vector<DictionaryMember> members;
  161. };
  162. struct Typedef {
  163. HashMap<ByteString, ByteString> extended_attributes;
  164. NonnullRefPtr<Type const> type;
  165. };
  166. struct Enumeration {
  167. OrderedHashTable<ByteString> values;
  168. OrderedHashMap<ByteString, ByteString> translated_cpp_names;
  169. HashMap<ByteString, ByteString> extended_attributes;
  170. ByteString first_member;
  171. bool is_original_definition { true };
  172. };
  173. struct CallbackFunction {
  174. NonnullRefPtr<Type const> return_type;
  175. Vector<Parameter> parameters;
  176. bool is_legacy_treat_non_object_as_null { false };
  177. };
  178. class ParameterizedType : public Type {
  179. public:
  180. ParameterizedType(ByteString name, bool nullable, Vector<NonnullRefPtr<Type const>> parameters)
  181. : Type(Kind::Parameterized, move(name), nullable)
  182. , m_parameters(move(parameters))
  183. {
  184. }
  185. virtual ~ParameterizedType() override = default;
  186. void generate_sequence_from_iterable(SourceGenerator& generator, ByteString const& cpp_name, ByteString const& iterable_cpp_name, ByteString const& iterator_method_cpp_name, IDL::Interface const&, size_t recursion_depth) const;
  187. Vector<NonnullRefPtr<Type const>> const& parameters() const { return m_parameters; }
  188. Vector<NonnullRefPtr<Type const>>& parameters() { return m_parameters; }
  189. private:
  190. Vector<NonnullRefPtr<Type const>> m_parameters;
  191. };
  192. static inline size_t get_shortest_function_length(Vector<Function&> const& overload_set)
  193. {
  194. size_t shortest_length = SIZE_MAX;
  195. for (auto const& function : overload_set)
  196. shortest_length = min(function.shortest_length(), shortest_length);
  197. return shortest_length;
  198. }
  199. class Interface {
  200. AK_MAKE_NONCOPYABLE(Interface);
  201. AK_MAKE_NONMOVABLE(Interface);
  202. public:
  203. explicit Interface() = default;
  204. ByteString name;
  205. ByteString parent_name;
  206. ByteString namespaced_name;
  207. bool is_namespace { false };
  208. bool is_mixin { false };
  209. HashMap<ByteString, ByteString> extended_attributes;
  210. Vector<Attribute> attributes;
  211. Vector<Constant> constants;
  212. Vector<Constructor> constructors;
  213. Vector<Function> functions;
  214. Vector<Function> static_functions;
  215. bool has_stringifier { false };
  216. Optional<ByteString> stringifier_attribute;
  217. bool has_unscopable_member { false };
  218. Optional<NonnullRefPtr<Type const>> value_iterator_type;
  219. Optional<Tuple<NonnullRefPtr<Type const>, NonnullRefPtr<Type const>>> pair_iterator_types;
  220. Optional<Function> named_property_getter;
  221. Optional<Function> named_property_setter;
  222. Optional<Function> indexed_property_getter;
  223. Optional<Function> indexed_property_setter;
  224. Optional<Function> named_property_deleter;
  225. HashMap<ByteString, Dictionary> dictionaries;
  226. HashMap<ByteString, Enumeration> enumerations;
  227. HashMap<ByteString, Typedef> typedefs;
  228. HashMap<ByteString, Interface*> mixins;
  229. HashMap<ByteString, CallbackFunction> callback_functions;
  230. // Added for convenience after parsing
  231. ByteString fully_qualified_name;
  232. ByteString constructor_class;
  233. ByteString prototype_class;
  234. ByteString prototype_base_class;
  235. ByteString namespace_class;
  236. ByteString global_mixin_class;
  237. HashMap<ByteString, HashTable<ByteString>> included_mixins;
  238. ByteString module_own_path;
  239. HashTable<ByteString> required_imported_paths;
  240. Vector<Interface&> imported_modules;
  241. HashMap<ByteString, Vector<Function&>> overload_sets;
  242. HashMap<ByteString, Vector<Function&>> static_overload_sets;
  243. // https://webidl.spec.whatwg.org/#dfn-support-indexed-properties
  244. bool supports_indexed_properties() const { return indexed_property_getter.has_value(); }
  245. // https://webidl.spec.whatwg.org/#dfn-support-named-properties
  246. bool supports_named_properties() const { return named_property_getter.has_value(); }
  247. // https://webidl.spec.whatwg.org/#dfn-legacy-platform-object
  248. bool is_legacy_platform_object() const { return !extended_attributes.contains("Global") && (supports_indexed_properties() || supports_named_properties()); }
  249. bool will_generate_code() const
  250. {
  251. return !name.is_empty() || any_of(enumerations, [](auto& entry) { return entry.value.is_original_definition; });
  252. }
  253. };
  254. class UnionType : public Type {
  255. public:
  256. UnionType(ByteString name, bool nullable, Vector<NonnullRefPtr<Type const>> member_types)
  257. : Type(Kind::Union, move(name), nullable)
  258. , m_member_types(move(member_types))
  259. {
  260. }
  261. virtual ~UnionType() override = default;
  262. Vector<NonnullRefPtr<Type const>> const& member_types() const { return m_member_types; }
  263. Vector<NonnullRefPtr<Type const>>& member_types() { return m_member_types; }
  264. // https://webidl.spec.whatwg.org/#dfn-flattened-union-member-types
  265. Vector<NonnullRefPtr<Type const>> flattened_member_types() const
  266. {
  267. // 1. Let T be the union type.
  268. // 2. Initialize S to ∅.
  269. Vector<NonnullRefPtr<Type const>> types;
  270. // 3. For each member type U of T:
  271. for (auto& type : m_member_types) {
  272. // FIXME: 1. If U is an annotated type, then set U to be the inner type of U.
  273. // 2. If U is a nullable type, then set U to be the inner type of U. (NOTE: Not necessary as nullable is stored with Type and not as a separate struct)
  274. // 3. If U is a union type, then add to S the flattened member types of U.
  275. if (type->is_union()) {
  276. auto& union_member_type = type->as_union();
  277. types.extend(union_member_type.flattened_member_types());
  278. } else {
  279. // 4. Otherwise, U is not a union type. Add U to S.
  280. types.append(type);
  281. }
  282. }
  283. // 4. Return S.
  284. return types;
  285. }
  286. // https://webidl.spec.whatwg.org/#dfn-number-of-nullable-member-types
  287. size_t number_of_nullable_member_types() const
  288. {
  289. // 1. Let T be the union type.
  290. // 2. Initialize n to 0.
  291. size_t num_nullable_member_types = 0;
  292. // 3. For each member type U of T:
  293. for (auto& type : m_member_types) {
  294. // 1. If U is a nullable type, then:
  295. if (type->is_nullable()) {
  296. // 1. Set n to n + 1.
  297. ++num_nullable_member_types;
  298. // 2. Set U to be the inner type of U. (NOTE: Not necessary as nullable is stored with Type and not as a separate struct)
  299. }
  300. // 2. If U is a union type, then:
  301. if (type->is_union()) {
  302. auto& union_member_type = type->as_union();
  303. // 1. Let m be the number of nullable member types of U.
  304. // 2. Set n to n + m.
  305. num_nullable_member_types += union_member_type.number_of_nullable_member_types();
  306. }
  307. }
  308. // 4. Return n.
  309. return num_nullable_member_types;
  310. }
  311. private:
  312. Vector<NonnullRefPtr<Type const>> m_member_types;
  313. };
  314. // https://webidl.spec.whatwg.org/#dfn-optionality-value
  315. enum class Optionality {
  316. Required,
  317. Optional,
  318. Variadic,
  319. };
  320. // https://webidl.spec.whatwg.org/#dfn-effective-overload-set
  321. class EffectiveOverloadSet {
  322. public:
  323. struct Item {
  324. int callable_id;
  325. Vector<NonnullRefPtr<Type const>> types;
  326. Vector<Optionality> optionality_values;
  327. };
  328. EffectiveOverloadSet(Vector<Item> items, size_t distinguishing_argument_index)
  329. : m_items(move(items))
  330. , m_distinguishing_argument_index(distinguishing_argument_index)
  331. {
  332. }
  333. Vector<Item>& items() { return m_items; }
  334. Vector<Item> const& items() const { return m_items; }
  335. Item const& only_item() const
  336. {
  337. VERIFY(m_items.size() == 1);
  338. return m_items[0];
  339. }
  340. bool is_empty() const { return m_items.is_empty(); }
  341. size_t size() const { return m_items.size(); }
  342. size_t distinguishing_argument_index() const { return m_distinguishing_argument_index; }
  343. template<typename Matches>
  344. bool has_overload_with_matching_argument_at_index(size_t index, Matches matches)
  345. {
  346. for (size_t i = 0; i < m_items.size(); ++i) {
  347. auto const& item = m_items[i];
  348. if (matches(item.types[index], item.optionality_values[index])) {
  349. m_last_matching_item_index = i;
  350. return true;
  351. }
  352. }
  353. m_last_matching_item_index = {};
  354. return false;
  355. }
  356. void remove_all_other_entries();
  357. private:
  358. // FIXME: This should be an "ordered set".
  359. Vector<Item> m_items;
  360. size_t m_distinguishing_argument_index { 0 };
  361. Optional<size_t> m_last_matching_item_index;
  362. };
  363. }