From 8ce38fddd9cf1366fde86dfad7b8a33e744b3c3d Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Tue, 27 Sep 2022 16:05:57 +0100 Subject: [PATCH] LibWeb: Move CSS TokenStream to its own file This lets us use TokenStream in StyleComputer without every user of StyleComputer pulling in the entire CSS Parser. --- .../Libraries/LibWeb/CSS/Parser/Parser.cpp | 81 ---------- Userland/Libraries/LibWeb/CSS/Parser/Parser.h | 66 +-------- .../Libraries/LibWeb/CSS/Parser/TokenStream.h | 139 ++++++++++++++++++ 3 files changed, 140 insertions(+), 146 deletions(-) create mode 100644 Userland/Libraries/LibWeb/CSS/Parser/TokenStream.h diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 3705c5cb3e..c9df4f7fbc 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -81,87 +81,6 @@ AK::URL ParsingContext::complete_url(String const& addr) const return m_url.complete_url(addr); } -template -TokenStream::TokenStream(Vector const& tokens) - : m_tokens(tokens) - , m_eof(make_eof()) -{ -} - -template -bool TokenStream::has_next_token() -{ - return (size_t)(m_iterator_offset + 1) < m_tokens.size(); -} - -template -T const& TokenStream::peek_token(int offset) -{ - if (!has_next_token()) - return m_eof; - - return m_tokens.at(m_iterator_offset + offset + 1); -} - -template -T const& TokenStream::next_token() -{ - if (!has_next_token()) - return m_eof; - - ++m_iterator_offset; - - return m_tokens.at(m_iterator_offset); -} - -template -T const& TokenStream::current_token() -{ - if ((size_t)m_iterator_offset >= m_tokens.size()) - return m_eof; - - return m_tokens.at(m_iterator_offset); -} - -template -void TokenStream::reconsume_current_input_token() -{ - if (m_iterator_offset >= 0) - --m_iterator_offset; -} - -template -void TokenStream::skip_whitespace() -{ - while (peek_token().is(Token::Type::Whitespace)) - next_token(); -} - -template<> -Token TokenStream::make_eof() -{ - return Tokenizer::create_eof_token(); -} - -template<> -ComponentValue TokenStream::make_eof() -{ - return ComponentValue(Tokenizer::create_eof_token()); -} - -template -void TokenStream::dump_all_tokens() -{ - dbgln("Dumping all tokens:"); - for (size_t i = 0; i < m_tokens.size(); ++i) { - auto& token = m_tokens[i]; - if ((i - 1) == (size_t)m_iterator_offset) - dbgln("-> {}", token.to_debug_string()); - else - dbgln(" {}", token.to_debug_string()); - } -} - Parser::Parser(ParsingContext const& context, StringView input, String const& encoding) : m_context(context) , m_tokenizer(input, encoding) diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index 61acf39ffc..7b5b97343f 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -56,71 +57,6 @@ private: AK::URL m_url; }; -template -class TokenStream { -public: - class StateTransaction { - public: - explicit StateTransaction(TokenStream& token_stream) - : m_token_stream(token_stream) - , m_saved_iterator_offset(token_stream.m_iterator_offset) - { - } - - ~StateTransaction() - { - if (!m_commit) - m_token_stream.m_iterator_offset = m_saved_iterator_offset; - } - - StateTransaction create_child() { return StateTransaction(*this); } - - void commit() - { - m_commit = true; - if (m_parent) - m_parent->commit(); - } - - private: - explicit StateTransaction(StateTransaction& parent) - : m_parent(&parent) - , m_token_stream(parent.m_token_stream) - , m_saved_iterator_offset(parent.m_token_stream.m_iterator_offset) - { - } - - StateTransaction* m_parent { nullptr }; - TokenStream& m_token_stream; - int m_saved_iterator_offset { 0 }; - bool m_commit { false }; - }; - - explicit TokenStream(Vector const&); - ~TokenStream() = default; - - TokenStream(TokenStream const&) = delete; - - bool has_next_token(); - T const& next_token(); - T const& peek_token(int offset = 0); - T const& current_token(); - void reconsume_current_input_token(); - - StateTransaction begin_transaction() { return StateTransaction(*this); } - - void skip_whitespace(); - - void dump_all_tokens(); - -private: - Vector const& m_tokens; - int m_iterator_offset { -1 }; - - T make_eof(); - T m_eof; -}; - class Parser { public: Parser(ParsingContext const&, StringView input, String const& encoding = "utf-8"); diff --git a/Userland/Libraries/LibWeb/CSS/Parser/TokenStream.h b/Userland/Libraries/LibWeb/CSS/Parser/TokenStream.h new file mode 100644 index 0000000000..b4800dc9aa --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/Parser/TokenStream.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2020-2021, the SerenityOS developers. + * Copyright (c) 2021-2022, Sam Atkins + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include + +namespace Web::CSS::Parser { + +template +class TokenStream { +public: + class StateTransaction { + public: + explicit StateTransaction(TokenStream& token_stream) + : m_token_stream(token_stream) + , m_saved_iterator_offset(token_stream.m_iterator_offset) + { + } + + ~StateTransaction() + { + if (!m_commit) + m_token_stream.m_iterator_offset = m_saved_iterator_offset; + } + + StateTransaction create_child() { return StateTransaction(*this); } + + void commit() + { + m_commit = true; + if (m_parent) + m_parent->commit(); + } + + private: + explicit StateTransaction(StateTransaction& parent) + : m_parent(&parent) + , m_token_stream(parent.m_token_stream) + , m_saved_iterator_offset(parent.m_token_stream.m_iterator_offset) + { + } + + StateTransaction* m_parent { nullptr }; + TokenStream& m_token_stream; + int m_saved_iterator_offset { 0 }; + bool m_commit { false }; + }; + + explicit TokenStream(Vector const& tokens) + : m_tokens(tokens) + , m_eof(make_eof()) + { + } + TokenStream(TokenStream const&) = delete; + + ~TokenStream() = default; + + bool has_next_token() + { + return (size_t)(m_iterator_offset + 1) < m_tokens.size(); + } + + T const& next_token() + { + if (!has_next_token()) + return m_eof; + + ++m_iterator_offset; + + return m_tokens.at(m_iterator_offset); + } + + T const& peek_token(int offset = 0) + { + if (!has_next_token()) + return m_eof; + + return m_tokens.at(m_iterator_offset + offset + 1); + } + + T const& current_token() + { + if ((size_t)m_iterator_offset >= m_tokens.size()) + return m_eof; + + return m_tokens.at(m_iterator_offset); + } + + void reconsume_current_input_token() + { + if (m_iterator_offset >= 0) + --m_iterator_offset; + } + + StateTransaction begin_transaction() { return StateTransaction(*this); } + + void skip_whitespace() + { + while (peek_token().is(Token::Type::Whitespace)) + next_token(); + } + + void dump_all_tokens() + { + dbgln("Dumping all tokens:"); + for (size_t i = 0; i < m_tokens.size(); ++i) { + auto& token = m_tokens[i]; + if ((i - 1) == (size_t)m_iterator_offset) + dbgln("-> {}", token.to_debug_string()); + else + dbgln(" {}", token.to_debug_string()); + } + } + +private: + Vector const& m_tokens; + int m_iterator_offset { -1 }; + + T make_eof() + { + if constexpr (IsSame) { + return Tokenizer::create_eof_token(); + } + if constexpr (IsSame) { + return ComponentValue(Tokenizer::create_eof_token()); + } + } + + T m_eof; +}; + +}