Skip to content

Commit 2d28ac5

Browse files
committed
Merge pull request #2028 from mgreter/bugfix/issue_1706
Fix parsing of calc function invocations
2 parents 7889f8c + cf85639 commit 2d28ac5

File tree

8 files changed

+29
-14
lines changed

8 files changed

+29
-14
lines changed

src/constants.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,6 @@ namespace Sass {
8888
extern const char progid_kwd[] = "progid";
8989
extern const char expression_kwd[] = "expression";
9090
extern const char calc_fn_kwd[] = "calc";
91-
extern const char calc_kwd[] = "calc(";
92-
extern const char moz_calc_kwd[] = "-moz-calc(";
93-
extern const char webkit_calc_kwd[] = "-webkit-calc(";
94-
extern const char ms_calc_kwd[] = "-ms-calc(";
9591

9692
// css selector keywords
9793
extern const char sel_deep_kwd[] = "/deep/";

src/constants.hpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,7 @@ namespace Sass {
8787
extern const char odd_kwd[];
8888
extern const char progid_kwd[];
8989
extern const char expression_kwd[];
90-
extern const char calc_kwd[];
9190
extern const char calc_fn_kwd[];
92-
extern const char moz_calc_kwd[];
93-
extern const char webkit_calc_kwd[];
94-
extern const char ms_calc_kwd[];
9591

9692
// css selector keywords
9793
extern const char sel_deep_kwd[];

src/expand.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,7 @@ namespace Sass {
652652
(d->type() == Definition::MIXIN ? "[m]" : "[f]")] = dd;
653653

654654
if (d->type() == Definition::FUNCTION && (
655-
d->name() == "calc" ||
655+
Prelexer::calc_fn_call(d->name().c_str()) ||
656656
d->name() == "element" ||
657657
d->name() == "expression" ||
658658
d->name() == "url"

src/lexer.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,15 @@ namespace Sass {
121121
const char* xdigit(const char* src) { return is_xdigit(*src) ? src + 1 : 0; }
122122
const char* alnum(const char* src) { return is_alnum(*src) ? src + 1 : 0; }
123123
const char* punct(const char* src) { return is_punct(*src) ? src + 1 : 0; }
124+
const char* hyphen(const char* src) { return *src && *src == '-' ? src + 1 : 0; }
124125
const char* character(const char* src) { return is_character(*src) ? src + 1 : 0; }
125126
const char* uri_character(const char* src) { return is_uri_character(*src) ? src + 1 : 0; }
126127
const char* escapable_character(const char* src) { return is_escapable_character(*src) ? src + 1 : 0; }
127128

128129
// Match multiple ctype characters.
129130
const char* spaces(const char* src) { return one_plus<space>(src); }
130131
const char* digits(const char* src) { return one_plus<digit>(src); }
132+
const char* hyphens(const char* src) { return one_plus<hyphen>(src); }
131133

132134
// Whitespace handling.
133135
const char* no_spaces(const char* src) { return negate< space >(src); }

src/lexer.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ namespace Sass {
4444
const char* xdigit(const char* src);
4545
const char* alnum(const char* src);
4646
const char* punct(const char* src);
47+
const char* hyphen(const char* src);
4748
const char* unicode(const char* src);
4849
const char* nonascii(const char* src);
4950
const char* character(const char* src);
@@ -53,6 +54,7 @@ namespace Sass {
5354
// Match multiple ctype characters.
5455
const char* spaces(const char* src);
5556
const char* digits(const char* src);
57+
const char* hyphens(const char* src);
5658

5759
// Whitespace handling.
5860
const char* no_spaces(const char* src);

src/parser.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,10 +1325,7 @@ namespace Sass {
13251325
else if (peek< ie_keyword_arg >()) {
13261326
return parse_ie_keyword_arg();
13271327
}
1328-
else if (peek< exactly< calc_kwd > >() ||
1329-
peek< exactly< moz_calc_kwd > >() ||
1330-
peek< exactly< ms_calc_kwd > >() ||
1331-
peek< exactly< webkit_calc_kwd > >()) {
1328+
else if (peek< sequence < calc_fn_call, exactly <'('> > >()) {
13321329
return parse_calc_function();
13331330
}
13341331
else if (lex < functional_schema >()) {

src/prelexer.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,22 @@ namespace Sass {
825825
return sequence<exactly<'$'>, identifier>(src);
826826
}
827827

828+
// parse `calc`, `-a-calc` and `--b-c-calc`
829+
// but do not parse `foocalc` or `foo-calc`
830+
const char* calc_fn_call(const char* src) {
831+
return sequence <
832+
optional < sequence <
833+
hyphens,
834+
one_plus < sequence <
835+
strict_identifier,
836+
hyphens
837+
> >
838+
> >,
839+
exactly < calc_fn_kwd >,
840+
word_boundary
841+
>(src);
842+
}
843+
828844
// Match Sass boolean keywords.
829845
const char* kwd_true(const char* src) {
830846
return word<true_kwd>(src);
@@ -1183,6 +1199,12 @@ namespace Sass {
11831199
// lexer special_fn: these functions cannot be overloaded
11841200
// (/((-[\w-]+-)?(calc|element)|expression|progid:[a-z\.]*)\(/i)
11851201
const char* re_special_fun(const char* src) {
1202+
1203+
// match this first as we test prefix hyphens
1204+
if (const char* calc = calc_fn_call(src)) {
1205+
return calc;
1206+
}
1207+
11861208
return sequence <
11871209
optional <
11881210
sequence <
@@ -1197,7 +1219,6 @@ namespace Sass {
11971219
>
11981220
>,
11991221
alternatives <
1200-
word < calc_fn_kwd >,
12011222
word < expression_kwd >,
12021223
sequence <
12031224
sequence <

src/prelexer.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ namespace Sass {
331331

332332
// Match SCSS variable names.
333333
const char* variable(const char* src);
334+
const char* calc_fn_call(const char* src);
334335

335336
// IE stuff
336337
const char* ie_progid(const char* src);

0 commit comments

Comments
 (0)