IDL dictionary members are nullable by default (unless marked as
`required`) and should not get any value assigned unless one was
provided by the userland code that isn't undefined, or if the member has
a default value.
This is so that we can use Optional<T> in the internal representation
and check for "is present" via Optional::has_value().
The SourceGenerator's @else@ mapping is only set in the second iteration
of the loop, causing the generated return for unrecognized values to not
be guarded by an else statement.
We can simply use a hardcoded 'else' here, @else@ is only to create the
first comparison as a plain 'if' and subsequent ones as 'else if'.
Without this, the generated DOMExceptionConstructor does not refer to
the WebIDL::DOMException with its fully qualified name. This caused an
ambiguity error on my machine.
Let's stop putting generic types and AOs from the Web IDL spec into
the Bindings namespace and directory in LibWeb, and instead follow our
usual naming rules of 'directory = namespace = spec name'. The IDL
namespace is already used by LibIDL, so Web::WebIDL seems like a good
choice.
This code generator no longer creates JS wrappers for platform objects
in the old sense, instead they're JS objects internally themselves.
Most of what we generate now are prototypes - which can be seen as
bindings for the internal C++ methods implementing getters, setters, and
methods - as well as object constructors, i.e. bindings for the internal
create_with_global_object() method.
Also tweak the naming of various CMake glue code existing around this.
This name more accurately reflects what we are checking. Also add an
explanatory note that only a hand-curated subset of platform object
types is checked in the absence of a full generated list.
This fixes an issue on Twitter where they were instantiating an
IntersectionObserver with a null root. The root IDL type is
`(Element or Document)?` so null needs to be allowed.
We compute the effective overload sets for each argument count at build
time, to save us having to do it every time a function with overloads
is called.
As part of this, I've moved a couple of methods for checking for
null/undefined from UnionType to Type, and filled in more of their
steps.
This now detects more, and so causes us to hit a `TODO()` which is too
big for me to go after right now, so I've replaced that assertion with
a log message.
Track the kind of Type it is, and use that to provide some convenient
`is_foo()` / `as_foo()` methods. While I was at it, made these all
classes instead of structs and made their data private.
IDL function overload resolution requires knowing each IDL function's
parameters and their types at runtime. The simplest way to do that is
just to make the types the generator uses available to the runtime.
Parsing has moved to LibIDL, but code generation has not, since that is
very specific to WrapperGenerator.
There are still some remaining cases where generated code depends on the
existence of FooWrapper => Web::NS::Foo mappings. Fixing those will
require figuring out the appropriate namespace for all IDL types, not
just the currently parsed interface.
Unlike ensure_web_prototype<T>(), the cached version doesn't require the
prototype type to be fully formed, so we can use it without including
the FooPrototype.h header. It's also a bit less verbose. :^)
This is a monster patch that turns all EventTargets into GC-allocated
PlatformObjects. Their C++ wrapper classes are removed, and the LibJS
garbage collector is now responsible for their lifetimes.
There's a fair amount of hacks and band-aids in this patch, and we'll
have a lot of cleanup to do after this.
This patch moves the following things to being GC-allocated:
- Bindings::CallbackType
- HTML::EventHandler
- DOM::IDLEventListener
- DOM::DOMEventListener
- DOM::NodeFilter
Note that we only use PlatformObject for things that might be exposed
to web content. Anything that is only used internally inherits directly
from JS::Cell instead, making them a bit more lightweight.
This tells the wrapper generator that there is no separate wrapper class
for this interface, and it should refer directly to the C++ "Foo" object
instead of "FooWrapper".
Intrinsics, i.e. mostly constructor and prototype objects, but also
things like empty and new object shape now live on a new heap-allocated
JS::Intrinsics object, thus completing the long journey of taking all
the magic away from the global object.
This represents the Realm's [[Intrinsics]] slot in the spec and matches
its existing [[GlobalObject]] / [[GlobalEnv]] slots in terms of
architecture.
In the majority of cases it should now be possibly to fully allocate a
regular object without the global object existing, and in fact that's
what we do now - the realm is allocated before the global object, and
the intrinsics between both :^)
- Prefer VM::current_realm() over GlobalObject::associated_realm()
- Prefer VM::heap() over GlobalObject::heap()
- Prefer Cell::vm() over Cell::global_object()
- Prefer Wrapper::vm() over Wrapper::global_object()
- Inline Realm::global_object() calls used to access intrinsics as they
will later perform a direct lookup without going through the global
object