mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 21:07:35 +00:00
LibGUI: Remove GML prefix in favor of proper namespace
Prefixes are very much a C thing which we don't need in C++. This commit moves all GML-related classes in LibGUI into the GUI::GML namespace, a change somewhat overdue.
This commit is contained in:
parent
89201b682b
commit
4931c88b13
17 changed files with 129 additions and 125 deletions
|
@ -338,9 +338,9 @@ if (BUILD_LAGOM)
|
||||||
LIBS m LagomGfx LagomSoftGPU)
|
LIBS m LagomGfx LagomSoftGPU)
|
||||||
|
|
||||||
# GUI-GML
|
# GUI-GML
|
||||||
file(GLOB LIBGUI_GML_SOURCES CONFIGURE_DEPENDS "../../Userland/Libraries/LibGUI/GML*.cpp")
|
file(GLOB LIBGUI_GML_SOURCES CONFIGURE_DEPENDS "../../Userland/Libraries/LibGUI/GML/*.cpp")
|
||||||
list(REMOVE_ITEM LIBGUI_GML_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/../../Userland/Libraries/LibGUI/GMLAutocompleteProvider.cpp")
|
list(REMOVE_ITEM LIBGUI_GML_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/../../Userland/Libraries/LibGUI/GML/AutocompleteProvider.cpp")
|
||||||
list(REMOVE_ITEM LIBGUI_GML_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/../../Userland/Libraries/LibGUI/GMLSyntaxHighlighter.cpp")
|
list(REMOVE_ITEM LIBGUI_GML_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/../../Userland/Libraries/LibGUI/GML/SyntaxHighlighter.cpp")
|
||||||
lagom_lib(GML gml
|
lagom_lib(GML gml
|
||||||
SOURCES ${LIBGUI_GML_SOURCES}
|
SOURCES ${LIBGUI_GML_SOURCES}
|
||||||
)
|
)
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include <LibGUI/CheckBox.h>
|
#include <LibGUI/CheckBox.h>
|
||||||
#include <LibGUI/FilePicker.h>
|
#include <LibGUI/FilePicker.h>
|
||||||
#include <LibGUI/FontPicker.h>
|
#include <LibGUI/FontPicker.h>
|
||||||
#include <LibGUI/GMLSyntaxHighlighter.h>
|
#include <LibGUI/GML/SyntaxHighlighter.h>
|
||||||
#include <LibGUI/GitCommitSyntaxHighlighter.h>
|
#include <LibGUI/GitCommitSyntaxHighlighter.h>
|
||||||
#include <LibGUI/GroupBox.h>
|
#include <LibGUI/GroupBox.h>
|
||||||
#include <LibGUI/INISyntaxHighlighter.h>
|
#include <LibGUI/INISyntaxHighlighter.h>
|
||||||
|
@ -582,7 +582,7 @@ void MainWidget::initialize_menubar(GUI::Window& window)
|
||||||
syntax_menu.add_action(*m_git_highlight);
|
syntax_menu.add_action(*m_git_highlight);
|
||||||
|
|
||||||
m_gml_highlight = GUI::Action::create_checkable("&GML", [&](auto&) {
|
m_gml_highlight = GUI::Action::create_checkable("&GML", [&](auto&) {
|
||||||
m_editor->set_syntax_highlighter(make<GUI::GMLSyntaxHighlighter>());
|
m_editor->set_syntax_highlighter(make<GUI::GML::SyntaxHighlighter>());
|
||||||
m_editor->update();
|
m_editor->update();
|
||||||
});
|
});
|
||||||
syntax_actions.add_action(*m_gml_highlight);
|
syntax_actions.add_action(*m_gml_highlight);
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
#include <LibCpp/SyntaxHighlighter.h>
|
#include <LibCpp/SyntaxHighlighter.h>
|
||||||
#include <LibGUI/Action.h>
|
#include <LibGUI/Action.h>
|
||||||
#include <LibGUI/Application.h>
|
#include <LibGUI/Application.h>
|
||||||
#include <LibGUI/GMLAutocompleteProvider.h>
|
#include <LibGUI/GML/AutocompleteProvider.h>
|
||||||
#include <LibGUI/GMLSyntaxHighlighter.h>
|
#include <LibGUI/GML/SyntaxHighlighter.h>
|
||||||
#include <LibGUI/GitCommitSyntaxHighlighter.h>
|
#include <LibGUI/GitCommitSyntaxHighlighter.h>
|
||||||
#include <LibGUI/INISyntaxHighlighter.h>
|
#include <LibGUI/INISyntaxHighlighter.h>
|
||||||
#include <LibGUI/Label.h>
|
#include <LibGUI/Label.h>
|
||||||
|
@ -611,7 +611,7 @@ void Editor::set_syntax_highlighter_for(const CodeDocument& document)
|
||||||
set_syntax_highlighter(make<GUI::GitCommitSyntaxHighlighter>());
|
set_syntax_highlighter(make<GUI::GitCommitSyntaxHighlighter>());
|
||||||
break;
|
break;
|
||||||
case Language::GML:
|
case Language::GML:
|
||||||
set_syntax_highlighter(make<GUI::GMLSyntaxHighlighter>());
|
set_syntax_highlighter(make<GUI::GML::SyntaxHighlighter>());
|
||||||
break;
|
break;
|
||||||
case Language::HTML:
|
case Language::HTML:
|
||||||
set_syntax_highlighter(make<Web::HTML::SyntaxHighlighter>());
|
set_syntax_highlighter(make<Web::HTML::SyntaxHighlighter>());
|
||||||
|
@ -637,7 +637,7 @@ void Editor::set_autocomplete_provider_for(CodeDocument const& document)
|
||||||
{
|
{
|
||||||
switch (document.language()) {
|
switch (document.language()) {
|
||||||
case Language::GML:
|
case Language::GML:
|
||||||
set_autocomplete_provider(make<GUI::GMLAutocompleteProvider>());
|
set_autocomplete_provider(make<GUI::GML::AutocompleteProvider>());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
set_autocomplete_provider({});
|
set_autocomplete_provider({});
|
||||||
|
|
|
@ -12,10 +12,10 @@
|
||||||
#include <LibDesktop/Launcher.h>
|
#include <LibDesktop/Launcher.h>
|
||||||
#include <LibGUI/Application.h>
|
#include <LibGUI/Application.h>
|
||||||
#include <LibGUI/FilePicker.h>
|
#include <LibGUI/FilePicker.h>
|
||||||
#include <LibGUI/GMLAutocompleteProvider.h>
|
#include <LibGUI/GML/AutocompleteProvider.h>
|
||||||
#include <LibGUI/GMLFormatter.h>
|
#include <LibGUI/GML/Formatter.h>
|
||||||
#include <LibGUI/GMLLexer.h>
|
#include <LibGUI/GML/Lexer.h>
|
||||||
#include <LibGUI/GMLSyntaxHighlighter.h>
|
#include <LibGUI/GML/SyntaxHighlighter.h>
|
||||||
#include <LibGUI/Icon.h>
|
#include <LibGUI/Icon.h>
|
||||||
#include <LibGUI/Menu.h>
|
#include <LibGUI/Menu.h>
|
||||||
#include <LibGUI/Menubar.h>
|
#include <LibGUI/Menubar.h>
|
||||||
|
@ -87,8 +87,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
auto editor = TRY(splitter->try_add<GUI::TextEditor>());
|
auto editor = TRY(splitter->try_add<GUI::TextEditor>());
|
||||||
auto preview = TRY(splitter->try_add<GUI::Frame>());
|
auto preview = TRY(splitter->try_add<GUI::Frame>());
|
||||||
|
|
||||||
editor->set_syntax_highlighter(make<GUI::GMLSyntaxHighlighter>());
|
editor->set_syntax_highlighter(make<GUI::GML::SyntaxHighlighter>());
|
||||||
editor->set_autocomplete_provider(make<GUI::GMLAutocompleteProvider>());
|
editor->set_autocomplete_provider(make<GUI::GML::AutocompleteProvider>());
|
||||||
editor->set_should_autocomplete_automatically(true);
|
editor->set_should_autocomplete_automatically(true);
|
||||||
editor->set_automatic_indentation_enabled(true);
|
editor->set_automatic_indentation_enabled(true);
|
||||||
editor->set_ruler_visible(true);
|
editor->set_ruler_visible(true);
|
||||||
|
@ -215,9 +215,9 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
auto edit_menu = TRY(window->try_add_menu("&Edit"));
|
auto edit_menu = TRY(window->try_add_menu("&Edit"));
|
||||||
TRY(edit_menu->try_add_action(GUI::Action::create("&Format GML", { Mod_Ctrl | Mod_Shift, Key_I }, [&](auto&) {
|
TRY(edit_menu->try_add_action(GUI::Action::create("&Format GML", { Mod_Ctrl | Mod_Shift, Key_I }, [&](auto&) {
|
||||||
auto source = editor->text();
|
auto source = editor->text();
|
||||||
GUI::GMLLexer lexer(source);
|
GUI::GML::Lexer lexer(source);
|
||||||
for (auto& token : lexer.lex()) {
|
for (auto& token : lexer.lex()) {
|
||||||
if (token.m_type == GUI::GMLToken::Type::Comment) {
|
if (token.m_type == GUI::GML::Token::Type::Comment) {
|
||||||
auto result = GUI::MessageBox::show(
|
auto result = GUI::MessageBox::show(
|
||||||
window,
|
window,
|
||||||
"Your GML contains comments, which currently are not supported by the formatter and will be removed. Proceed?",
|
"Your GML contains comments, which currently are not supported by the formatter and will be removed. Proceed?",
|
||||||
|
@ -229,7 +229,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto formatted_gml = GUI::format_gml(source);
|
auto formatted_gml = GUI::GML::format_gml(source);
|
||||||
if (!formatted_gml.is_null()) {
|
if (!formatted_gml.is_null()) {
|
||||||
editor->set_text(formatted_gml);
|
editor->set_text(formatted_gml);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -46,11 +46,11 @@ set(SOURCES
|
||||||
GitCommitLexer.cpp
|
GitCommitLexer.cpp
|
||||||
GitCommitSyntaxHighlighter.cpp
|
GitCommitSyntaxHighlighter.cpp
|
||||||
GlyphMapWidget.cpp
|
GlyphMapWidget.cpp
|
||||||
GMLAutocompleteProvider.cpp
|
GML/AutocompleteProvider.cpp
|
||||||
GMLFormatter.cpp
|
GML/Formatter.cpp
|
||||||
GMLLexer.cpp
|
GML/Lexer.cpp
|
||||||
GMLParser.cpp
|
GML/Parser.cpp
|
||||||
GMLSyntaxHighlighter.cpp
|
GML/SyntaxHighlighter.cpp
|
||||||
GroupBox.cpp
|
GroupBox.cpp
|
||||||
HeaderView.cpp
|
HeaderView.cpp
|
||||||
INILexer.cpp
|
INILexer.cpp
|
||||||
|
|
|
@ -5,17 +5,17 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "GMLAutocompleteProvider.h"
|
#include "AutocompleteProvider.h"
|
||||||
#include "GMLLexer.h"
|
#include "Lexer.h"
|
||||||
#include <AK/QuickSort.h>
|
#include <AK/QuickSort.h>
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI::GML {
|
||||||
|
|
||||||
void GMLAutocompleteProvider::provide_completions(Function<void(Vector<Entry>)> callback)
|
void AutocompleteProvider::provide_completions(Function<void(Vector<Entry>)> callback)
|
||||||
{
|
{
|
||||||
auto cursor = m_editor->cursor();
|
auto cursor = m_editor->cursor();
|
||||||
auto text = m_editor->text();
|
auto text = m_editor->text();
|
||||||
GUI::GMLLexer lexer(text);
|
Lexer lexer(text);
|
||||||
// FIXME: Provide a begin() and end() for lexers PLEASE!
|
// FIXME: Provide a begin() and end() for lexers PLEASE!
|
||||||
auto all_tokens = lexer.lex();
|
auto all_tokens = lexer.lex();
|
||||||
enum State {
|
enum State {
|
||||||
|
@ -29,16 +29,16 @@ void GMLAutocompleteProvider::provide_completions(Function<void(Vector<Entry>)>
|
||||||
Vector<String> class_names;
|
Vector<String> class_names;
|
||||||
Vector<State> previous_states;
|
Vector<State> previous_states;
|
||||||
bool should_push_state { true };
|
bool should_push_state { true };
|
||||||
GUI::GMLToken* last_seen_token { nullptr };
|
Token* last_seen_token { nullptr };
|
||||||
GUI::GMLToken* last_identifier_token { nullptr };
|
Token* last_identifier_token { nullptr };
|
||||||
|
|
||||||
for (auto& token : all_tokens) {
|
for (auto& token : all_tokens) {
|
||||||
auto handle_class_child = [&] {
|
auto handle_class_child = [&] {
|
||||||
if (token.m_type == GUI::GMLToken::Type::Identifier) {
|
if (token.m_type == Token::Type::Identifier) {
|
||||||
state = InIdentifier;
|
state = InIdentifier;
|
||||||
identifier_string = token.m_view;
|
identifier_string = token.m_view;
|
||||||
last_identifier_token = &token;
|
last_identifier_token = &token;
|
||||||
} else if (token.m_type == GUI::GMLToken::Type::ClassMarker) {
|
} else if (token.m_type == Token::Type::ClassMarker) {
|
||||||
previous_states.append(AfterClassName);
|
previous_states.append(AfterClassName);
|
||||||
state = Free;
|
state = Free;
|
||||||
should_push_state = false;
|
should_push_state = false;
|
||||||
|
@ -51,7 +51,7 @@ void GMLAutocompleteProvider::provide_completions(Function<void(Vector<Entry>)>
|
||||||
last_seen_token = &token;
|
last_seen_token = &token;
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case Free:
|
case Free:
|
||||||
if (token.m_type == GUI::GMLToken::Type::ClassName) {
|
if (token.m_type == Token::Type::ClassName) {
|
||||||
if (should_push_state)
|
if (should_push_state)
|
||||||
previous_states.append(state);
|
previous_states.append(state);
|
||||||
else
|
else
|
||||||
|
@ -62,7 +62,7 @@ void GMLAutocompleteProvider::provide_completions(Function<void(Vector<Entry>)>
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case InClassName:
|
case InClassName:
|
||||||
if (token.m_type != GUI::GMLToken::Type::LeftCurly) {
|
if (token.m_type != Token::Type::LeftCurly) {
|
||||||
// Close empty class and immediately handle our parent's next child
|
// Close empty class and immediately handle our parent's next child
|
||||||
class_names.take_last();
|
class_names.take_last();
|
||||||
state = previous_states.take_last();
|
state = previous_states.take_last();
|
||||||
|
@ -77,20 +77,20 @@ void GMLAutocompleteProvider::provide_completions(Function<void(Vector<Entry>)>
|
||||||
case AfterClassName:
|
case AfterClassName:
|
||||||
handle_class_child();
|
handle_class_child();
|
||||||
|
|
||||||
if (token.m_type == GUI::GMLToken::Type::RightCurly) {
|
if (token.m_type == Token::Type::RightCurly) {
|
||||||
class_names.take_last();
|
class_names.take_last();
|
||||||
state = previous_states.take_last();
|
state = previous_states.take_last();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case InIdentifier:
|
case InIdentifier:
|
||||||
if (token.m_type == GUI::GMLToken::Type::Colon)
|
if (token.m_type == Token::Type::Colon)
|
||||||
state = AfterIdentifier;
|
state = AfterIdentifier;
|
||||||
break;
|
break;
|
||||||
case AfterIdentifier:
|
case AfterIdentifier:
|
||||||
if (token.m_type == GUI::GMLToken::Type::RightCurly || token.m_type == GUI::GMLToken::Type::LeftCurly)
|
if (token.m_type == Token::Type::RightCurly || token.m_type == Token::Type::LeftCurly)
|
||||||
break;
|
break;
|
||||||
if (token.m_type == GUI::GMLToken::Type::ClassMarker) {
|
if (token.m_type == Token::Type::ClassMarker) {
|
||||||
previous_states.append(AfterClassName);
|
previous_states.append(AfterClassName);
|
||||||
state = Free;
|
state = Free;
|
||||||
should_push_state = false;
|
should_push_state = false;
|
||||||
|
@ -121,7 +121,7 @@ void GMLAutocompleteProvider::provide_completions(Function<void(Vector<Entry>)>
|
||||||
return fuzzy_str_builder.build();
|
return fuzzy_str_builder.build();
|
||||||
};
|
};
|
||||||
|
|
||||||
Vector<GUI::AutocompleteProvider::Entry> class_entries, identifier_entries;
|
Vector<AutocompleteProvider::Entry> class_entries, identifier_entries;
|
||||||
|
|
||||||
auto register_layouts_matching_pattern = [&](String pattern, size_t partial_input_length) {
|
auto register_layouts_matching_pattern = [&](String pattern, size_t partial_input_length) {
|
||||||
Core::ObjectClassRegistration::for_each([&](const Core::ObjectClassRegistration& registration) {
|
Core::ObjectClassRegistration::for_each([&](const Core::ObjectClassRegistration& registration) {
|
||||||
|
@ -211,7 +211,7 @@ void GMLAutocompleteProvider::provide_completions(Function<void(Vector<Entry>)>
|
||||||
break;
|
break;
|
||||||
case AfterClassName:
|
case AfterClassName:
|
||||||
if (last_seen_token && last_seen_token->m_end.line == cursor.line()) {
|
if (last_seen_token && last_seen_token->m_end.line == cursor.line()) {
|
||||||
if (last_seen_token->m_type != GUI::GMLToken::Type::Identifier || last_seen_token->m_end.column != cursor.column()) {
|
if (last_seen_token->m_type != Token::Type::Identifier || last_seen_token->m_end.column != cursor.column()) {
|
||||||
// Inside braces, but on the same line as some other stuff (and not the continuation of one!)
|
// Inside braces, but on the same line as some other stuff (and not the continuation of one!)
|
||||||
// The user expects nothing here.
|
// The user expects nothing here.
|
||||||
break;
|
break;
|
|
@ -6,14 +6,14 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "AutocompleteProvider.h"
|
#include "../AutocompleteProvider.h"
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI::GML {
|
||||||
|
|
||||||
class GMLAutocompleteProvider final : public virtual GUI::AutocompleteProvider {
|
class AutocompleteProvider final : public virtual GUI::AutocompleteProvider {
|
||||||
public:
|
public:
|
||||||
GMLAutocompleteProvider() { }
|
AutocompleteProvider() { }
|
||||||
virtual ~GMLAutocompleteProvider() override { }
|
virtual ~AutocompleteProvider() override { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool can_have_declared_layout(StringView class_name)
|
static bool can_have_declared_layout(StringView class_name)
|
|
@ -1,16 +1,17 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
|
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
|
||||||
|
* Copyright (c) 2022, kleines Filmröllchen <filmroellchen@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "Formatter.h"
|
||||||
|
#include "Parser.h"
|
||||||
#include <AK/JsonObject.h>
|
#include <AK/JsonObject.h>
|
||||||
#include <AK/JsonValue.h>
|
#include <AK/JsonValue.h>
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
#include <LibGUI/GMLFormatter.h>
|
|
||||||
#include <LibGUI/GMLParser.h>
|
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI::GML {
|
||||||
|
|
||||||
static String format_gml_object(const JsonObject& node, size_t indentation = 0, bool is_inline = false)
|
static String format_gml_object(const JsonObject& node, size_t indentation = 0, bool is_inline = false)
|
||||||
{
|
{
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#include <AK/Forward.h>
|
#include <AK/Forward.h>
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI::GML {
|
||||||
|
|
||||||
String format_gml(StringView);
|
String format_gml(StringView);
|
||||||
|
|
|
@ -4,25 +4,25 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "GMLLexer.h"
|
#include "Lexer.h"
|
||||||
#include <AK/CharacterTypes.h>
|
#include <AK/CharacterTypes.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI::GML {
|
||||||
|
|
||||||
GMLLexer::GMLLexer(StringView input)
|
Lexer::Lexer(StringView input)
|
||||||
: m_input(input)
|
: m_input(input)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
char GMLLexer::peek(size_t offset) const
|
char Lexer::peek(size_t offset) const
|
||||||
{
|
{
|
||||||
if ((m_index + offset) >= m_input.length())
|
if ((m_index + offset) >= m_input.length())
|
||||||
return 0;
|
return 0;
|
||||||
return m_input[m_index + offset];
|
return m_input[m_index + offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
char GMLLexer::consume()
|
char Lexer::consume()
|
||||||
{
|
{
|
||||||
VERIFY(m_index < m_input.length());
|
VERIFY(m_index < m_input.length());
|
||||||
char ch = m_input[m_index++];
|
char ch = m_input[m_index++];
|
||||||
|
@ -50,12 +50,12 @@ constexpr bool is_valid_class_character(char ch)
|
||||||
return is_ascii_alphanumeric(ch) || ch == '_' || ch == ':';
|
return is_ascii_alphanumeric(ch) || ch == '_' || ch == ':';
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<GMLToken> GMLLexer::lex()
|
Vector<Token> Lexer::lex()
|
||||||
{
|
{
|
||||||
Vector<GMLToken> tokens;
|
Vector<Token> tokens;
|
||||||
|
|
||||||
size_t token_start_index = 0;
|
size_t token_start_index = 0;
|
||||||
GMLPosition token_start_position;
|
Position token_start_position;
|
||||||
|
|
||||||
auto begin_token = [&] {
|
auto begin_token = [&] {
|
||||||
token_start_index = m_index;
|
token_start_index = m_index;
|
||||||
|
@ -63,7 +63,7 @@ Vector<GMLToken> GMLLexer::lex()
|
||||||
};
|
};
|
||||||
|
|
||||||
auto commit_token = [&](auto type) {
|
auto commit_token = [&](auto type) {
|
||||||
GMLToken token;
|
Token token;
|
||||||
token.m_view = m_input.substring_view(token_start_index, m_index - token_start_index);
|
token.m_view = m_input.substring_view(token_start_index, m_index - token_start_index);
|
||||||
token.m_type = type;
|
token.m_type = type;
|
||||||
token.m_start = token_start_position;
|
token.m_start = token_start_position;
|
||||||
|
@ -74,11 +74,11 @@ Vector<GMLToken> GMLLexer::lex()
|
||||||
auto consume_class = [&] {
|
auto consume_class = [&] {
|
||||||
begin_token();
|
begin_token();
|
||||||
consume();
|
consume();
|
||||||
commit_token(GMLToken::Type::ClassMarker);
|
commit_token(Token::Type::ClassMarker);
|
||||||
begin_token();
|
begin_token();
|
||||||
while (is_valid_class_character(peek()))
|
while (is_valid_class_character(peek()))
|
||||||
consume();
|
consume();
|
||||||
commit_token(GMLToken::Type::ClassName);
|
commit_token(Token::Type::ClassName);
|
||||||
};
|
};
|
||||||
|
|
||||||
while (m_index < m_input.length()) {
|
while (m_index < m_input.length()) {
|
||||||
|
@ -94,21 +94,21 @@ Vector<GMLToken> GMLLexer::lex()
|
||||||
begin_token();
|
begin_token();
|
||||||
while (peek() && peek() != '\n')
|
while (peek() && peek() != '\n')
|
||||||
consume();
|
consume();
|
||||||
commit_token(GMLToken::Type::Comment);
|
commit_token(Token::Type::Comment);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peek(0) == '{') {
|
if (peek(0) == '{') {
|
||||||
begin_token();
|
begin_token();
|
||||||
consume();
|
consume();
|
||||||
commit_token(GMLToken::Type::LeftCurly);
|
commit_token(Token::Type::LeftCurly);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peek(0) == '}') {
|
if (peek(0) == '}') {
|
||||||
begin_token();
|
begin_token();
|
||||||
consume();
|
consume();
|
||||||
commit_token(GMLToken::Type::RightCurly);
|
commit_token(Token::Type::RightCurly);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,14 +122,14 @@ Vector<GMLToken> GMLLexer::lex()
|
||||||
consume();
|
consume();
|
||||||
while (is_valid_identifier_character(peek(0)))
|
while (is_valid_identifier_character(peek(0)))
|
||||||
consume();
|
consume();
|
||||||
commit_token(GMLToken::Type::Identifier);
|
commit_token(Token::Type::Identifier);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peek(0) == ':') {
|
if (peek(0) == ':') {
|
||||||
begin_token();
|
begin_token();
|
||||||
consume();
|
consume();
|
||||||
commit_token(GMLToken::Type::Colon);
|
commit_token(Token::Type::Colon);
|
||||||
|
|
||||||
while (is_ascii_space(peek()))
|
while (is_ascii_space(peek()))
|
||||||
consume();
|
consume();
|
||||||
|
@ -140,13 +140,13 @@ Vector<GMLToken> GMLLexer::lex()
|
||||||
begin_token();
|
begin_token();
|
||||||
while (peek() && peek() != '\n')
|
while (peek() && peek() != '\n')
|
||||||
consume();
|
consume();
|
||||||
commit_token(GMLToken::Type::JsonValue);
|
commit_token(Token::Type::JsonValue);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
consume();
|
consume();
|
||||||
commit_token(GMLToken::Type::Unknown);
|
commit_token(Token::Type::Unknown);
|
||||||
}
|
}
|
||||||
return tokens;
|
return tokens;
|
||||||
}
|
}
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#include <AK/StringView.h>
|
#include <AK/StringView.h>
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI::GML {
|
||||||
|
|
||||||
#define FOR_EACH_TOKEN_TYPE \
|
#define FOR_EACH_TOKEN_TYPE \
|
||||||
__TOKEN(Unknown) \
|
__TOKEN(Unknown) \
|
||||||
|
@ -21,12 +21,12 @@ namespace GUI {
|
||||||
__TOKEN(Colon) \
|
__TOKEN(Colon) \
|
||||||
__TOKEN(JsonValue)
|
__TOKEN(JsonValue)
|
||||||
|
|
||||||
struct GMLPosition {
|
struct Position {
|
||||||
size_t line;
|
size_t line;
|
||||||
size_t column;
|
size_t column;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GMLToken {
|
struct Token {
|
||||||
enum class Type {
|
enum class Type {
|
||||||
#define __TOKEN(x) x,
|
#define __TOKEN(x) x,
|
||||||
FOR_EACH_TOKEN_TYPE
|
FOR_EACH_TOKEN_TYPE
|
||||||
|
@ -47,15 +47,15 @@ struct GMLToken {
|
||||||
|
|
||||||
Type m_type { Type::Unknown };
|
Type m_type { Type::Unknown };
|
||||||
StringView m_view;
|
StringView m_view;
|
||||||
GMLPosition m_start;
|
Position m_start;
|
||||||
GMLPosition m_end;
|
Position m_end;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GMLLexer {
|
class Lexer {
|
||||||
public:
|
public:
|
||||||
GMLLexer(StringView);
|
Lexer(StringView);
|
||||||
|
|
||||||
Vector<GMLToken> lex();
|
Vector<Token> lex();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char peek(size_t offset = 0) const;
|
char peek(size_t offset = 0) const;
|
||||||
|
@ -63,7 +63,7 @@ private:
|
||||||
|
|
||||||
StringView m_input;
|
StringView m_input;
|
||||||
size_t m_index { 0 };
|
size_t m_index { 0 };
|
||||||
GMLPosition m_position { 0, 0 };
|
Position m_position { 0, 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,40 +1,41 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||||
|
* Copyright (c) 2022, kleines Filmröllchen <filmroellchen@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "Parser.h"
|
||||||
|
#include "Lexer.h"
|
||||||
#include <AK/GenericLexer.h>
|
#include <AK/GenericLexer.h>
|
||||||
#include <AK/JsonObject.h>
|
#include <AK/JsonObject.h>
|
||||||
#include <AK/JsonValue.h>
|
#include <AK/JsonValue.h>
|
||||||
#include <AK/Queue.h>
|
#include <AK/Queue.h>
|
||||||
#include <LibGUI/GMLLexer.h>
|
|
||||||
#include <LibGUI/GMLParser.h>
|
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI::GML {
|
||||||
|
|
||||||
static Optional<JsonValue> parse_core_object(Queue<GMLToken>& tokens)
|
static Optional<JsonValue> parse_core_object(Queue<Token>& tokens)
|
||||||
{
|
{
|
||||||
JsonObject object;
|
JsonObject object;
|
||||||
JsonArray children;
|
JsonArray children;
|
||||||
|
|
||||||
auto peek = [&] {
|
auto peek = [&] {
|
||||||
if (tokens.is_empty())
|
if (tokens.is_empty())
|
||||||
return GMLToken::Type::Unknown;
|
return Token::Type::Unknown;
|
||||||
return tokens.head().m_type;
|
return tokens.head().m_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
while (peek() == GMLToken::Type::Comment)
|
while (peek() == Token::Type::Comment)
|
||||||
tokens.dequeue();
|
tokens.dequeue();
|
||||||
|
|
||||||
if (peek() != GMLToken::Type::ClassMarker) {
|
if (peek() != Token::Type::ClassMarker) {
|
||||||
dbgln("Expected class marker");
|
dbgln("Expected class marker");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens.dequeue();
|
tokens.dequeue();
|
||||||
|
|
||||||
if (peek() != GMLToken::Type::ClassName) {
|
if (peek() != Token::Type::ClassName) {
|
||||||
dbgln("Expected class name");
|
dbgln("Expected class name");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -42,19 +43,19 @@ static Optional<JsonValue> parse_core_object(Queue<GMLToken>& tokens)
|
||||||
auto class_name = tokens.dequeue();
|
auto class_name = tokens.dequeue();
|
||||||
object.set("class", JsonValue(class_name.m_view));
|
object.set("class", JsonValue(class_name.m_view));
|
||||||
|
|
||||||
if (peek() != GMLToken::Type::LeftCurly) {
|
if (peek() != Token::Type::LeftCurly) {
|
||||||
// Empty object
|
// Empty object
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
tokens.dequeue();
|
tokens.dequeue();
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (peek() == GMLToken::Type::RightCurly) {
|
if (peek() == Token::Type::RightCurly) {
|
||||||
// End of object
|
// End of object
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peek() == GMLToken::Type::ClassMarker) {
|
if (peek() == Token::Type::ClassMarker) {
|
||||||
// It's a child object.
|
// It's a child object.
|
||||||
auto value = parse_core_object(tokens);
|
auto value = parse_core_object(tokens);
|
||||||
if (!value.has_value()) {
|
if (!value.has_value()) {
|
||||||
|
@ -66,7 +67,7 @@ static Optional<JsonValue> parse_core_object(Queue<GMLToken>& tokens)
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
children.append(value.release_value());
|
children.append(value.release_value());
|
||||||
} else if (peek() == GMLToken::Type::Identifier) {
|
} else if (peek() == Token::Type::Identifier) {
|
||||||
// It's a property.
|
// It's a property.
|
||||||
auto property_name = tokens.dequeue();
|
auto property_name = tokens.dequeue();
|
||||||
|
|
||||||
|
@ -75,14 +76,14 @@ static Optional<JsonValue> parse_core_object(Queue<GMLToken>& tokens)
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peek() != GMLToken::Type::Colon) {
|
if (peek() != Token::Type::Colon) {
|
||||||
dbgln("Expected ':'");
|
dbgln("Expected ':'");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
tokens.dequeue();
|
tokens.dequeue();
|
||||||
|
|
||||||
JsonValue value;
|
JsonValue value;
|
||||||
if (peek() == GMLToken::Type::ClassMarker) {
|
if (peek() == Token::Type::ClassMarker) {
|
||||||
auto parsed_value = parse_core_object(tokens);
|
auto parsed_value = parse_core_object(tokens);
|
||||||
if (!parsed_value.has_value())
|
if (!parsed_value.has_value())
|
||||||
return {};
|
return {};
|
||||||
|
@ -91,7 +92,7 @@ static Optional<JsonValue> parse_core_object(Queue<GMLToken>& tokens)
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
value = parsed_value.release_value();
|
value = parsed_value.release_value();
|
||||||
} else if (peek() == GMLToken::Type::JsonValue) {
|
} else if (peek() == Token::Type::JsonValue) {
|
||||||
auto value_string = tokens.dequeue();
|
auto value_string = tokens.dequeue();
|
||||||
auto parsed_value = JsonValue::from_string(value_string.m_view);
|
auto parsed_value = JsonValue::from_string(value_string.m_view);
|
||||||
if (parsed_value.is_error()) {
|
if (parsed_value.is_error()) {
|
||||||
|
@ -101,7 +102,7 @@ static Optional<JsonValue> parse_core_object(Queue<GMLToken>& tokens)
|
||||||
value = parsed_value.release_value();
|
value = parsed_value.release_value();
|
||||||
}
|
}
|
||||||
object.set(property_name.m_view, move(value));
|
object.set(property_name.m_view, move(value));
|
||||||
} else if (peek() == GMLToken::Type::Comment) {
|
} else if (peek() == Token::Type::Comment) {
|
||||||
tokens.dequeue();
|
tokens.dequeue();
|
||||||
} else {
|
} else {
|
||||||
dbgln("Expected child, property, comment, or }}");
|
dbgln("Expected child, property, comment, or }}");
|
||||||
|
@ -109,7 +110,7 @@ static Optional<JsonValue> parse_core_object(Queue<GMLToken>& tokens)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peek() != GMLToken::Type::RightCurly) {
|
if (peek() != Token::Type::RightCurly) {
|
||||||
dbgln("Expected }}");
|
dbgln("Expected }}");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -123,9 +124,9 @@ static Optional<JsonValue> parse_core_object(Queue<GMLToken>& tokens)
|
||||||
|
|
||||||
JsonValue parse_gml(StringView string)
|
JsonValue parse_gml(StringView string)
|
||||||
{
|
{
|
||||||
auto lexer = GMLLexer(string);
|
auto lexer = Lexer(string);
|
||||||
|
|
||||||
Queue<GMLToken> tokens;
|
Queue<Token> tokens;
|
||||||
for (auto& token : lexer.lex())
|
for (auto& token : lexer.lex())
|
||||||
tokens.enqueue(token);
|
tokens.enqueue(token);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||||
|
* Copyright (c) 2022, kleines Filmröllchen <filmroellchen@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -8,7 +9,7 @@
|
||||||
|
|
||||||
#include <AK/Forward.h>
|
#include <AK/Forward.h>
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI::GML {
|
||||||
|
|
||||||
JsonValue parse_gml(StringView);
|
JsonValue parse_gml(StringView);
|
||||||
|
|
|
@ -4,43 +4,43 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <LibGUI/GMLLexer.h>
|
#include "SyntaxHighlighter.h"
|
||||||
#include <LibGUI/GMLSyntaxHighlighter.h>
|
#include "Lexer.h"
|
||||||
#include <LibGfx/Palette.h>
|
#include <LibGfx/Palette.h>
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI::GML {
|
||||||
|
|
||||||
static Syntax::TextStyle style_for_token_type(const Gfx::Palette& palette, GMLToken::Type type)
|
static Syntax::TextStyle style_for_token_type(const Gfx::Palette& palette, Token::Type type)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case GMLToken::Type::LeftCurly:
|
case Token::Type::LeftCurly:
|
||||||
case GMLToken::Type::RightCurly:
|
case Token::Type::RightCurly:
|
||||||
return { palette.syntax_punctuation() };
|
return { palette.syntax_punctuation() };
|
||||||
case GMLToken::Type::ClassMarker:
|
case Token::Type::ClassMarker:
|
||||||
return { palette.syntax_keyword() };
|
return { palette.syntax_keyword() };
|
||||||
case GMLToken::Type::ClassName:
|
case Token::Type::ClassName:
|
||||||
return { palette.syntax_identifier(), true };
|
return { palette.syntax_identifier(), true };
|
||||||
case GMLToken::Type::Identifier:
|
case Token::Type::Identifier:
|
||||||
return { palette.syntax_identifier() };
|
return { palette.syntax_identifier() };
|
||||||
case GMLToken::Type::JsonValue:
|
case Token::Type::JsonValue:
|
||||||
return { palette.syntax_string() };
|
return { palette.syntax_string() };
|
||||||
case GMLToken::Type::Comment:
|
case Token::Type::Comment:
|
||||||
return { palette.syntax_comment() };
|
return { palette.syntax_comment() };
|
||||||
default:
|
default:
|
||||||
return { palette.base_text() };
|
return { palette.base_text() };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GMLSyntaxHighlighter::is_identifier(u64 token) const
|
bool SyntaxHighlighter::is_identifier(u64 token) const
|
||||||
{
|
{
|
||||||
auto ini_token = static_cast<GUI::GMLToken::Type>(token);
|
auto ini_token = static_cast<Token::Type>(token);
|
||||||
return ini_token == GUI::GMLToken::Type::Identifier;
|
return ini_token == Token::Type::Identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMLSyntaxHighlighter::rehighlight(const Palette& palette)
|
void SyntaxHighlighter::rehighlight(const Palette& palette)
|
||||||
{
|
{
|
||||||
auto text = m_client->get_text();
|
auto text = m_client->get_text();
|
||||||
GMLLexer lexer(text);
|
Lexer lexer(text);
|
||||||
auto tokens = lexer.lex();
|
auto tokens = lexer.lex();
|
||||||
|
|
||||||
Vector<GUI::TextDocumentSpan> spans;
|
Vector<GUI::TextDocumentSpan> spans;
|
||||||
|
@ -63,21 +63,21 @@ void GMLSyntaxHighlighter::rehighlight(const Palette& palette)
|
||||||
m_client->do_update();
|
m_client->do_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<GMLSyntaxHighlighter::MatchingTokenPair> GMLSyntaxHighlighter::matching_token_pairs_impl() const
|
Vector<SyntaxHighlighter::MatchingTokenPair> SyntaxHighlighter::matching_token_pairs_impl() const
|
||||||
{
|
{
|
||||||
static Vector<MatchingTokenPair> pairs;
|
static Vector<MatchingTokenPair> pairs;
|
||||||
if (pairs.is_empty()) {
|
if (pairs.is_empty()) {
|
||||||
pairs.append({ static_cast<u64>(GMLToken::Type::LeftCurly), static_cast<u64>(GMLToken::Type::RightCurly) });
|
pairs.append({ static_cast<u64>(Token::Type::LeftCurly), static_cast<u64>(Token::Type::RightCurly) });
|
||||||
}
|
}
|
||||||
return pairs;
|
return pairs;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GMLSyntaxHighlighter::token_types_equal(u64 token1, u64 token2) const
|
bool SyntaxHighlighter::token_types_equal(u64 token1, u64 token2) const
|
||||||
{
|
{
|
||||||
return static_cast<GUI::GMLToken::Type>(token1) == static_cast<GUI::GMLToken::Type>(token2);
|
return static_cast<Token::Type>(token1) == static_cast<Token::Type>(token2);
|
||||||
}
|
}
|
||||||
|
|
||||||
GMLSyntaxHighlighter::~GMLSyntaxHighlighter()
|
SyntaxHighlighter::~SyntaxHighlighter()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,12 @@
|
||||||
|
|
||||||
#include <LibSyntax/Highlighter.h>
|
#include <LibSyntax/Highlighter.h>
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI::GML {
|
||||||
|
|
||||||
class GMLSyntaxHighlighter final : public Syntax::Highlighter {
|
class SyntaxHighlighter final : public Syntax::Highlighter {
|
||||||
public:
|
public:
|
||||||
GMLSyntaxHighlighter() { }
|
SyntaxHighlighter() { }
|
||||||
virtual ~GMLSyntaxHighlighter() override;
|
virtual ~SyntaxHighlighter() override;
|
||||||
|
|
||||||
virtual bool is_identifier(u64) const override;
|
virtual bool is_identifier(u64) const override;
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include <LibGUI/Application.h>
|
#include <LibGUI/Application.h>
|
||||||
#include <LibGUI/BoxLayout.h>
|
#include <LibGUI/BoxLayout.h>
|
||||||
#include <LibGUI/Event.h>
|
#include <LibGUI/Event.h>
|
||||||
#include <LibGUI/GMLParser.h>
|
#include <LibGUI/GML/Parser.h>
|
||||||
#include <LibGUI/Layout.h>
|
#include <LibGUI/Layout.h>
|
||||||
#include <LibGUI/Menu.h>
|
#include <LibGUI/Menu.h>
|
||||||
#include <LibGUI/Painter.h>
|
#include <LibGUI/Painter.h>
|
||||||
|
@ -1066,7 +1066,7 @@ bool Widget::load_from_gml(StringView gml_string)
|
||||||
|
|
||||||
bool Widget::load_from_gml(StringView gml_string, RefPtr<Core::Object> (*unregistered_child_handler)(const String&))
|
bool Widget::load_from_gml(StringView gml_string, RefPtr<Core::Object> (*unregistered_child_handler)(const String&))
|
||||||
{
|
{
|
||||||
auto value = parse_gml(gml_string);
|
auto value = GML::parse_gml(gml_string);
|
||||||
if (!value.is_object())
|
if (!value.is_object())
|
||||||
return false;
|
return false;
|
||||||
return load_from_json(value.as_object(), unregistered_child_handler);
|
return load_from_json(value.as_object(), unregistered_child_handler);
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include <LibCore/ArgsParser.h>
|
#include <LibCore/ArgsParser.h>
|
||||||
#include <LibCore/File.h>
|
#include <LibCore/File.h>
|
||||||
#include <LibCore/System.h>
|
#include <LibCore/System.h>
|
||||||
#include <LibGUI/GMLFormatter.h>
|
#include <LibGUI/GML/Formatter.h>
|
||||||
#include <LibMain/Main.h>
|
#include <LibMain/Main.h>
|
||||||
|
|
||||||
ErrorOr<bool> format_file(StringView, bool);
|
ErrorOr<bool> format_file(StringView, bool);
|
||||||
|
@ -22,7 +22,8 @@ ErrorOr<bool> format_file(StringView path, bool inplace)
|
||||||
auto open_mode = inplace ? Core::OpenMode::ReadWrite : Core::OpenMode::ReadOnly;
|
auto open_mode = inplace ? Core::OpenMode::ReadWrite : Core::OpenMode::ReadOnly;
|
||||||
file = TRY(Core::File::open(path, open_mode));
|
file = TRY(Core::File::open(path, open_mode));
|
||||||
}
|
}
|
||||||
auto formatted_gml = GUI::format_gml(file->read_all());
|
auto contents = file->read_all();
|
||||||
|
auto formatted_gml = GUI::GML::format_gml(contents);
|
||||||
if (formatted_gml.is_null()) {
|
if (formatted_gml.is_null()) {
|
||||||
warnln("Failed to parse GML!");
|
warnln("Failed to parse GML!");
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue