Types.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. /*
  2. * Copyright (c) 2020-2021, 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/HashMap.h>
  12. #include <AK/NonnullRefPtr.h>
  13. #include <AK/NonnullRefPtrVector.h>
  14. #include <AK/SourceGenerator.h>
  15. #include <AK/String.h>
  16. #include <AK/StringBuilder.h>
  17. #include <AK/Tuple.h>
  18. #include <AK/TypeCasts.h>
  19. namespace IDL {
  20. template<typename FunctionType>
  21. static size_t get_function_shortest_length(FunctionType& function)
  22. {
  23. size_t length = 0;
  24. for (auto& parameter : function.parameters) {
  25. if (!parameter.optional && !parameter.variadic)
  26. length++;
  27. }
  28. return length;
  29. }
  30. enum class SequenceStorageType {
  31. Vector, // Used to safely store non-JS values
  32. MarkedVector, // Used to safely store JS::Value and anything that inherits JS::Cell, e.g. JS::Object
  33. };
  34. struct CppType {
  35. String name;
  36. SequenceStorageType sequence_storage_type;
  37. };
  38. class ParameterizedType;
  39. class UnionType;
  40. class Type : public RefCounted<Type> {
  41. public:
  42. enum class Kind {
  43. Plain, // AKA, Type.
  44. Parameterized,
  45. Union,
  46. };
  47. Type(String name, bool nullable)
  48. : m_kind(Kind::Plain)
  49. , m_name(move(name))
  50. , m_nullable(nullable)
  51. {
  52. }
  53. Type(Kind kind, String 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. String 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(Type const& other) const;
  106. private:
  107. Kind m_kind;
  108. String m_name;
  109. bool m_nullable { false };
  110. };
  111. struct Parameter {
  112. NonnullRefPtr<Type> type;
  113. String name;
  114. bool optional { false };
  115. Optional<String> optional_default_value;
  116. HashMap<String, String> extended_attributes;
  117. bool variadic { false };
  118. };
  119. struct Function {
  120. NonnullRefPtr<Type> return_type;
  121. String name;
  122. Vector<Parameter> parameters;
  123. HashMap<String, String> extended_attributes;
  124. size_t overload_index { 0 };
  125. bool is_overloaded { false };
  126. size_t shortest_length() const { return get_function_shortest_length(*this); }
  127. };
  128. struct Constructor {
  129. String name;
  130. Vector<Parameter> parameters;
  131. size_t shortest_length() const { return get_function_shortest_length(*this); }
  132. };
  133. struct Constant {
  134. NonnullRefPtr<Type> type;
  135. String name;
  136. String value;
  137. };
  138. struct Attribute {
  139. bool inherit { false };
  140. bool readonly { false };
  141. NonnullRefPtr<Type> type;
  142. String name;
  143. HashMap<String, String> extended_attributes;
  144. // Added for convenience after parsing
  145. String getter_callback_name;
  146. String setter_callback_name;
  147. };
  148. struct DictionaryMember {
  149. bool required { false };
  150. NonnullRefPtr<Type> type;
  151. String name;
  152. HashMap<String, String> extended_attributes;
  153. Optional<String> default_value;
  154. };
  155. struct Dictionary {
  156. String parent_name;
  157. Vector<DictionaryMember> members;
  158. };
  159. struct Typedef {
  160. HashMap<String, String> extended_attributes;
  161. NonnullRefPtr<Type> type;
  162. };
  163. struct Enumeration {
  164. HashTable<String> values;
  165. HashMap<String, String> translated_cpp_names;
  166. String first_member;
  167. bool is_original_definition { true };
  168. };
  169. struct CallbackFunction {
  170. NonnullRefPtr<Type> return_type;
  171. Vector<Parameter> parameters;
  172. bool is_legacy_treat_non_object_as_null { false };
  173. };
  174. class Interface;
  175. class ParameterizedType : public Type {
  176. public:
  177. ParameterizedType(String name, bool nullable, NonnullRefPtrVector<Type> parameters)
  178. : Type(Kind::Parameterized, move(name), nullable)
  179. , m_parameters(move(parameters))
  180. {
  181. }
  182. virtual ~ParameterizedType() override = default;
  183. void generate_sequence_from_iterable(SourceGenerator& generator, String const& cpp_name, String const& iterable_cpp_name, String const& iterator_method_cpp_name, IDL::Interface const&, size_t recursion_depth) const;
  184. NonnullRefPtrVector<Type> const& parameters() const { return m_parameters; }
  185. NonnullRefPtrVector<Type>& parameters() { return m_parameters; }
  186. private:
  187. NonnullRefPtrVector<Type> m_parameters;
  188. };
  189. static inline size_t get_shortest_function_length(Vector<Function&> const& overload_set)
  190. {
  191. size_t shortest_length = SIZE_MAX;
  192. for (auto const& function : overload_set)
  193. shortest_length = min(function.shortest_length(), shortest_length);
  194. return shortest_length;
  195. }
  196. class Interface {
  197. AK_MAKE_NONCOPYABLE(Interface);
  198. AK_MAKE_NONMOVABLE(Interface);
  199. public:
  200. explicit Interface() = default;
  201. String name;
  202. String parent_name;
  203. bool is_mixin { false };
  204. HashMap<String, String> extended_attributes;
  205. Vector<Attribute> attributes;
  206. Vector<Constant> constants;
  207. Vector<Constructor> constructors;
  208. Vector<Function> functions;
  209. Vector<Function> static_functions;
  210. bool has_stringifier { false };
  211. Optional<String> stringifier_attribute;
  212. bool has_unscopable_member { false };
  213. Optional<NonnullRefPtr<Type>> value_iterator_type;
  214. Optional<Tuple<NonnullRefPtr<Type>, NonnullRefPtr<Type>>> pair_iterator_types;
  215. Optional<Function> named_property_getter;
  216. Optional<Function> named_property_setter;
  217. Optional<Function> indexed_property_getter;
  218. Optional<Function> indexed_property_setter;
  219. Optional<Function> named_property_deleter;
  220. HashMap<String, Dictionary> dictionaries;
  221. HashMap<String, Enumeration> enumerations;
  222. HashMap<String, Typedef> typedefs;
  223. HashMap<String, Interface*> mixins;
  224. HashMap<String, CallbackFunction> callback_functions;
  225. // Added for convenience after parsing
  226. String fully_qualified_name;
  227. String constructor_class;
  228. String prototype_class;
  229. String prototype_base_class;
  230. HashMap<String, HashTable<String>> included_mixins;
  231. String module_own_path;
  232. HashTable<String> required_imported_paths;
  233. Vector<Interface&> imported_modules;
  234. HashMap<String, Vector<Function&>> overload_sets;
  235. HashMap<String, Vector<Function&>> static_overload_sets;
  236. // https://webidl.spec.whatwg.org/#dfn-support-indexed-properties
  237. bool supports_indexed_properties() const { return indexed_property_getter.has_value(); }
  238. // https://webidl.spec.whatwg.org/#dfn-support-named-properties
  239. bool supports_named_properties() const { return named_property_getter.has_value(); }
  240. // https://webidl.spec.whatwg.org/#dfn-legacy-platform-object
  241. bool is_legacy_platform_object() const { return !extended_attributes.contains("Global") && (supports_indexed_properties() || supports_named_properties()); }
  242. bool will_generate_code() const
  243. {
  244. return !name.is_empty() || any_of(enumerations, [](auto& entry) { return entry.value.is_original_definition; });
  245. }
  246. };
  247. class UnionType : public Type {
  248. public:
  249. UnionType(String name, bool nullable, NonnullRefPtrVector<Type> member_types)
  250. : Type(Kind::Union, move(name), nullable)
  251. , m_member_types(move(member_types))
  252. {
  253. }
  254. virtual ~UnionType() override = default;
  255. NonnullRefPtrVector<Type> const& member_types() const { return m_member_types; }
  256. NonnullRefPtrVector<Type>& member_types() { return m_member_types; }
  257. // https://webidl.spec.whatwg.org/#dfn-flattened-union-member-types
  258. NonnullRefPtrVector<Type> flattened_member_types() const
  259. {
  260. // 1. Let T be the union type.
  261. // 2. Initialize S to ∅.
  262. NonnullRefPtrVector<Type> types;
  263. // 3. For each member type U of T:
  264. for (auto& type : m_member_types) {
  265. // FIXME: 1. If U is an annotated type, then set U to be the inner type of U.
  266. // 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)
  267. // 3. If U is a union type, then add to S the flattened member types of U.
  268. if (type.is_union()) {
  269. auto& union_member_type = type.as_union();
  270. types.extend(union_member_type.flattened_member_types());
  271. } else {
  272. // 4. Otherwise, U is not a union type. Add U to S.
  273. types.append(type);
  274. }
  275. }
  276. // 4. Return S.
  277. return types;
  278. }
  279. // https://webidl.spec.whatwg.org/#dfn-number-of-nullable-member-types
  280. size_t number_of_nullable_member_types() const
  281. {
  282. // 1. Let T be the union type.
  283. // 2. Initialize n to 0.
  284. size_t num_nullable_member_types = 0;
  285. // 3. For each member type U of T:
  286. for (auto& type : m_member_types) {
  287. // 1. If U is a nullable type, then:
  288. if (type.is_nullable()) {
  289. // 1. Set n to n + 1.
  290. ++num_nullable_member_types;
  291. // 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)
  292. }
  293. // 2. If U is a union type, then:
  294. if (type.is_union()) {
  295. auto& union_member_type = type.as_union();
  296. // 1. Let m be the number of nullable member types of U.
  297. // 2. Set n to n + m.
  298. num_nullable_member_types += union_member_type.number_of_nullable_member_types();
  299. }
  300. }
  301. // 4. Return n.
  302. return num_nullable_member_types;
  303. }
  304. private:
  305. NonnullRefPtrVector<Type> m_member_types;
  306. };
  307. // https://webidl.spec.whatwg.org/#dfn-optionality-value
  308. enum class Optionality {
  309. Required,
  310. Optional,
  311. Variadic,
  312. };
  313. // https://webidl.spec.whatwg.org/#dfn-effective-overload-set
  314. class EffectiveOverloadSet {
  315. public:
  316. struct Item {
  317. int callable_id;
  318. NonnullRefPtrVector<Type> types;
  319. Vector<Optionality> optionality_values;
  320. };
  321. EffectiveOverloadSet(Vector<Item> items)
  322. : m_items(move(items))
  323. , m_argument_count(m_items.is_empty() ? 0 : m_items.first().types.size())
  324. {
  325. }
  326. Vector<Item>& items() { return m_items; }
  327. Vector<Item> const& items() const { return m_items; }
  328. Item const& only_item() const
  329. {
  330. VERIFY(m_items.size() == 1);
  331. return m_items[0];
  332. }
  333. bool is_empty() const { return m_items.is_empty(); }
  334. size_t size() const { return m_items.size(); }
  335. int distinguishing_argument_index();
  336. template<typename Matches>
  337. bool has_overload_with_matching_argument_at_index(size_t index, Matches matches)
  338. {
  339. for (auto const& item : m_items) {
  340. if (matches(item.types[index], item.optionality_values[index])) {
  341. m_last_matching_item = &item;
  342. return true;
  343. }
  344. }
  345. m_last_matching_item = nullptr;
  346. return false;
  347. }
  348. void remove_all_other_entries();
  349. private:
  350. // FIXME: This should be an "ordered set".
  351. Vector<Item> m_items;
  352. size_t m_argument_count;
  353. Item const* m_last_matching_item { nullptr };
  354. };
  355. }