Types.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  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 Type : public RefCounted<Type> {
  40. public:
  41. enum class Kind {
  42. Plain, // AKA, Type.
  43. Parameterized,
  44. Union,
  45. };
  46. Type(DeprecatedString name, bool nullable)
  47. : m_kind(Kind::Plain)
  48. , m_name(move(name))
  49. , m_nullable(nullable)
  50. {
  51. }
  52. Type(Kind kind, DeprecatedString name, bool nullable)
  53. : m_kind(kind)
  54. , m_name(move(name))
  55. , m_nullable(nullable)
  56. {
  57. }
  58. virtual ~Type() = default;
  59. Kind kind() const { return m_kind; }
  60. bool is_plain() const { return m_kind == Kind::Plain; }
  61. bool is_parameterized() const { return m_kind == Kind::Parameterized; }
  62. ParameterizedType const& as_parameterized() const;
  63. ParameterizedType& as_parameterized();
  64. bool is_union() const { return m_kind == Kind::Union; }
  65. UnionType const& as_union() const;
  66. UnionType& as_union();
  67. DeprecatedString const& name() const { return m_name; }
  68. bool is_nullable() const { return m_nullable; }
  69. void set_nullable(bool value) { m_nullable = value; }
  70. // https://webidl.spec.whatwg.org/#dfn-includes-a-nullable-type
  71. bool includes_nullable_type() const;
  72. // -> https://webidl.spec.whatwg.org/#dfn-includes-undefined
  73. bool includes_undefined() const;
  74. Type const& innermost_type() const
  75. {
  76. // From step 4 of https://webidl.spec.whatwg.org/#dfn-distinguishable
  77. // "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."
  78. // FIXME: Annotated types.
  79. VERIFY(!is_union());
  80. return *this;
  81. }
  82. // https://webidl.spec.whatwg.org/#idl-any
  83. bool is_any() const { return is_plain() && m_name == "any"; }
  84. // https://webidl.spec.whatwg.org/#idl-undefined
  85. bool is_undefined() const { return is_plain() && m_name == "undefined"; }
  86. // https://webidl.spec.whatwg.org/#idl-boolean
  87. bool is_boolean() const { return is_plain() && m_name == "boolean"; }
  88. // https://webidl.spec.whatwg.org/#idl-bigint
  89. bool is_bigint() const { return is_plain() && m_name == "bigint"; }
  90. // https://webidl.spec.whatwg.org/#idl-object
  91. bool is_object() const { return is_plain() && m_name == "object"; }
  92. // https://webidl.spec.whatwg.org/#idl-symbol
  93. bool is_symbol() const { return is_plain() && m_name == "symbol"; }
  94. bool is_string() const { return is_plain() && m_name.is_one_of("ByteString", "CSSOMString", "DOMString", "USVString"); }
  95. // https://webidl.spec.whatwg.org/#dfn-integer-type
  96. 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"); }
  97. // https://webidl.spec.whatwg.org/#dfn-numeric-type
  98. bool is_numeric() const { return is_plain() && (is_integer() || m_name.is_one_of("float", "unrestricted float", "double", "unrestricted double")); }
  99. // https://webidl.spec.whatwg.org/#dfn-primitive-type
  100. bool is_primitive() const { return is_plain() && (is_numeric() || is_boolean() || m_name == "bigint"); }
  101. // https://webidl.spec.whatwg.org/#idl-sequence
  102. bool is_sequence() const { return is_parameterized() && m_name == "sequence"; }
  103. // https://webidl.spec.whatwg.org/#dfn-distinguishable
  104. bool is_distinguishable_from(Type const& other) const;
  105. private:
  106. Kind m_kind;
  107. DeprecatedString m_name;
  108. bool m_nullable { false };
  109. };
  110. struct Parameter {
  111. NonnullRefPtr<Type const> type;
  112. DeprecatedString name;
  113. bool optional { false };
  114. Optional<DeprecatedString> optional_default_value;
  115. HashMap<DeprecatedString, DeprecatedString> extended_attributes;
  116. bool variadic { false };
  117. };
  118. struct Function {
  119. NonnullRefPtr<Type const> return_type;
  120. DeprecatedString name;
  121. Vector<Parameter> parameters;
  122. HashMap<DeprecatedString, DeprecatedString> extended_attributes;
  123. size_t overload_index { 0 };
  124. bool is_overloaded { false };
  125. size_t shortest_length() const { return get_function_shortest_length(*this); }
  126. };
  127. struct Constructor {
  128. DeprecatedString name;
  129. Vector<Parameter> parameters;
  130. size_t shortest_length() const { return get_function_shortest_length(*this); }
  131. };
  132. struct Constant {
  133. NonnullRefPtr<Type const> type;
  134. DeprecatedString name;
  135. DeprecatedString value;
  136. };
  137. struct Attribute {
  138. bool inherit { false };
  139. bool readonly { false };
  140. NonnullRefPtr<Type const> type;
  141. DeprecatedString name;
  142. HashMap<DeprecatedString, DeprecatedString> extended_attributes;
  143. // Added for convenience after parsing
  144. DeprecatedString getter_callback_name;
  145. DeprecatedString setter_callback_name;
  146. };
  147. struct DictionaryMember {
  148. bool required { false };
  149. NonnullRefPtr<Type const> type;
  150. DeprecatedString name;
  151. HashMap<DeprecatedString, DeprecatedString> extended_attributes;
  152. Optional<DeprecatedString> default_value;
  153. };
  154. struct Dictionary {
  155. DeprecatedString parent_name;
  156. Vector<DictionaryMember> members;
  157. };
  158. struct Typedef {
  159. HashMap<DeprecatedString, DeprecatedString> extended_attributes;
  160. NonnullRefPtr<Type const> type;
  161. };
  162. struct Enumeration {
  163. OrderedHashTable<DeprecatedString> values;
  164. OrderedHashMap<DeprecatedString, DeprecatedString> translated_cpp_names;
  165. DeprecatedString first_member;
  166. bool is_original_definition { true };
  167. };
  168. struct CallbackFunction {
  169. NonnullRefPtr<Type const> return_type;
  170. Vector<Parameter> parameters;
  171. bool is_legacy_treat_non_object_as_null { false };
  172. };
  173. class Interface;
  174. class ParameterizedType : public Type {
  175. public:
  176. ParameterizedType(DeprecatedString name, bool nullable, Vector<NonnullRefPtr<Type const>> parameters)
  177. : Type(Kind::Parameterized, move(name), nullable)
  178. , m_parameters(move(parameters))
  179. {
  180. }
  181. virtual ~ParameterizedType() override = default;
  182. 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;
  183. Vector<NonnullRefPtr<Type const>> const& parameters() const { return m_parameters; }
  184. Vector<NonnullRefPtr<Type const>>& parameters() { return m_parameters; }
  185. private:
  186. Vector<NonnullRefPtr<Type const>> m_parameters;
  187. };
  188. static inline size_t get_shortest_function_length(Vector<Function&> const& overload_set)
  189. {
  190. size_t shortest_length = SIZE_MAX;
  191. for (auto const& function : overload_set)
  192. shortest_length = min(function.shortest_length(), shortest_length);
  193. return shortest_length;
  194. }
  195. class Interface {
  196. AK_MAKE_NONCOPYABLE(Interface);
  197. AK_MAKE_NONMOVABLE(Interface);
  198. public:
  199. explicit Interface() = default;
  200. DeprecatedString name;
  201. DeprecatedString parent_name;
  202. bool is_namespace { false };
  203. bool is_mixin { false };
  204. HashMap<DeprecatedString, DeprecatedString> 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<DeprecatedString> stringifier_attribute;
  212. bool has_unscopable_member { false };
  213. Optional<NonnullRefPtr<Type const>> value_iterator_type;
  214. Optional<Tuple<NonnullRefPtr<Type const>, NonnullRefPtr<Type const>>> 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<DeprecatedString, Dictionary> dictionaries;
  221. HashMap<DeprecatedString, Enumeration> enumerations;
  222. HashMap<DeprecatedString, Typedef> typedefs;
  223. HashMap<DeprecatedString, Interface*> mixins;
  224. HashMap<DeprecatedString, CallbackFunction> callback_functions;
  225. // Added for convenience after parsing
  226. DeprecatedString fully_qualified_name;
  227. DeprecatedString constructor_class;
  228. DeprecatedString prototype_class;
  229. DeprecatedString prototype_base_class;
  230. DeprecatedString namespace_class;
  231. DeprecatedString global_mixin_class;
  232. HashMap<DeprecatedString, HashTable<DeprecatedString>> included_mixins;
  233. DeprecatedString module_own_path;
  234. HashTable<DeprecatedString> required_imported_paths;
  235. Vector<Interface&> imported_modules;
  236. HashMap<DeprecatedString, Vector<Function&>> overload_sets;
  237. HashMap<DeprecatedString, Vector<Function&>> static_overload_sets;
  238. // https://webidl.spec.whatwg.org/#dfn-support-indexed-properties
  239. bool supports_indexed_properties() const { return indexed_property_getter.has_value(); }
  240. // https://webidl.spec.whatwg.org/#dfn-support-named-properties
  241. bool supports_named_properties() const { return named_property_getter.has_value(); }
  242. // https://webidl.spec.whatwg.org/#dfn-legacy-platform-object
  243. bool is_legacy_platform_object() const { return !extended_attributes.contains("Global") && (supports_indexed_properties() || supports_named_properties()); }
  244. bool will_generate_code() const
  245. {
  246. return !name.is_empty() || any_of(enumerations, [](auto& entry) { return entry.value.is_original_definition; });
  247. }
  248. };
  249. class UnionType : public Type {
  250. public:
  251. UnionType(DeprecatedString name, bool nullable, Vector<NonnullRefPtr<Type const>> member_types)
  252. : Type(Kind::Union, move(name), nullable)
  253. , m_member_types(move(member_types))
  254. {
  255. }
  256. virtual ~UnionType() override = default;
  257. Vector<NonnullRefPtr<Type const>> const& member_types() const { return m_member_types; }
  258. Vector<NonnullRefPtr<Type const>>& member_types() { return m_member_types; }
  259. // https://webidl.spec.whatwg.org/#dfn-flattened-union-member-types
  260. Vector<NonnullRefPtr<Type const>> flattened_member_types() const
  261. {
  262. // 1. Let T be the union type.
  263. // 2. Initialize S to ∅.
  264. Vector<NonnullRefPtr<Type const>> types;
  265. // 3. For each member type U of T:
  266. for (auto& type : m_member_types) {
  267. // FIXME: 1. If U is an annotated type, then set U to be the inner type of U.
  268. // 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)
  269. // 3. If U is a union type, then add to S the flattened member types of U.
  270. if (type->is_union()) {
  271. auto& union_member_type = type->as_union();
  272. types.extend(union_member_type.flattened_member_types());
  273. } else {
  274. // 4. Otherwise, U is not a union type. Add U to S.
  275. types.append(type);
  276. }
  277. }
  278. // 4. Return S.
  279. return types;
  280. }
  281. // https://webidl.spec.whatwg.org/#dfn-number-of-nullable-member-types
  282. size_t number_of_nullable_member_types() const
  283. {
  284. // 1. Let T be the union type.
  285. // 2. Initialize n to 0.
  286. size_t num_nullable_member_types = 0;
  287. // 3. For each member type U of T:
  288. for (auto& type : m_member_types) {
  289. // 1. If U is a nullable type, then:
  290. if (type->is_nullable()) {
  291. // 1. Set n to n + 1.
  292. ++num_nullable_member_types;
  293. // 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)
  294. }
  295. // 2. If U is a union type, then:
  296. if (type->is_union()) {
  297. auto& union_member_type = type->as_union();
  298. // 1. Let m be the number of nullable member types of U.
  299. // 2. Set n to n + m.
  300. num_nullable_member_types += union_member_type.number_of_nullable_member_types();
  301. }
  302. }
  303. // 4. Return n.
  304. return num_nullable_member_types;
  305. }
  306. private:
  307. Vector<NonnullRefPtr<Type const>> m_member_types;
  308. };
  309. // https://webidl.spec.whatwg.org/#dfn-optionality-value
  310. enum class Optionality {
  311. Required,
  312. Optional,
  313. Variadic,
  314. };
  315. // https://webidl.spec.whatwg.org/#dfn-effective-overload-set
  316. class EffectiveOverloadSet {
  317. public:
  318. struct Item {
  319. int callable_id;
  320. Vector<NonnullRefPtr<Type const>> types;
  321. Vector<Optionality> optionality_values;
  322. };
  323. EffectiveOverloadSet(Vector<Item> items)
  324. : m_items(move(items))
  325. , m_argument_count(m_items.is_empty() ? 0 : m_items.first().types.size())
  326. {
  327. }
  328. Vector<Item>& items() { return m_items; }
  329. Vector<Item> const& items() const { return m_items; }
  330. Item const& only_item() const
  331. {
  332. VERIFY(m_items.size() == 1);
  333. return m_items[0];
  334. }
  335. bool is_empty() const { return m_items.is_empty(); }
  336. size_t size() const { return m_items.size(); }
  337. int distinguishing_argument_index();
  338. template<typename Matches>
  339. bool has_overload_with_matching_argument_at_index(size_t index, Matches matches)
  340. {
  341. for (size_t i = 0; i < m_items.size(); ++i) {
  342. auto const& item = m_items[i];
  343. if (matches(item.types[index], item.optionality_values[index])) {
  344. m_last_matching_item_index = i;
  345. return true;
  346. }
  347. }
  348. m_last_matching_item_index = {};
  349. return false;
  350. }
  351. void remove_all_other_entries();
  352. private:
  353. // FIXME: This should be an "ordered set".
  354. Vector<Item> m_items;
  355. size_t m_argument_count;
  356. Optional<size_t> m_last_matching_item_index;
  357. };
  358. }