Types.h 15 KB

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