Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,15 @@ constexpr std::optional<CSSColor> parseRgbFunction(CSSSyntaxParser& parser) {
if (std::holds_alternative<CSSNumber>(firstValue)) {
redNumber = std::get<CSSNumber>(firstValue).value;

auto green = parseNextCSSValue<CSSNumber>(
parser, CSSComponentValueDelimiter::CommaOrWhitespace);
auto green =
parseNextCSSValue<CSSNumber>(parser, CSSDelimiter::CommaOrWhitespace);
if (!std::holds_alternative<CSSNumber>(green)) {
return {};
}
greenNumber = std::get<CSSNumber>(green).value;

auto blue = parseNextCSSValue<CSSNumber>(
parser, CSSComponentValueDelimiter::CommaOrWhitespace);
auto blue =
parseNextCSSValue<CSSNumber>(parser, CSSDelimiter::CommaOrWhitespace);
if (!std::holds_alternative<CSSNumber>(blue)) {
return {};
}
Expand All @@ -70,31 +70,22 @@ constexpr std::optional<CSSColor> parseRgbFunction(CSSSyntaxParser& parser) {
redNumber = std::get<CSSPercentage>(firstValue).value * 2.55f;

auto green = parseNextCSSValue<CSSPercentage>(
parser, CSSComponentValueDelimiter::CommaOrWhitespace);
parser, CSSDelimiter::CommaOrWhitespace);
if (!std::holds_alternative<CSSPercentage>(green)) {
return {};
}
greenNumber = std::get<CSSPercentage>(green).value * 2.55f;

auto blue = parseNextCSSValue<CSSPercentage>(
parser, CSSComponentValueDelimiter::CommaOrWhitespace);
parser, CSSDelimiter::CommaOrWhitespace);
if (!std::holds_alternative<CSSPercentage>(blue)) {
return {};
}
blueNumber = std::get<CSSPercentage>(blue).value * 2.55f;
}

auto alphaValue = peekNextCSSValue<CSSNumber, CSSPercentage>(
parser, CSSComponentValueDelimiter::CommaOrWhitespace);
if (!std::holds_alternative<std::monostate>(alphaValue)) {
parser.consumeComponentValue(CSSComponentValueDelimiter::CommaOrWhitespace);
} else {
alphaValue = peekNextCSSValue<CSSNumber, CSSPercentage>(
parser, CSSComponentValueDelimiter::Solidus);
if (!std::holds_alternative<std::monostate>(alphaValue)) {
parser.consumeComponentValue(CSSComponentValueDelimiter::Solidus);
}
}
auto alphaValue = parseNextCSSValue<CSSNumber, CSSPercentage>(
parser, CSSDelimiter::CommaOrWhitespaceOrSolidus);

float alphaNumber = std::holds_alternative<std::monostate>(alphaValue) ? 1.0f
: std::holds_alternative<CSSNumber>(alphaValue)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ struct CSSDataTypeParser<CSSRatio> {
if (isValidRatioPart(token.numericValue())) {
float numerator = token.numericValue();

auto denominator = peekNextCSSValue<CSSNumber>(
parser, CSSComponentValueDelimiter::Solidus);
auto denominator =
peekNextCSSValue<CSSNumber>(parser, CSSDelimiter::Solidus);
if (std::holds_alternative<CSSNumber>(denominator) &&
isValidRatioPart(std::get<CSSNumber>(denominator).value)) {
parser.consumeComponentValue(CSSComponentValueDelimiter::Solidus);
parser.consumeComponentValue(CSSDelimiter::Solidus);
return CSSRatio{numerator, std::get<CSSNumber>(denominator).value};
}

Expand Down
112 changes: 69 additions & 43 deletions packages/react-native/ReactCommon/react/renderer/css/CSSSyntaxParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,13 @@ concept CSSUniqueComponentValueVisitors =
/**
* Describes the delimeter to expect before the next component value.
*/
enum class CSSComponentValueDelimiter {
Comma,
enum class CSSDelimiter {
Whitespace,
CommaOrWhitespace,
OptionalWhitespace,
Solidus,
Comma,
CommaOrWhitespace,
CommaOrWhitespaceOrSolidus,
None,
};

Expand Down Expand Up @@ -142,7 +144,7 @@ class CSSSyntaxParser {
*/
template <typename ReturnT = std::nullptr_t>
constexpr ReturnT consumeComponentValue(
CSSComponentValueDelimiter delimiter,
CSSDelimiter delimiter,
const CSSComponentValueVisitor<ReturnT> auto&... visitors)
requires(CSSUniqueComponentValueVisitors<ReturnT, decltype(visitors)...>);

Expand Down Expand Up @@ -172,7 +174,7 @@ class CSSSyntaxParser {
*/
template <typename ReturnT = std::nullptr_t>
constexpr ReturnT peekComponentValue(
CSSComponentValueDelimiter delimiter,
CSSDelimiter delimiter,
const CSSComponentValueVisitor<ReturnT> auto&... visitors)
requires(CSSUniqueComponentValueVisitors<ReturnT, decltype(visitors)...>);

Expand Down Expand Up @@ -229,38 +231,10 @@ struct CSSComponentValueVisitorDispatcher {
CSSSyntaxParser& parser;

constexpr ReturnT consumeComponentValue(
CSSComponentValueDelimiter delimiter,
CSSDelimiter delimiter,
const VisitorsT&... visitors) {
switch (delimiter) {
case CSSComponentValueDelimiter::Comma:
parser.consumeWhitespace();
if (parser.peek().type() != CSSTokenType::Comma) {
return ReturnT{};
}
parser.consumeToken();
parser.consumeWhitespace();
break;
case CSSComponentValueDelimiter::Whitespace:
parser.consumeWhitespace();
break;
case CSSComponentValueDelimiter::CommaOrWhitespace:
parser.consumeWhitespace();
if (parser.peek().type() == CSSTokenType::Comma) {
parser.consumeToken();
}
parser.consumeWhitespace();
break;
case CSSComponentValueDelimiter::Solidus:
parser.consumeWhitespace();
if (parser.peek().type() != CSSTokenType::Delim ||
parser.peek().stringValue() != "/") {
return ReturnT{};
}
parser.consumeToken();
parser.consumeWhitespace();
break;
case CSSComponentValueDelimiter::None:
break;
if (!consumeDelimiter(delimiter)) {
return {};
}

if (parser.peek().type() == parser.terminator_) {
Expand Down Expand Up @@ -301,8 +275,62 @@ struct CSSComponentValueVisitorDispatcher {
return ReturnT{};
}

/**
* Consume a delimiter, returning false if a required delimiter is not found.
*/
constexpr bool consumeDelimiter(CSSDelimiter delimiter) {
if (delimiter == CSSDelimiter::None) {
return true;
}

bool hasWhiteSpace = parser.peek().type() == CSSTokenType::WhiteSpace;
parser.consumeWhitespace();

switch (delimiter) {
case CSSDelimiter::Comma:
if (parser.peek().type() == CSSTokenType::Comma) {
parser.consumeToken();
parser.consumeWhitespace();
return true;
}
return false;
case CSSDelimiter::Whitespace:
return hasWhiteSpace;
case CSSDelimiter::OptionalWhitespace:
return true;
case CSSDelimiter::CommaOrWhitespace:
if (parser.peek().type() == CSSTokenType::Comma) {
parser.consumeToken();
parser.consumeWhitespace();
return true;
}
return hasWhiteSpace;
case CSSDelimiter::Solidus:
if (parser.peek().type() == CSSTokenType::Delim &&
parser.peek().stringValue() == "/") {
parser.consumeToken();
parser.consumeWhitespace();
return true;
}
return false;
case CSSDelimiter::CommaOrWhitespaceOrSolidus:
if (parser.peek().type() == CSSTokenType::Comma ||
(parser.peek().type() == CSSTokenType::Delim &&
parser.peek().stringValue() == "/")) {
parser.consumeToken();
parser.consumeWhitespace();
return true;
}
return hasWhiteSpace;
case CSSDelimiter::None:
return true;
}

return false;
}

constexpr ReturnT peekComponentValue(
CSSComponentValueDelimiter delimiter,
CSSDelimiter delimiter,
const VisitorsT&... visitors) {
auto originalParser = parser;
auto ret = consumeComponentValue(delimiter, visitors...);
Expand Down Expand Up @@ -393,7 +421,7 @@ struct CSSComponentValueVisitorDispatcher {

template <typename ReturnT>
constexpr ReturnT CSSSyntaxParser::consumeComponentValue(
CSSComponentValueDelimiter delimiter,
CSSDelimiter delimiter,
const CSSComponentValueVisitor<ReturnT> auto&... visitors)
requires(CSSUniqueComponentValueVisitors<ReturnT, decltype(visitors)...>)
{
Expand All @@ -407,13 +435,12 @@ constexpr ReturnT CSSSyntaxParser::consumeComponentValue(
const CSSComponentValueVisitor<ReturnT> auto&... visitors)
requires(CSSUniqueComponentValueVisitors<ReturnT, decltype(visitors)...>)
{
return consumeComponentValue<ReturnT>(
CSSComponentValueDelimiter::None, visitors...);
return consumeComponentValue<ReturnT>(CSSDelimiter::None, visitors...);
}

template <typename ReturnT>
constexpr ReturnT CSSSyntaxParser::peekComponentValue(
CSSComponentValueDelimiter delimiter,
CSSDelimiter delimiter,
const CSSComponentValueVisitor<ReturnT> auto&... visitors)
requires(CSSUniqueComponentValueVisitors<ReturnT, decltype(visitors)...>)
{
Expand All @@ -427,8 +454,7 @@ constexpr ReturnT CSSSyntaxParser::peekComponentValue(
const CSSComponentValueVisitor<ReturnT> auto&... visitors)
requires(CSSUniqueComponentValueVisitors<ReturnT, decltype(visitors)...>)
{
return peekComponentValue<ReturnT>(
CSSComponentValueDelimiter::None, visitors...);
return peekComponentValue<ReturnT>(CSSDelimiter::None, visitors...);
}

} // namespace facebook::react
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class CSSValueParser {
*/
template <CSSDataType... AllowedTypesT>
constexpr std::variant<std::monostate, AllowedTypesT...> consumeValue(
CSSComponentValueDelimiter delimeter = CSSComponentValueDelimiter::None) {
CSSDelimiter delimeter = CSSDelimiter::None) {
using ReturnT = std::variant<std::monostate, AllowedTypesT...>;

return parser_.consumeComponentValue<ReturnT>(
Expand Down Expand Up @@ -174,7 +174,7 @@ constexpr auto parseCSSProperty(std::string_view css)
template <CSSDataType... AllowedTypesT>
constexpr auto parseNextCSSValue(
CSSSyntaxParser& syntaxParser,
CSSComponentValueDelimiter delimeter = CSSComponentValueDelimiter::None)
CSSDelimiter delimeter = CSSDelimiter::None)
-> std::variant<std::monostate, AllowedTypesT...> {
detail::CSSValueParser valueParser(syntaxParser);
return valueParser.consumeValue<AllowedTypesT...>(delimeter);
Expand All @@ -187,7 +187,7 @@ constexpr auto parseNextCSSValue(
template <CSSDataType... AllowedTypesT>
constexpr auto peekNextCSSValue(
CSSSyntaxParser& syntaxParser,
CSSComponentValueDelimiter delimeter = CSSComponentValueDelimiter::None)
CSSDelimiter delimeter = CSSDelimiter::None)
-> std::variant<std::monostate, AllowedTypesT...> {
auto savedParser = syntaxParser;
detail::CSSValueParser valueParser(syntaxParser);
Expand Down
Loading
Loading