mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-11 18:50:50 +00:00
LibIDL+LibWeb: Move parse_exposure_set from code generator to LibIDL
This commit is contained in:
parent
dbba6c0df9
commit
da620d6ccf
Notes:
github-actions[bot]
2025-06-30 17:40:52 +00:00
Author: https://github.com/bplaat
Commit: da620d6ccf
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4535
Reviewed-by: https://github.com/ADKaster ✅
Reviewed-by: https://github.com/trflynn89
4 changed files with 114 additions and 83 deletions
|
@ -1,4 +1,5 @@
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
|
ExposedTo.cpp
|
||||||
IDLParser.cpp
|
IDLParser.cpp
|
||||||
Types.cpp
|
Types.cpp
|
||||||
)
|
)
|
||||||
|
|
76
Libraries/LibIDL/ExposedTo.cpp
Normal file
76
Libraries/LibIDL/ExposedTo.cpp
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Andrew Kaster <akaster@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <LibIDL/ExposedTo.h>
|
||||||
|
|
||||||
|
static ByteString s_error_string;
|
||||||
|
|
||||||
|
namespace IDL {
|
||||||
|
|
||||||
|
ErrorOr<ExposedTo> parse_exposure_set(StringView interface_name, StringView exposed)
|
||||||
|
{
|
||||||
|
// NOTE: This roughly follows the definitions of https://webidl.spec.whatwg.org/#Exposed
|
||||||
|
// It does not remotely interpret all the abstract operations therein though.
|
||||||
|
|
||||||
|
auto exposed_trimmed = exposed.trim_whitespace();
|
||||||
|
if (exposed_trimmed == "*"sv)
|
||||||
|
return ExposedTo::All;
|
||||||
|
if (exposed_trimmed == "Nobody"sv)
|
||||||
|
return ExposedTo::Nobody;
|
||||||
|
if (exposed_trimmed == "Window"sv)
|
||||||
|
return ExposedTo::Window;
|
||||||
|
if (exposed_trimmed == "Worker"sv)
|
||||||
|
return ExposedTo::AllWorkers;
|
||||||
|
if (exposed_trimmed == "DedicatedWorker"sv)
|
||||||
|
return ExposedTo::DedicatedWorker;
|
||||||
|
if (exposed_trimmed == "SharedWorker"sv)
|
||||||
|
return ExposedTo::SharedWorker;
|
||||||
|
if (exposed_trimmed == "ServiceWorker"sv)
|
||||||
|
return ExposedTo::ServiceWorker;
|
||||||
|
if (exposed_trimmed == "AudioWorklet"sv)
|
||||||
|
return ExposedTo::AudioWorklet;
|
||||||
|
if (exposed_trimmed == "Worklet"sv)
|
||||||
|
return ExposedTo::Worklet;
|
||||||
|
if (exposed_trimmed == "ShadowRealm"sv)
|
||||||
|
return ExposedTo::ShadowRealm;
|
||||||
|
|
||||||
|
if (exposed_trimmed[0] == '(') {
|
||||||
|
ExposedTo whom = Nobody;
|
||||||
|
for (StringView candidate : exposed_trimmed.substring_view(1, exposed_trimmed.length() - 1).split_view(',')) {
|
||||||
|
candidate = candidate.trim_whitespace();
|
||||||
|
if (candidate == "Window"sv) {
|
||||||
|
whom |= ExposedTo::Window;
|
||||||
|
} else if (candidate == "Worker"sv) {
|
||||||
|
whom |= ExposedTo::AllWorkers;
|
||||||
|
} else if (candidate == "DedicatedWorker"sv) {
|
||||||
|
whom |= ExposedTo::DedicatedWorker;
|
||||||
|
} else if (candidate == "SharedWorker"sv) {
|
||||||
|
whom |= ExposedTo::SharedWorker;
|
||||||
|
} else if (candidate == "ServiceWorker"sv) {
|
||||||
|
whom |= ExposedTo::ServiceWorker;
|
||||||
|
} else if (candidate == "AudioWorklet"sv) {
|
||||||
|
whom |= ExposedTo::AudioWorklet;
|
||||||
|
} else if (candidate == "Worklet"sv) {
|
||||||
|
whom |= ExposedTo::Worklet;
|
||||||
|
} else if (candidate == "ShadowRealm"sv) {
|
||||||
|
whom |= ExposedTo::ShadowRealm;
|
||||||
|
} else {
|
||||||
|
s_error_string = ByteString::formatted("Unknown Exposed attribute candidate {} in {} in {}", candidate, exposed_trimmed, interface_name);
|
||||||
|
return Error::from_string_view(s_error_string.view());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (whom == ExposedTo::Nobody) {
|
||||||
|
s_error_string = ByteString::formatted("Unknown Exposed attribute {} in {}", exposed_trimmed, interface_name);
|
||||||
|
return Error::from_string_view(s_error_string.view());
|
||||||
|
}
|
||||||
|
return whom;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_error_string = ByteString::formatted("Unknown Exposed attribute {} in {}", exposed_trimmed, interface_name);
|
||||||
|
return Error::from_string_view(s_error_string.view());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
29
Libraries/LibIDL/ExposedTo.h
Normal file
29
Libraries/LibIDL/ExposedTo.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Andrew Kaster <akaster@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibIDL/Types.h>
|
||||||
|
|
||||||
|
namespace IDL {
|
||||||
|
|
||||||
|
enum ExposedTo {
|
||||||
|
Nobody = 0x0,
|
||||||
|
DedicatedWorker = 0x1,
|
||||||
|
SharedWorker = 0x2,
|
||||||
|
ServiceWorker = 0x4,
|
||||||
|
AudioWorklet = 0x8,
|
||||||
|
Window = 0x10,
|
||||||
|
ShadowRealm = 0x20,
|
||||||
|
Worklet = 0x40,
|
||||||
|
AllWorkers = DedicatedWorker | SharedWorker | ServiceWorker | AudioWorklet, // FIXME: Is "AudioWorklet" a Worker? We'll assume it is for now (here, and line below)
|
||||||
|
All = AllWorkers | Window | ShadowRealm | Worklet,
|
||||||
|
};
|
||||||
|
AK_ENUM_BITWISE_OPERATORS(ExposedTo);
|
||||||
|
|
||||||
|
ErrorOr<ExposedTo> parse_exposure_set(StringView interface_name, StringView exposed);
|
||||||
|
|
||||||
|
}
|
|
@ -10,6 +10,7 @@
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
#include <LibCore/ArgsParser.h>
|
#include <LibCore/ArgsParser.h>
|
||||||
#include <LibCore/File.h>
|
#include <LibCore/File.h>
|
||||||
|
#include <LibIDL/ExposedTo.h>
|
||||||
#include <LibIDL/IDLParser.h>
|
#include <LibIDL/IDLParser.h>
|
||||||
#include <LibIDL/Types.h>
|
#include <LibIDL/Types.h>
|
||||||
#include <LibMain/Main.h>
|
#include <LibMain/Main.h>
|
||||||
|
@ -433,105 +434,29 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ExposedTo {
|
ErrorOr<void> add_to_interface_sets(IDL::Interface& interface, Vector<IDL::Interface&>& intrinsics, Vector<IDL::Interface&>& window_exposed, Vector<IDL::Interface&>& dedicated_worker_exposed, Vector<IDL::Interface&>& shared_worker_exposed, Vector<IDL::Interface&>& shadow_realm_exposed)
|
||||||
Nobody = 0x0,
|
|
||||||
DedicatedWorker = 0x1,
|
|
||||||
SharedWorker = 0x2,
|
|
||||||
ServiceWorker = 0x4,
|
|
||||||
AudioWorklet = 0x8,
|
|
||||||
Window = 0x10,
|
|
||||||
ShadowRealm = 0x20,
|
|
||||||
Worklet = 0x40,
|
|
||||||
AllWorkers = DedicatedWorker | SharedWorker | ServiceWorker | AudioWorklet, // FIXME: Is "AudioWorklet" a Worker? We'll assume it is for now (here, and line below)
|
|
||||||
All = AllWorkers | Window | ShadowRealm | Worklet,
|
|
||||||
};
|
|
||||||
AK_ENUM_BITWISE_OPERATORS(ExposedTo);
|
|
||||||
|
|
||||||
static ErrorOr<ExposedTo> parse_exposure_set(IDL::Interface& interface)
|
|
||||||
{
|
{
|
||||||
// NOTE: This roughly follows the definitions of https://webidl.spec.whatwg.org/#Exposed
|
// TODO: Add service worker exposed and audio worklet exposed
|
||||||
// It does not remotely interpret all the abstract operations therein though.
|
|
||||||
|
|
||||||
auto maybe_exposed = interface.extended_attributes.get("Exposed");
|
auto maybe_exposed = interface.extended_attributes.get("Exposed");
|
||||||
if (!maybe_exposed.has_value()) {
|
if (!maybe_exposed.has_value()) {
|
||||||
s_error_string = ByteString::formatted("Interface {} is missing extended attribute Exposed", interface.name);
|
s_error_string = ByteString::formatted("Interface {} is missing extended attribute Exposed", interface.name);
|
||||||
return Error::from_string_view(s_error_string.view());
|
return Error::from_string_view(s_error_string.view());
|
||||||
}
|
}
|
||||||
auto exposed = maybe_exposed.value().trim_whitespace();
|
auto whom = TRY(IDL::parse_exposure_set(interface.name, *maybe_exposed));
|
||||||
if (exposed == "*"sv)
|
|
||||||
return ExposedTo::All;
|
|
||||||
if (exposed == "Nobody"sv)
|
|
||||||
return ExposedTo::Nobody;
|
|
||||||
if (exposed == "Window"sv)
|
|
||||||
return ExposedTo::Window;
|
|
||||||
if (exposed == "Worker"sv)
|
|
||||||
return ExposedTo::AllWorkers;
|
|
||||||
if (exposed == "DedicatedWorker"sv)
|
|
||||||
return ExposedTo::DedicatedWorker;
|
|
||||||
if (exposed == "SharedWorker"sv)
|
|
||||||
return ExposedTo::SharedWorker;
|
|
||||||
if (exposed == "ServiceWorker"sv)
|
|
||||||
return ExposedTo::ServiceWorker;
|
|
||||||
if (exposed == "AudioWorklet"sv)
|
|
||||||
return ExposedTo::AudioWorklet;
|
|
||||||
if (exposed == "Worklet"sv)
|
|
||||||
return ExposedTo::Worklet;
|
|
||||||
if (exposed == "ShadowRealm"sv)
|
|
||||||
return ExposedTo::ShadowRealm;
|
|
||||||
|
|
||||||
if (exposed[0] == '(') {
|
|
||||||
ExposedTo whom = Nobody;
|
|
||||||
for (StringView candidate : exposed.substring_view(1, exposed.length() - 1).split_view(',')) {
|
|
||||||
candidate = candidate.trim_whitespace();
|
|
||||||
if (candidate == "Window"sv) {
|
|
||||||
whom |= ExposedTo::Window;
|
|
||||||
} else if (candidate == "Worker"sv) {
|
|
||||||
whom |= ExposedTo::AllWorkers;
|
|
||||||
} else if (candidate == "DedicatedWorker"sv) {
|
|
||||||
whom |= ExposedTo::DedicatedWorker;
|
|
||||||
} else if (candidate == "SharedWorker"sv) {
|
|
||||||
whom |= ExposedTo::SharedWorker;
|
|
||||||
} else if (candidate == "ServiceWorker"sv) {
|
|
||||||
whom |= ExposedTo::ServiceWorker;
|
|
||||||
} else if (candidate == "AudioWorklet"sv) {
|
|
||||||
whom |= ExposedTo::AudioWorklet;
|
|
||||||
} else if (candidate == "Worklet"sv) {
|
|
||||||
whom |= ExposedTo::Worklet;
|
|
||||||
} else if (candidate == "ShadowRealm"sv) {
|
|
||||||
whom |= ExposedTo::ShadowRealm;
|
|
||||||
} else {
|
|
||||||
s_error_string = ByteString::formatted("Unknown Exposed attribute candidate {} in {} in {}", candidate, exposed, interface.name);
|
|
||||||
return Error::from_string_view(s_error_string.view());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (whom == ExposedTo::Nobody) {
|
|
||||||
s_error_string = ByteString::formatted("Unknown Exposed attribute {} in {}", exposed, interface.name);
|
|
||||||
return Error::from_string_view(s_error_string.view());
|
|
||||||
}
|
|
||||||
return whom;
|
|
||||||
}
|
|
||||||
|
|
||||||
s_error_string = ByteString::formatted("Unknown Exposed attribute {} in {}", exposed, interface.name);
|
|
||||||
return Error::from_string_view(s_error_string.view());
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorOr<void> add_to_interface_sets(IDL::Interface& interface, Vector<IDL::Interface&>& intrinsics, Vector<IDL::Interface&>& window_exposed, Vector<IDL::Interface&>& dedicated_worker_exposed, Vector<IDL::Interface&>& shared_worker_exposed, Vector<IDL::Interface&>& shadow_realm_exposed)
|
|
||||||
{
|
|
||||||
// TODO: Add service worker exposed and audio worklet exposed
|
|
||||||
auto whom = TRY(parse_exposure_set(interface));
|
|
||||||
|
|
||||||
intrinsics.append(interface);
|
intrinsics.append(interface);
|
||||||
|
|
||||||
if (whom & ExposedTo::Window)
|
if (whom & IDL::ExposedTo::Window)
|
||||||
window_exposed.append(interface);
|
window_exposed.append(interface);
|
||||||
|
|
||||||
if (whom & ExposedTo::DedicatedWorker)
|
if (whom & IDL::ExposedTo::DedicatedWorker)
|
||||||
dedicated_worker_exposed.append(interface);
|
dedicated_worker_exposed.append(interface);
|
||||||
|
|
||||||
if (whom & ExposedTo::SharedWorker)
|
if (whom & IDL::ExposedTo::SharedWorker)
|
||||||
shared_worker_exposed.append(interface);
|
shared_worker_exposed.append(interface);
|
||||||
|
|
||||||
if (whom & ExposedTo::ShadowRealm)
|
if (whom & IDL::ExposedTo::ShadowRealm)
|
||||||
shadow_realm_exposed.append(interface);
|
shadow_realm_exposed.append(interface);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue