mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-06 02:55:49 +03:00
LibIDL: Implement EffectiveOverloadSet
This requires a little explanation. The overload resolution algorithm, where this is used, repeatedly has steps like this: > Otherwise: if V is a platform object, and there is an entry in S that > has one of the following types at position i of its type list, > - an interface type that V implements > - object > - a nullable version of any of the above types > - an annotated type whose inner type is one of the above types > - a union type, nullable union type, or annotated union type that has > one of the above types in its flattened member types > then remove from S all other entries. So, the API here tries to match that. We save the matching entry when checking through them and then use that in `remove_all_other_entries()`. Removing all those entries when all we actually care about is looking at that one matching entry feels silly, but sticking to the spec is more important while things are still half-implemented. :^)
This commit is contained in:
parent
8b4cc07a54
commit
0d2d5ba02c
Notes:
sideshowbarker
2024-07-17 09:49:33 +09:00
Author: https://github.com/AtkinsSJ Commit: https://github.com/SerenityOS/serenity/commit/0d2d5ba02c Pull-request: https://github.com/SerenityOS/serenity/pull/15170
@ -188,4 +188,35 @@ bool Type::is_distinguishable_from(IDL::Type const& other) const
|
||||
return table[to_underlying(this_distinguishability)][to_underlying(other_distinguishability)];
|
||||
}
|
||||
|
||||
// https://webidl.spec.whatwg.org/#dfn-distinguishing-argument-index
|
||||
int EffectiveOverloadSet::distinguishing_argument_index()
|
||||
{
|
||||
for (auto argument_index = 0u; argument_index < m_argument_count; ++argument_index) {
|
||||
bool found_indistinguishable = false;
|
||||
|
||||
for (auto first_item_index = 0u; first_item_index < m_items.size(); ++first_item_index) {
|
||||
for (auto second_item_index = first_item_index + 1; second_item_index < m_items.size(); ++second_item_index) {
|
||||
if (!m_items[first_item_index].types[argument_index].is_distinguishable_from(m_items[second_item_index].types[argument_index])) {
|
||||
found_indistinguishable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found_indistinguishable)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found_indistinguishable)
|
||||
return argument_index;
|
||||
}
|
||||
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
void EffectiveOverloadSet::remove_all_other_entries()
|
||||
{
|
||||
m_items.remove_all_matching([this](auto const& item) {
|
||||
return &item != m_last_matching_item;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -394,4 +394,63 @@ private:
|
||||
NonnullRefPtrVector<Type> m_member_types;
|
||||
};
|
||||
|
||||
// https://webidl.spec.whatwg.org/#dfn-optionality-value
|
||||
enum class Optionality {
|
||||
Required,
|
||||
Optional,
|
||||
Variadic,
|
||||
};
|
||||
|
||||
// https://webidl.spec.whatwg.org/#dfn-effective-overload-set
|
||||
class EffectiveOverloadSet {
|
||||
public:
|
||||
struct Item {
|
||||
int callable_id;
|
||||
NonnullRefPtrVector<Type> types;
|
||||
Vector<Optionality> optionality_values;
|
||||
};
|
||||
|
||||
EffectiveOverloadSet(Vector<Item> items)
|
||||
: m_items(move(items))
|
||||
, m_argument_count(m_items.is_empty() ? 0 : m_items.first().types.size())
|
||||
{
|
||||
}
|
||||
|
||||
Vector<Item>& items() { return m_items; }
|
||||
Vector<Item> const& items() const { return m_items; }
|
||||
|
||||
Item const& only_item() const
|
||||
{
|
||||
VERIFY(m_items.size() == 1);
|
||||
return m_items[0];
|
||||
}
|
||||
|
||||
bool is_empty() const { return m_items.is_empty(); }
|
||||
size_t size() const { return m_items.size(); }
|
||||
|
||||
int distinguishing_argument_index();
|
||||
|
||||
template<typename Matches>
|
||||
bool has_overload_with_matching_argument_at_index(size_t index, Matches matches)
|
||||
{
|
||||
for (auto const& item : m_items) {
|
||||
if (matches(item.types[index], item.optionality_values[index])) {
|
||||
m_last_matching_item = &item;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
m_last_matching_item = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
void remove_all_other_entries();
|
||||
|
||||
private:
|
||||
// FIXME: This should be an "ordered set".
|
||||
Vector<Item> m_items;
|
||||
size_t m_argument_count;
|
||||
|
||||
Item const* m_last_matching_item { nullptr };
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user