@@ -50,6 +50,9 @@ abstract class StylesheetParser extends Parser {
50
50
/// Whether the parser is currently parsing an unknown rule.
51
51
var _inUnknownAtRule = false ;
52
52
53
+ /// Whether the parser is currently parsing a plain-CSS `@function` rule.
54
+ var _inPlainCssFunction = false ;
55
+
53
56
/// Whether the parser is currently parsing a style rule.
54
57
var _inStyleRule = false ;
55
58
@@ -411,14 +414,19 @@ abstract class StylesheetParser extends Parser {
411
414
412
415
// Parse custom properties as declarations no matter what.
413
416
var name = nameBuffer.interpolation (scanner.spanFrom (start, beforeColon));
414
- if (name.initialPlain.startsWith ('--' )) {
417
+ var customProperty = name.initialPlain.startsWith ('--' );
418
+ if (customProperty ||
419
+ (_inPlainCssFunction &&
420
+ (name.asPlain.andThen ((name) => equalsIgnoreCase (name, 'result' )) ??
421
+ false ))) {
415
422
var value = StringExpression (
416
423
atEndOfStatement ()
417
424
? Interpolation (const [], const [], scanner.emptySpan)
418
425
: _interpolatedDeclarationValue (silentComments: false ),
419
426
);
420
- expectStatementSeparator ("custom property" );
421
- return Declaration (name, value, scanner.spanFrom (start));
427
+ expectStatementSeparator (
428
+ customProperty ? "custom property" : "@function result" );
429
+ return Declaration .notSassScript (name, value, scanner.spanFrom (start));
422
430
}
423
431
424
432
if (scanner.scanChar ($colon)) {
@@ -542,15 +550,12 @@ abstract class StylesheetParser extends Parser {
542
550
/// Consumes either a property declaration or a namespaced variable
543
551
/// declaration.
544
552
///
545
- /// This is only used in contexts where declarations are allowed but style
546
- /// rules are not, such as nested declarations. Otherwise,
553
+ /// This is only used when nested beneath other declarations. Otherwise,
547
554
/// [_declarationOrStyleRule] is used instead.
548
555
///
549
556
/// If [parseCustomProperties] is `true` , properties that begin with `--` will
550
557
/// be parsed using custom property parsing rules.
551
- Statement _propertyOrVariableDeclaration ({
552
- bool parseCustomProperties = true ,
553
- }) {
558
+ Statement _propertyOrVariableDeclaration () {
554
559
var start = scanner.state;
555
560
556
561
Interpolation name;
@@ -574,12 +579,9 @@ abstract class StylesheetParser extends Parser {
574
579
whitespace (consumeNewlines: false );
575
580
scanner.expectChar ($colon);
576
581
577
- if (parseCustomProperties && name.initialPlain.startsWith ('--' )) {
578
- var value = StringExpression (
579
- _interpolatedDeclarationValue (silentComments: false ),
580
- );
581
- expectStatementSeparator ("custom property" );
582
- return Declaration (name, value, scanner.spanFrom (start));
582
+ if (name.initialPlain.startsWith ('--' )) {
583
+ error ('Declarations whose names begin with "--" may not be nested.' ,
584
+ name.span);
583
585
}
584
586
585
587
whitespace (consumeNewlines: false );
@@ -619,7 +621,7 @@ abstract class StylesheetParser extends Parser {
619
621
/// Consumes a statement that's allowed within a declaration.
620
622
Statement _declarationChild () => scanner.peekChar () == $at
621
623
? _declarationAtRule ()
622
- : _propertyOrVariableDeclaration (parseCustomProperties : false );
624
+ : _propertyOrVariableDeclaration ();
623
625
624
626
// ## At Rules
625
627
@@ -669,7 +671,7 @@ abstract class StylesheetParser extends Parser {
669
671
if (! root) _disallowedAtRule (start);
670
672
return _forwardRule (start);
671
673
case "function" :
672
- return _functionRule (start);
674
+ return _functionRule (start, name );
673
675
case "if" :
674
676
return _ifRule (start, child);
675
677
case "import" :
@@ -914,24 +916,16 @@ abstract class StylesheetParser extends Parser {
914
916
/// Consumes a function declaration.
915
917
///
916
918
/// [start] should point before the `@` .
917
- FunctionRule _functionRule (LineScannerState start) {
919
+ Statement _functionRule (LineScannerState start, Interpolation atRuleName ) {
918
920
whitespace (consumeNewlines: true );
919
921
var precedingComment = lastSilentComment;
920
922
lastSilentComment = null ;
921
923
var beforeName = scanner.state;
922
- var name = identifier ();
923
924
924
- if (name.startsWith ('--' )) {
925
- warnings.add ((
926
- deprecation: Deprecation .cssFunctionMixin,
927
- message:
928
- 'Sass @function names beginning with -- are deprecated for forward-'
929
- 'compatibility with plain CSS functions.\n '
930
- '\n '
931
- 'For details, see https://sass-lang.com/d/css-function-mixin' ,
932
- span: scanner.spanFrom (beforeName),
933
- ));
934
- } else if (equalsIgnoreCase (name, 'type' )) {
925
+ if (scanner.matches ('--' )) return unknownAtRule (start, atRuleName);
926
+
927
+ var name = identifier ();
928
+ if (equalsIgnoreCase (name, 'type' )) {
935
929
error ('This name is reserved for the plain-CSS function.' ,
936
930
scanner.spanFrom (beforeName));
937
931
}
@@ -1428,15 +1422,13 @@ abstract class StylesheetParser extends Parser {
1428
1422
var name = identifier ();
1429
1423
1430
1424
if (name.startsWith ('--' )) {
1431
- warnings.add ((
1432
- deprecation: Deprecation .cssFunctionMixin,
1433
- message:
1434
- 'Sass @mixin names beginning with -- are deprecated for forward-'
1435
- 'compatibility with plain CSS mixins.\n '
1436
- '\n '
1437
- 'For details, see https://sass-lang.com/d/css-function-mixin' ,
1438
- span: scanner.spanFrom (beforeName),
1439
- ));
1425
+ error (
1426
+ 'Sass @mixin names beginning with -- are forbidden for forward-'
1427
+ 'compatibility with plain CSS mixins.\n '
1428
+ '\n '
1429
+ 'For details, see https://sass-lang.com/d/css-function-mixin' ,
1430
+ scanner.spanFrom (beforeName),
1431
+ );
1440
1432
}
1441
1433
1442
1434
whitespace (consumeNewlines: false );
@@ -1736,22 +1728,27 @@ abstract class StylesheetParser extends Parser {
1736
1728
if (scanner.peekChar () != $exclamation && ! atEndOfStatement ()) {
1737
1729
value = _interpolatedDeclarationValue (allowOpenBrace: false );
1738
1730
}
1739
-
1740
- AtRule rule;
1741
- if (lookingAtChildren ()) {
1742
- rule = _withChildren (
1743
- _statement,
1744
- start,
1745
- (children, span) =>
1746
- AtRule (name, span, value: value, children: children),
1747
- );
1748
- } else {
1749
- expectStatementSeparator ();
1750
- rule = AtRule (name, scanner.spanFrom (start), value: value);
1731
+ var wasInPlainCssFunction = _inPlainCssFunction;
1732
+ if (name.asPlain case var name? when equalsIgnoreCase (name, 'function' )) {
1733
+ _inPlainCssFunction = true ;
1751
1734
}
1752
1735
1753
- _inUnknownAtRule = wasInUnknownAtRule;
1754
- return rule;
1736
+ try {
1737
+ if (lookingAtChildren ()) {
1738
+ return _withChildren (
1739
+ _statement,
1740
+ start,
1741
+ (children, span) =>
1742
+ AtRule (name, span, value: value, children: children),
1743
+ );
1744
+ } else {
1745
+ expectStatementSeparator ();
1746
+ return AtRule (name, scanner.spanFrom (start), value: value);
1747
+ }
1748
+ } finally {
1749
+ _inUnknownAtRule = wasInUnknownAtRule;
1750
+ _inPlainCssFunction = wasInPlainCssFunction;
1751
+ }
1755
1752
}
1756
1753
1757
1754
/// Throws a [StringScannerException] indicating that the at-rule starting at
0 commit comments