Skip to content

Commit 3de51e9

Browse files
committed
[WIP] [DNM] Backport dart sass parser 15
1 parent 4613f3e commit 3de51e9

27 files changed

+1092
-403
lines changed

src/ast.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ namespace Sass {
236236
virtual const T& at(size_t i) const { return elements_.at(i); }
237237
virtual T& at(size_t i) { return elements_.at(i); }
238238
const T& get(size_t i) const { return elements_[i]; }
239+
// ToDo: might insert am item (update ordered list)
239240
const T& operator[](size_t i) const { return elements_[i]; }
240241

241242
// Implicitly get the std::vector from our object

src/ast_css.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ namespace Sass {
288288

289289
CssMediaQueryObj query = SASS_MEMORY_NEW(CssMediaQuery, pstate());
290290
query->modifier(modifier == ourModifier ? this->modifier() : other->modifier());
291-
query->type(ourType.empty() ? other->type() : this->type());
291+
query->type(type == ourType ? this->type() : other->type());
292292
query->features(features);
293293
return query;
294294
}

src/ast_values.cpp

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ namespace Sass {
7676
}
7777
return true;
7878
}
79+
if (auto m = Cast<Map>(&rhs)) {
80+
return m->empty() && empty();
81+
}
7982
return false;
8083
}
8184

@@ -92,6 +95,20 @@ namespace Sass {
9295
return length();
9396
}
9497

98+
environment_map(ExpressionObj) List::getNormalizedArgMap()
99+
{
100+
environment_map(ExpressionObj) map;
101+
if (is_arglist_) {
102+
for (Expression* item : elements()) {
103+
if (Argument * arg = Cast<Argument>(item)) {
104+
if (arg->name().empty()) continue;
105+
map[arg->name()] = arg->value();
106+
}
107+
}
108+
}
109+
return map;
110+
}
111+
95112

96113
Expression_Obj List::value_at_index(size_t i) {
97114
Expression_Obj obj = this->at(i);
@@ -444,18 +461,44 @@ namespace Sass {
444461
}
445462
// ensure both have same units
446463
l.normalize(); r.normalize();
447-
Units &lhs_unit = l, &rhs_unit = r;
464+
Units& lhs_unit = l, & rhs_unit = r;
448465
if (!(lhs_unit == rhs_unit)) {
449466
/* ToDo: do we always get usefull backtraces? */
450467
throw Exception::IncompatibleUnits(*this, rhs);
451468
}
452469
if (lhs_unit == rhs_unit) {
453470
return l.value() < r.value();
454-
} else {
471+
}
472+
else {
455473
return lhs_unit < rhs_unit;
456474
}
457475
}
458476

477+
bool Number::operator> (const Number& rhs) const
478+
{
479+
// unitless or only having one unit are equivalent (3.4)
480+
// therefore we need to reduce the units beforehand
481+
Number l(*this), r(rhs); l.reduce(); r.reduce();
482+
size_t lhs_units = l.numerators.size() + l.denominators.size();
483+
size_t rhs_units = r.numerators.size() + r.denominators.size();
484+
if (!lhs_units || !rhs_units) {
485+
return l.value() > r.value();
486+
}
487+
// ensure both have same units
488+
l.normalize(); r.normalize();
489+
Units& lhs_unit = l, & rhs_unit = r;
490+
if (!(lhs_unit == rhs_unit)) {
491+
/* ToDo: do we always get usefull backtraces? */
492+
throw Exception::IncompatibleUnits(*this, rhs);
493+
}
494+
if (lhs_unit == rhs_unit) {
495+
return l.value() > r.value();
496+
}
497+
else {
498+
return lhs_unit > rhs_unit;
499+
}
500+
}
501+
459502
/////////////////////////////////////////////////////////////////////////
460503
/////////////////////////////////////////////////////////////////////////
461504

