Skip to content

Commit d2b3db1

Browse files
committed
Patch division delay (keep slash) with function calls
1 parent a57a66e commit d2b3db1

File tree

3 files changed

+54
-3
lines changed

3 files changed

+54
-3
lines changed

src/ast.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2017,6 +2017,29 @@ namespace Sass {
20172017
return is_interpolant() || (right() && right()->is_right_interpolant());
20182018
}
20192019

2020+
// delay binary expressions in function arguments
2021+
// https://github.com/sass/libsass/issues/1417
2022+
bool Binary_Expression::can_delay(void) const
2023+
{
2024+
bool l_delay = false;
2025+
bool r_delay = false;
2026+
if (op().operand == Sass_OP::DIV) {
2027+
if (Textual* tl = dynamic_cast<Textual*>(left())) {
2028+
l_delay = tl->type() == Textual::NUMBER ||
2029+
tl->type() == Textual::DIMENSION;
2030+
} else {
2031+
l_delay = dynamic_cast<Number*>(left()) != NULL;
2032+
}
2033+
if (Textual* tr = dynamic_cast<Textual*>(right())) {
2034+
r_delay = tr->type() == Textual::NUMBER ||
2035+
tr->type() == Textual::DIMENSION;
2036+
} else {
2037+
r_delay = dynamic_cast<Number*>(right()) != NULL;
2038+
}
2039+
}
2040+
return l_delay && r_delay;
2041+
}
2042+
20202043
std::string AST_Node::to_string(Sass_Inspect_Options opt) const
20212044
{
20222045
Sass_Output_Options out(opt);

src/ast.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,12 @@ namespace Sass {
10111011
return is_left_interpolant() ||
10121012
is_right_interpolant();
10131013
}
1014+
virtual bool can_delay() const;
1015+
void reset_whitespace()
1016+
{
1017+
op_.ws_before = false;
1018+
op_.ws_after = false;
1019+
}
10141020
virtual void set_delayed(bool delayed)
10151021
{
10161022
right()->set_delayed(delayed);

src/eval.cpp

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -832,17 +832,34 @@ namespace Sass {
832832
stm << "Stack depth exceeded max of " << Constants::MaxCallStack;
833833
error(stm.str(), c->pstate(), backtrace());
834834
}
835+
835836
std::string name(Util::normalize_underscores(c->name()));
836837
std::string full_name(name + "[f]");
837838
Arguments* args = c->arguments();
838-
if (full_name != "if[f]") {
839-
args = static_cast<Arguments*>(args->perform(this));
839+
840+
// handle call here if valid arg
841+
// otherwise we eval arguments to early
842+
if (name == "call" && args->length() > 0) {
843+
Expression* redirect = args->at(0)->perform(this);
844+
args->erase(args->begin());
845+
Function_Call* lit = SASS_MEMORY_NEW(ctx.mem, Function_Call,
846+
c->pstate(),
847+
unquote(redirect->to_string()),
848+
args);
849+
return operator()(lit);
840850
}
841851

842852
Env* env = environment();
843853
if (!env->has(full_name)) {
844854
if (!env->has("*[f]")) {
845855
// just pass it through as a literal
856+
for (Argument* arg : *args) {
857+
if (Binary_Expression* b = dynamic_cast<Binary_Expression*>(arg->value())) {
858+
b->reset_whitespace();
859+
arg->is_delayed(b->can_delay()); // delay
860+
}
861+
}
862+
args = static_cast<Arguments*>(args->perform(this));
846863
Function_Call* lit = SASS_MEMORY_NEW(ctx.mem, Function_Call,
847864
c->pstate(),
848865
c->name(),
@@ -861,6 +878,10 @@ namespace Sass {
861878
}
862879
}
863880

881+
if (full_name != "if[f]") {
882+
args = static_cast<Arguments*>(args->perform(this));
883+
}
884+
864885
Definition* def = static_cast<Definition*>((*env)[full_name]);
865886

866887
if (def->is_overload_stub()) {
@@ -1321,7 +1342,8 @@ namespace Sass {
13211342
Expression* Eval::operator()(Argument* a)
13221343
{
13231344
Expression* val = a->value();
1324-
val->is_delayed(false);
1345+
// delay missin function arguments?
1346+
val->is_delayed(a->is_delayed());
13251347
val = val->perform(this);
13261348
val->is_delayed(false);
13271349

0 commit comments

Comments
 (0)