Skip to content

Commit

Permalink
Used strongly-typed enum for CSS arithmetic operators
Browse files Browse the repository at this point in the history
Current code uses weakly-typed CalcOperator enum for arithmetic
operators, and casts them between chars interchangeably. This
makes it hard to read, and prevents extending the operators with
more math functions.

Hence, this patch changes CalcOperator to a strongly-typed enum,
stops all the direct casting between chars, and renames it to
CSSMathOperator as a preparation to add new math functions.

Bug: 825895
Change-Id: Ie2ea58163f800cf5f480ac34a9c49a3e677e1946
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1680294
Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org>
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#673341}
  • Loading branch information
xiaochengh authored and Commit Bot committed Jun 28, 2019
1 parent 2024a11 commit ee68e30
Show file tree
Hide file tree
Showing 13 changed files with 168 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,8 @@ const CSSValue* LengthInterpolationFunctions::CreateCSSValue(
if (!root_node) {
root_node = CSSCalcValue::CreateExpressionNode(first_value);
}
root_node =
CSSCalcValue::CreateExpressionNode(root_node, current_node, kCalcAdd);
root_node = CSSCalcValue::CreateExpressionNode(root_node, current_node,
CSSMathOperator::kAdd);
}

if (root_node) {
Expand Down
2 changes: 2 additions & 0 deletions third_party/blink/renderer/core/css/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ blink_core_sources("css") {
"css_layout_function_value.h",
"css_markup.cc",
"css_markup.h",
"css_math_operator.cc",
"css_math_operator.h",
"css_media_rule.cc",
"css_media_rule.h",
"css_namespace_rule.cc",
Expand Down
102 changes: 52 additions & 50 deletions third_party/blink/renderer/core/css/css_calculation_value.cc
Original file line number Diff line number Diff line change
Expand Up @@ -272,9 +272,9 @@ class CSSCalcPrimitiveValue final : public CSSCalcExpressionNode {
return nullptr;
}

CalcOperator OperatorType() const override {
CSSMathOperator OperatorType() const override {
NOTREACHED();
return kCalcAdd;
return CSSMathOperator::kInvalid;
}

void Trace(blink::Visitor* visitor) override {
Expand Down Expand Up @@ -328,25 +328,27 @@ static const CalculationCategory kAddSubtractResult[kCalcOther][kCalcOther] = {
static CalculationCategory DetermineCategory(
const CSSCalcExpressionNode& left_side,
const CSSCalcExpressionNode& right_side,
CalcOperator op) {
CSSMathOperator op) {
CalculationCategory left_category = left_side.Category();
CalculationCategory right_category = right_side.Category();

if (left_category == kCalcOther || right_category == kCalcOther)
return kCalcOther;

switch (op) {
case kCalcAdd:
case kCalcSubtract:
case CSSMathOperator::kAdd:
case CSSMathOperator::kSubtract:
return kAddSubtractResult[left_category][right_category];
case kCalcMultiply:
case CSSMathOperator::kMultiply:
if (left_category != kCalcNumber && right_category != kCalcNumber)
return kCalcOther;
return left_category == kCalcNumber ? right_category : left_category;
case kCalcDivide:
case CSSMathOperator::kDivide:
if (right_category != kCalcNumber || right_side.IsZero())
return kCalcOther;
return left_category;
default:
break;
}

NOTREACHED();
Expand All @@ -355,18 +357,19 @@ static CalculationCategory DetermineCategory(

static bool IsIntegerResult(const CSSCalcExpressionNode* left_side,
const CSSCalcExpressionNode* right_side,
CalcOperator op) {
CSSMathOperator op) {
// Not testing for actual integer values.
// Performs W3C spec's type checking for calc integers.
// http://www.w3.org/TR/css3-values/#calc-type-checking
return op != kCalcDivide && left_side->IsInteger() && right_side->IsInteger();
return op != CSSMathOperator::kDivide && left_side->IsInteger() &&
right_side->IsInteger();
}

class CSSCalcBinaryOperation final : public CSSCalcExpressionNode {
public:
static CSSCalcExpressionNode* Create(CSSCalcExpressionNode* left_side,
CSSCalcExpressionNode* right_side,
CalcOperator op) {
CSSMathOperator op) {
DCHECK_NE(left_side->Category(), kCalcOther);
DCHECK_NE(right_side->Category(), kCalcOther);

Expand All @@ -382,7 +385,7 @@ class CSSCalcBinaryOperation final : public CSSCalcExpressionNode {
static CSSCalcExpressionNode* CreateSimplified(
CSSCalcExpressionNode* left_side,
CSSCalcExpressionNode* right_side,
CalcOperator op) {
CSSMathOperator op) {
CalculationCategory left_category = left_side->Category();
CalculationCategory right_category = right_side->Category();
DCHECK_NE(left_category, kCalcOther);
Expand All @@ -399,7 +402,7 @@ class CSSCalcBinaryOperation final : public CSSCalcExpressionNode {
}

// Simplify addition and subtraction between same types.
if (op == kCalcAdd || op == kCalcSubtract) {
if (op == CSSMathOperator::kAdd || op == CSSMathOperator::kSubtract) {
if (left_category == right_side->Category()) {
CSSPrimitiveValue::UnitType left_type =
left_side->TypeWithCalcResolved();
Expand Down Expand Up @@ -437,19 +440,20 @@ class CSSCalcBinaryOperation final : public CSSCalcExpressionNode {
}
} else {
// Simplify multiplying or dividing by a number for simplifiable types.
DCHECK(op == kCalcMultiply || op == kCalcDivide);
DCHECK(op == CSSMathOperator::kMultiply ||
op == CSSMathOperator::kDivide);
CSSCalcExpressionNode* number_side = GetNumberSide(left_side, right_side);
if (!number_side)
return Create(left_side, right_side, op);
if (number_side == left_side && op == kCalcDivide)
if (number_side == left_side && op == CSSMathOperator::kDivide)
return nullptr;
CSSCalcExpressionNode* other_side =
left_side == number_side ? right_side : left_side;

double number = number_side->DoubleValue();
if (std::isnan(number) || std::isinf(number))
return nullptr;
if (op == kCalcDivide && !number)
if (op == CSSMathOperator::kDivide && !number)
return nullptr;

CSSPrimitiveValue::UnitType other_type =
Expand All @@ -465,7 +469,7 @@ class CSSCalcBinaryOperation final : public CSSCalcExpressionNode {

CSSCalcBinaryOperation(CSSCalcExpressionNode* left_side,
CSSCalcExpressionNode* right_side,
CalcOperator op,
CSSMathOperator op,
CalculationCategory category)
: CSSCalcExpressionNode(category,
IsIntegerResult(left_side, right_side, op)),
Expand All @@ -480,19 +484,19 @@ class CSSCalcBinaryOperation final : public CSSCalcExpressionNode {
PixelsAndPercent& value,
float multiplier) const override {
switch (operator_) {
case kCalcAdd:
case CSSMathOperator::kAdd:
left_side_->AccumulatePixelsAndPercent(conversion_data, value,
multiplier);
right_side_->AccumulatePixelsAndPercent(conversion_data, value,
multiplier);
break;
case kCalcSubtract:
case CSSMathOperator::kSubtract:
left_side_->AccumulatePixelsAndPercent(conversion_data, value,
multiplier);
right_side_->AccumulatePixelsAndPercent(conversion_data, value,
-multiplier);
break;
case kCalcMultiply:
case CSSMathOperator::kMultiply:
DCHECK_NE((left_side_->Category() == kCalcNumber),
(right_side_->Category() == kCalcNumber));
if (left_side_->Category() == kCalcNumber)
Expand All @@ -502,7 +506,7 @@ class CSSCalcBinaryOperation final : public CSSCalcExpressionNode {
left_side_->AccumulatePixelsAndPercent(
conversion_data, value, multiplier * right_side_->DoubleValue());
break;
case kCalcDivide:
case CSSMathOperator::kDivide:
DCHECK_EQ(right_side_->Category(), kCalcNumber);
left_side_->AccumulatePixelsAndPercent(
conversion_data, value, multiplier / right_side_->DoubleValue());
Expand All @@ -526,15 +530,15 @@ class CSSCalcBinaryOperation final : public CSSCalcExpressionNode {
void AccumulateLengthArray(CSSLengthArray& length_array,
double multiplier) const override {
switch (operator_) {
case kCalcAdd:
case CSSMathOperator::kAdd:
left_side_->AccumulateLengthArray(length_array, multiplier);
right_side_->AccumulateLengthArray(length_array, multiplier);
break;
case kCalcSubtract:
case CSSMathOperator::kSubtract:
left_side_->AccumulateLengthArray(length_array, multiplier);
right_side_->AccumulateLengthArray(length_array, -multiplier);
break;
case kCalcMultiply:
case CSSMathOperator::kMultiply:
DCHECK_NE((left_side_->Category() == kCalcNumber),
(right_side_->Category() == kCalcNumber));
if (left_side_->Category() == kCalcNumber)
Expand All @@ -544,7 +548,7 @@ class CSSCalcBinaryOperation final : public CSSCalcExpressionNode {
left_side_->AccumulateLengthArray(
length_array, multiplier * right_side_->DoubleValue());
break;
case kCalcDivide:
case CSSMathOperator::kDivide:
DCHECK_EQ(right_side_->Category(), kCalcNumber);
left_side_->AccumulateLengthArray(
length_array, multiplier / right_side_->DoubleValue());
Expand All @@ -556,12 +560,12 @@ class CSSCalcBinaryOperation final : public CSSCalcExpressionNode {

static String BuildCSSText(const String& left_expression,
const String& right_expression,
CalcOperator op) {
CSSMathOperator op) {
StringBuilder result;
result.Append('(');
result.Append(left_expression);
result.Append(' ');
result.Append(static_cast<char>(op));
result.Append(ToString(op));
result.Append(' ');
result.Append(right_expression);
result.Append(')');
Expand Down Expand Up @@ -594,7 +598,7 @@ class CSSCalcBinaryOperation final : public CSSCalcExpressionNode {
return right_side_;
}

CalcOperator OperatorType() const override { return operator_; }
CSSMathOperator OperatorType() const override { return operator_; }

CSSPrimitiveValue::UnitType TypeWithCalcResolved() const override {
switch (category_) {
Expand Down Expand Up @@ -654,25 +658,28 @@ class CSSCalcBinaryOperation final : public CSSCalcExpressionNode {

static double EvaluateOperator(double left_value,
double right_value,
CalcOperator op) {
CSSMathOperator op) {
switch (op) {
case kCalcAdd:
case CSSMathOperator::kAdd:
return clampTo<double>(left_value + right_value);
case kCalcSubtract:
case CSSMathOperator::kSubtract:
return clampTo<double>(left_value - right_value);
case kCalcMultiply:
case CSSMathOperator::kMultiply:
return clampTo<double>(left_value * right_value);
case kCalcDivide:
case CSSMathOperator::kDivide:
if (right_value)
return clampTo<double>(left_value / right_value);
return std::numeric_limits<double>::quiet_NaN();
default:
NOTREACHED();
break;
}
return 0;
}

const Member<CSSCalcExpressionNode> left_side_;
const Member<CSSCalcExpressionNode> right_side_;
const CalcOperator operator_;
const CSSMathOperator operator_;
};

static ParseState CheckDepthAndIndex(int* depth, CSSParserTokenRange tokens) {
Expand All @@ -699,12 +706,6 @@ class CSSCalcExpressionNodeParser {
}

private:
char OperatorValue(const CSSParserToken& token) {
if (token.GetType() == kDelimiterToken)
return token.Delimiter();
return 0;
}

CSSCalcExpressionNode* ParseValue(CSSParserTokenRange& tokens) {
CSSParserToken token = tokens.ConsumeIncludingWhitespace();
if (!(token.GetType() == kNumberToken ||
Expand Down Expand Up @@ -752,18 +753,18 @@ class CSSCalcExpressionNodeParser {
return nullptr;

while (!tokens.AtEnd()) {
char operator_character = OperatorValue(tokens.Peek());
if (operator_character != kCalcMultiply &&
operator_character != kCalcDivide)
CSSMathOperator math_operator = ParseCSSArithmeticOperator(tokens.Peek());
if (math_operator != CSSMathOperator::kMultiply &&
math_operator != CSSMathOperator::kDivide)
break;
tokens.ConsumeIncludingWhitespace();

CSSCalcExpressionNode* rhs = ParseValueTerm(tokens, depth);
if (!rhs)
return nullptr;

result = CSSCalcBinaryOperation::CreateSimplified(
result, rhs, static_cast<CalcOperator>(operator_character));
result =
CSSCalcBinaryOperation::CreateSimplified(result, rhs, math_operator);

if (!result)
return nullptr;
Expand All @@ -784,8 +785,9 @@ class CSSCalcExpressionNodeParser {
return nullptr;

while (!tokens.AtEnd()) {
char operator_character = OperatorValue(tokens.Peek());
if (operator_character != kCalcAdd && operator_character != kCalcSubtract)
CSSMathOperator math_operator = ParseCSSArithmeticOperator(tokens.Peek());
if (math_operator != CSSMathOperator::kAdd &&
math_operator != CSSMathOperator::kSubtract)
break;
if ((&tokens.Peek() - 1)->GetType() != kWhitespaceToken)
return nullptr; // calc(1px+ 2px) is invalid
Expand All @@ -799,8 +801,8 @@ class CSSCalcExpressionNodeParser {
if (!rhs)
return nullptr;

result = CSSCalcBinaryOperation::CreateSimplified(
result, rhs, static_cast<CalcOperator>(operator_character));
result =
CSSCalcBinaryOperation::CreateSimplified(result, rhs, math_operator);

if (!result)
return nullptr;
Expand All @@ -824,7 +826,7 @@ CSSCalcExpressionNode* CSSCalcValue::CreateExpressionNode(
CSSCalcExpressionNode* CSSCalcValue::CreateExpressionNode(
CSSCalcExpressionNode* left_side,
CSSCalcExpressionNode* right_side,
CalcOperator op) {
CSSMathOperator op) {
return CSSCalcBinaryOperation::Create(left_side, right_side, op);
}

Expand All @@ -838,7 +840,7 @@ CSSCalcExpressionNode* CSSCalcValue::CreateExpressionNode(double pixels,
CreateExpressionNode(CSSPrimitiveValue::Create(
pixels, CSSPrimitiveValue::UnitType::kPixels),
pixels == trunc(pixels)),
kCalcAdd);
CSSMathOperator::kAdd);
}

CSSCalcValue* CSSCalcValue::Create(const CSSParserTokenRange& tokens,
Expand Down
12 changes: 3 additions & 9 deletions third_party/blink/renderer/core/css/css_calculation_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_CALCULATION_VALUE_H_

#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/css/css_math_operator.h"
#include "third_party/blink/renderer/core/css/css_primitive_value.h"
#include "third_party/blink/renderer/core/css/css_value.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_token_range.h"
Expand All @@ -42,13 +43,6 @@ namespace blink {

class CalculationValue;

enum CalcOperator {
kCalcAdd = '+',
kCalcSubtract = '-',
kCalcMultiply = '*',
kCalcDivide = '/'
};

// The order of this enum should not change since its elements are used as
// indices in the addSubtractResult matrix.
enum CalculationCategory {
Expand Down Expand Up @@ -84,7 +78,7 @@ class CSSCalcExpressionNode : public GarbageCollected<CSSCalcExpressionNode> {
virtual Type GetType() const = 0;
virtual const CSSCalcExpressionNode* LeftExpressionNode() const = 0;
virtual const CSSCalcExpressionNode* RightExpressionNode() const = 0;
virtual CalcOperator OperatorType() const = 0;
virtual CSSMathOperator OperatorType() const = 0;

CalculationCategory Category() const { return category_; }
virtual CSSPrimitiveValue::UnitType TypeWithCalcResolved() const = 0;
Expand Down Expand Up @@ -116,7 +110,7 @@ class CORE_EXPORT CSSCalcValue : public GarbageCollected<CSSCalcValue> {
bool is_integer = false);
static CSSCalcExpressionNode* CreateExpressionNode(CSSCalcExpressionNode*,
CSSCalcExpressionNode*,
CalcOperator);
CSSMathOperator);
static CSSCalcExpressionNode* CreateExpressionNode(double pixels,
double percent);

Expand Down
Loading

0 comments on commit ee68e30

Please sign in to comment.