@@ -473,20 +516,6 @@ namespace Sass {
473516
hash_(ptr->hash_)
474517
{ concrete_type(COLOR); }
475518

476-
bool Color::operator== (const Value& rhs) const
477-
{
478-
if (auto r = Cast<Color_RGBA>(&rhs)) {
479-
return *this == *r;
480-
}
481-
else if (auto r = Cast<Color_HSLA>(&rhs)) {
482-
return *this == *r;
483-
}
484-
else if (auto r = Cast<Color>(&rhs)) {
485-
return a_ == r->a();
486-
}
487-
return false;
488-
}
489-
490519
/////////////////////////////////////////////////////////////////////////
491520
/////////////////////////////////////////////////////////////////////////
492521

src/ast_values.hpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include "sass.hpp"
77
#include "ast.hpp"
88

9+
#include "environment.hpp"
10+
911
namespace Sass {
1012

1113
//////////////////////////////////////////////////////////////////////
@@ -85,6 +87,8 @@ namespace Sass {
8587
virtual size_t hash() const override;
8688
virtual size_t size() const;
8789

90+
environment_map(ExpressionObj) getNormalizedArgMap();
91+
8892
virtual bool operator== (const Value& rhs) const override;
8993

9094
ATTACH_COPY_OPERATIONS(List)
@@ -227,6 +231,11 @@ namespace Sass {
227231
std::string type() const override { return "number"; }
228232
static std::string type_name() { return "number"; }
229233

234+
bool hasAsSlash() {
235+
return !lhsAsSlash_.isNull()
236+
&& !rhsAsSlash_.isNull();
237+
}
238+
230239
// cancel out unnecessary units
231240
// result will be in input units
232241
void reduce();
@@ -238,6 +247,7 @@ namespace Sass {
238247
size_t hash() const override;
239248

240249
bool operator< (const Number& rhs) const;
250+
bool operator> (const Number& rhs) const;
241251
bool operator== (const Number& rhs) const;
242252

243253

@@ -263,7 +273,7 @@ namespace Sass {
263273

264274
virtual size_t hash() const override = 0;
265275

266-
bool operator== (const Value& rhs) const override;
276+
virtual bool operator== (const Value& rhs) const override = 0;
267277

268278
virtual Color_RGBA* copyAsRGBA() const = 0;
269279
virtual Color_RGBA* toRGBA() = 0;

src/bind.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ namespace Sass {
6060
msg << "Only " << LP << " ";
6161
msg << (LP == 1 ? "argument" : "arguments");
6262
msg << " allowed, but " << LA << " ";
63-
msg << (LA <= 1 ? "was" : "were");
63+
msg << (LA == 1 ? "was" : "were");
6464
msg << " passed.";
6565
return error(msg.str(), as->pstate(), traces);
6666
}

src/color_maps.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,10 @@ namespace Sass {
631631
{
632632
auto p = colors_to_names->find(key);
633633
if (p != colors_to_names->end()) {
634+
std::string rv = p->second;
635+
// Match dart-sass output
636+
if (rv == "magenta") { return "fuchsia"; }
637+
if (rv == "cyan") { return "aqua"; }
634638
return p->second;
635639
}
636640
return nullptr;

src/context.cpp

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,6 @@ namespace Sass {
668668
{ register_c_function(*this, &global, c_functions[i]); }
669669
// create initial backtrace entry
670670
// create crtp visitor objects
671-
// debug_ast(root);
672671
Expand expand(*this, &global);
673672
// expand._stylesheet = sheet;
674673
expand.plainCss = sheet.plainCss;
@@ -780,25 +779,46 @@ namespace Sass {
780779
void register_built_in_functions(Context& ctx, Env* env)
781780
{
782781
using namespace Functions;
783-
// RGB Functions
784-
register_function(ctx, rgb_sig, rgb, env);
785-
register_overload_stub(ctx, "rgba", env, 4);
782+
register_overload_stub(ctx, "rgb", env, 1);
783+
register_function(ctx, rgb_4_sig, rgb_4, 4, env);
784+
register_function(ctx, rgb_3_sig, rgb_3, 3, env);
785+
register_function(ctx, rgb_2_sig, rgb_2, 2, env);
786+
register_function(ctx, rgb_1_sig, rgb_1, 1, env);
787+
788+
register_overload_stub(ctx, "rgba", env, 1);
786789
register_function(ctx, rgba_4_sig, rgba_4, 4, env);
790+
register_function(ctx, rgba_3_sig, rgba_3, 3, env);
787791
register_function(ctx, rgba_2_sig, rgba_2, 2, env);
792+
register_function(ctx, rgba_1_sig, rgba_1, 1, env);
793+
794+
register_overload_stub(ctx, "hsl", env, 1);
795+
register_function(ctx, hsl_4_sig, hsl_4, 4, env);
796+
register_function(ctx, hsl_3_sig, hsl_3, 3, env);
797+
register_function(ctx, hsl_2_sig, hsl_2, 2, env);
798+
register_function(ctx, hsl_1_sig, hsl_1, 1, env);
799+
800+
register_overload_stub(ctx, "hsla", env, 1);
801+
register_function(ctx, hsla_4_sig, hsla_4, 4, env);
802+
register_function(ctx, hsla_3_sig, hsla_3, 3, env);
803+
register_function(ctx, hsla_2_sig, hsla_2, 2, env);
804+
register_function(ctx, hsla_1_sig, hsla_1, 1, env);
805+
806+
register_overload_stub(ctx, "saturate", env, 2);
807+
register_function(ctx, saturate_1_sig, saturate_1, 1, env);
808+
register_function(ctx, saturate_2_sig, saturate_2, 2, env);
809+
810+
// RGB Functions
788811
register_function(ctx, red_sig, red, env);
789812
register_function(ctx, green_sig, green, env);
790813
register_function(ctx, blue_sig, blue, env);
791814
register_function(ctx, mix_sig, mix, env);
792815
// HSL Functions
793-
register_function(ctx, hsl_sig, hsl, env);
794-
register_function(ctx, hsla_sig, hsla, env);
795816
register_function(ctx, hue_sig, hue, env);
796817
register_function(ctx, saturation_sig, saturation, env);
797818
register_function(ctx, lightness_sig, lightness, env);
798819
register_function(ctx, adjust_hue_sig, adjust_hue, env);
799820
register_function(ctx, lighten_sig, lighten, env);
800821
register_function(ctx, darken_sig, darken, env);
801-
register_function(ctx, saturate_sig, saturate, env);
802822
register_function(ctx, desaturate_sig, desaturate, env);
803823
register_function(ctx, grayscale_sig, grayscale, env);
804824
register_function(ctx, complement_sig, complement, env);

src/error_handling.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ namespace Sass {
2626
InvalidParent::InvalidParent(Selector* parent, Backtraces traces, Selector* selector)
2727
: Base(selector->pstate(), def_msg, traces), parent(parent), selector(selector)
2828
{
29-
msg = "Invalid parent selector for "
30-
"\"" + selector->to_string(Sass_Inspect_Options()) + "\": "
31-
"\"" + parent->to_string(Sass_Inspect_Options()) + "\"";
29+
msg = "Parent "
30+
// "\"" + selector->to_string(Sass_Inspect_Options()) + "\": "
31+
"\"" + parent->to_string(Sass_Inspect_Options()) + "\""
32+
" is incompatible with this selector.";
3233
}
3334

3435
InvalidVarKwdType::InvalidVarKwdType(ParserState pstate, Backtraces traces, std::string name, const Argument* arg)
@@ -69,13 +70,14 @@ namespace Sass {
6970
DuplicateKeyError::DuplicateKeyError(Backtraces traces, const Map& dup, const Expression& org)
7071
: Base(org.pstate(), def_msg, traces), dup(dup), org(org)
7172
{
72-
msg = "Duplicate key " + dup.get_duplicate_key()->inspect() + " in map (" + org.inspect() + ").";
73+
// msg = "Duplicate key " + dup.get_duplicate_key()->inspect() + " in map (" + org.inspect() + ").";
74+
msg = "Duplicate key."; // dart-sass keeps it simple ...
7375
}
7476

7577
TypeMismatch::TypeMismatch(Backtraces traces, const Expression& var, const std::string type)
7678
: Base(var.pstate(), def_msg, traces), var(var), type(type)
7779
{
78-
msg = var.to_string() + " is not an " + type + ".";
80+
msg = var.to_string() + " is not " + type + ".";
7981
}
8082

8183
InvalidValue::InvalidValue(Backtraces traces, const Expression& val)

src/eval.cpp

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -190,20 +190,20 @@ namespace Sass {
190190
Expression_Obj low = f->lower_bound()->perform(this);
191191
if (low->concrete_type() != Expression::NUMBER) {
192192
traces.push_back(Backtrace(low->pstate()));
193-
throw Exception::TypeMismatch(traces, *low, "integer");
193+
throw Exception::TypeMismatch(traces, *low, "a number");
194194
}
195195
Expression_Obj high = f->upper_bound()->perform(this);
196196
if (high->concrete_type() != Expression::NUMBER) {
197197
traces.push_back(Backtrace(high->pstate()));
198-
throw Exception::TypeMismatch(traces, *high, "integer");
198+
throw Exception::TypeMismatch(traces, *high, "a number");
199199
}
200200
Number_Obj sass_start = Cast<Number>(low);
201201
Number_Obj sass_end = Cast<Number>(high);
202202
// check if units are valid for sequence
203203
if (sass_start->unit() != sass_end->unit()) {
204-
std::stringstream msg; msg << "Incompatible units: '"
205-
<< sass_end->unit() << "' and '"
206-
<< sass_start->unit() << "'.";
204+
std::stringstream msg; msg << "Incompatible units "
205+
<< sass_start->unit() << " and "
206+
<< sass_end->unit() << ".";
207207
error(msg.str(), low->pstate(), traces);
208208
}
209209
double start = sass_start->value();
@@ -294,15 +294,12 @@ namespace Sass {
294294
if (Argument* arg = Cast<Argument>(item)) item = arg->value();
295295
// check if we got passed a list of args (investigate)
296296
if (List* scalars = Cast<List>(item)) {
297-
// debug_ast(scalars);
298297
if (variables.size() == 1) {
299298
Expression* var = scalars;
300299
env.set_local(variables[0], var);
301300
} else {
302301
// XXX: this is never hit via spec tests
303-
// std::cerr << "qweqwe";
304302
for (size_t j = 0, K = variables.size(); j < K; ++j) {
305-
// std::cerr << "set next item\n";
306303
Expression* res = j >= scalars->length()
307304
? SASS_MEMORY_NEW(Null, expr->pstate())
308305
: scalars->at(j);
@@ -1008,6 +1005,10 @@ namespace Sass {
10081005
std::string plain(itpl->getPlainString());
10091006
if (plain.empty()) {
10101007
std::string evaluated_name(interpolationToValue(itpl, true, true));
1008+
if (!c->arguments()->empty()) {
1009+
Argument* arg = c->arguments()->last();
1010+
arg->is_rest_argument(false);
1011+
}
10111012
Expression_Obj evaluated_args = c->arguments()->perform(this);
10121013
std::string str(evaluated_name);
10131014
str += evaluated_args->to_string();
@@ -1024,21 +1025,23 @@ namespace Sass {
10241025
Arguments_Obj args = c->arguments();
10251026

10261027
Env* env = environment();
1027-
if (!env->has(full_name) /* || (!c->via_call() && Prelexer::re_special_fun(name.c_str()))*/) {
1028+
if (!c->func() && !env->has(full_name) /* || (!c->via_call() && Prelexer::re_special_fun(name.c_str()))*/) {
10281029
if (!env->has("*[f]")) {
10291030
for (Argument_Obj arg : args->elements()) {
10301031
if (List_Obj ls = Cast<List>(arg->value())) {
10311032
if (ls->size() == 0) error("() isn't a valid CSS value.", c->pstate(), traces);
10321033
}
10331034
}
10341035
args = Cast<Arguments>(args->perform(this));
1036+
if (!args->empty()) args->last()->is_rest_argument(false);
10351037
FunctionExpressionObj lit = SASS_MEMORY_NEW(FunctionExpression,
10361038
c->pstate(),
10371039
c->name(),
10381040
args,
10391041
c->ns());
10401042
if (args->hasNamedArgument()) {
1041-
error("Plain CSS function " + c->name() + " doesn't support keyword arguments", c->pstate(), traces);
1043+
// error("Plain CSS function " + c->name() + " doesn't support keyword arguments", c->pstate(), traces);
1044+
error("Plain CSS functions don't support keyword arguments.", c->pstate(), traces);
10421045
}
10431046
String_Quoted* str = SASS_MEMORY_NEW(String_Quoted,
10441047
c->pstate(),
@@ -1085,7 +1088,7 @@ namespace Sass {
10851088
msg << "Only " << LP << " ";
10861089
msg << (LP == 1 ? "argument" : "arguments");
10871090
msg << " allowed, but " << L << " ";
1088-
msg << (L <= 1 ? "was" : "were");
1091+
msg << (L == 1 ? "was" : "were");
10891092
msg << " passed.";
10901093
error(msg.str(), c->pstate(), traces);
10911094
}
@@ -1207,13 +1210,12 @@ namespace Sass {
12071210

12081211
Expression* Eval::operator()(Variable* v)
12091212
{
1210-
// return SASS_MEMORY_NEW(Number, "", 1);
12111213
Expression_Obj value;
12121214
Env* env = environment();
12131215
std::string name(v->name());
12141216
EnvResult rv(env->find(name));
12151217
if (rv.found) value = static_cast<Expression*>(rv.it->second.ptr());
1216-
else error("Undefined variable: \"" + v->name() + "\".", v->pstate(), traces);
1218+
else error("Undefined variable.", v->pstate(), traces);
12171219
if (Argument* arg = Cast<Argument>(value)) value = arg->value();
12181220

12191221
if (Number * nr = Cast<Number>(value)) {
@@ -1464,8 +1466,6 @@ namespace Sass {
14641466
feature = (feature ? feature->perform(this) : 0);
14651467
Expression_Obj value = e->value();
14661468
value = (value ? value->perform(this) : 0);
1467-
// if (feature) std::cerr << "feature: [" << feature->to_string() << "]\n";
1468-
// if (value) std::cerr << "value: [" << value->to_string() << "]\n";
14691469
Expression* ee = SASS_MEMORY_NEW(At_Root_Query,
14701470
e->pstate(),
14711471
Cast<String>(feature),
@@ -1480,7 +1480,6 @@ namespace Sass {
14801480

14811481
Expression* Eval::operator()(Argument* a)
14821482
{
1483-
// std::cerr << "EVAL ARGUMENT\n";
14841483
Expression_Obj val = a->value()->perform(this);
14851484
bool is_rest_argument = a->is_rest_argument();
14861485
bool is_keyword_argument = a->is_keyword_argument();

0 commit comments

Comments
 (0)