@@ -50,6 +50,9 @@ abstract class StylesheetParser extends Parser {
5050 /// Whether the parser is currently parsing an unknown rule.
5151 var _inUnknownAtRule = false ;
5252
53+ /// Whether the parser is currently parsing a plain-CSS `@function` rule.
54+ var _inPlainCssFunction = false ;
55+
5356 /// Whether the parser is currently parsing a style rule.
5457 var _inStyleRule = false ;
5558
@@ -411,14 +414,19 @@ abstract class StylesheetParser extends Parser {
411414
412415 // Parse custom properties as declarations no matter what.
413416 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 ))) {
415422 var value = StringExpression (
416423 atEndOfStatement ()
417424 ? Interpolation (const [], const [], scanner.emptySpan)
418425 : _interpolatedDeclarationValue (silentComments: false ),
419426 );
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));
422430 }
423431
424432 if (scanner.scanChar ($colon)) {
@@ -542,15 +550,12 @@ abstract class StylesheetParser extends Parser {
542550 /// Consumes either a property declaration or a namespaced variable
543551 /// declaration.
544552 ///
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,
547554 /// [_declarationOrStyleRule] is used instead.
548555 ///
549556 /// If [parseCustomProperties] is `true` , properties that begin with `--` will
550557 /// be parsed using custom property parsing rules.
551- Statement _propertyOrVariableDeclaration ({
552- bool parseCustomProperties = true ,
553- }) {
558+ Statement _propertyOrVariableDeclaration () {
554559 var start = scanner.state;
555560
556561 Interpolation name;
@@ -574,12 +579,9 @@ abstract class StylesheetParser extends Parser {
574579 whitespace (consumeNewlines: false );
575580 scanner.expectChar ($colon);
576581
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);
583585 }
584586
585587 whitespace (consumeNewlines: false );
@@ -619,7 +621,7 @@ abstract class StylesheetParser extends Parser {
619621 /// Consumes a statement that's allowed within a declaration.
620622 Statement _declarationChild () => scanner.peekChar () == $at
621623 ? _declarationAtRule ()
622- : _propertyOrVariableDeclaration (parseCustomProperties : false );
624+ : _propertyOrVariableDeclaration ();
623625
624626 // ## At Rules
625627
@@ -669,7 +671,7 @@ abstract class StylesheetParser extends Parser {
669671 if (! root) _disallowedAtRule (start);
670672 return _forwardRule (start);
671673 case "function" :
672- return _functionRule (start);
674+ return _functionRule (start, name );
673675 case "if" :
674676 return _ifRule (start, child);
675677 case "import" :
@@ -914,24 +916,16 @@ abstract class StylesheetParser extends Parser {
914916 /// Consumes a function declaration.
915917 ///
916918 /// [start] should point before the `@` .
917- FunctionRule _functionRule (LineScannerState start) {
919+ Statement _functionRule (LineScannerState start, Interpolation atRuleName ) {
918920 whitespace (consumeNewlines: true );
919921 var precedingComment = lastSilentComment;
920922 lastSilentComment = null ;
921923 var beforeName = scanner.state;
922- var name = identifier ();
923924
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' )) {
935929 error ('This name is reserved for the plain-CSS function.' ,
936930 scanner.spanFrom (beforeName));
937931 }
@@ -1428,15 +1422,13 @@ abstract class StylesheetParser extends Parser {
14281422 var name = identifier ();
14291423
14301424 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+ );
14401432 }
14411433
14421434 whitespace (consumeNewlines: false );
@@ -1736,22 +1728,27 @@ abstract class StylesheetParser extends Parser {
17361728 if (scanner.peekChar () != $exclamation && ! atEndOfStatement ()) {
17371729 value = _interpolatedDeclarationValue (allowOpenBrace: false );
17381730 }
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 ;
17511734 }
17521735
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+ }
17551752 }
17561753
17571754 /// Throws a [StringScannerException] indicating that the at-rule starting at
0 commit comments