@@ -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 (spanFrom (start, beforeColon));
414- if (name.initialPlain.startsWith ('--' )) {
417+ var isCustomProperty = name.initialPlain.startsWith ('--' );
418+ if (isCustomProperty ||
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, spanFrom (start));
427+ expectStatementSeparator (
428+ isCustomProperty ? "custom property" : "@function result" );
429+ return Declaration .notSassScript (name, value, 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, 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: 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 spanFrom (beforeName));
937931 }
@@ -1427,15 +1421,13 @@ abstract class StylesheetParser extends Parser {
14271421 var name = identifier ();
14281422
14291423 if (name.startsWith ('--' )) {
1430- warnings.add ((
1431- deprecation: Deprecation .cssFunctionMixin,
1432- message:
1433- 'Sass @mixin names beginning with -- are deprecated for forward-'
1434- 'compatibility with plain CSS mixins.\n '
1435- '\n '
1436- 'For details, see https://sass-lang.com/d/css-function-mixin' ,
1437- span: spanFrom (beforeName),
1438- ));
1424+ error (
1425+ 'Sass @mixin names beginning with -- are forbidden for forward-'
1426+ 'compatibility with plain CSS mixins.\n '
1427+ '\n '
1428+ 'For details, see https://sass-lang.com/d/css-function-mixin' ,
1429+ spanFrom (beforeName),
1430+ );
14391431 }
14401432
14411433 whitespace (consumeNewlines: false );
@@ -1735,22 +1727,27 @@ abstract class StylesheetParser extends Parser {
17351727 if (scanner.peekChar () != $exclamation && ! atEndOfStatement ()) {
17361728 value = _interpolatedDeclarationValue (allowOpenBrace: false );
17371729 }
1738-
1739- AtRule rule;
1740- if (lookingAtChildren ()) {
1741- rule = _withChildren (
1742- _statement,
1743- start,
1744- (children, span) =>
1745- AtRule (name, span, value: value, children: children),
1746- );
1747- } else {
1748- expectStatementSeparator ();
1749- rule = AtRule (name, spanFrom (start), value: value);
1730+ var wasInPlainCssFunction = _inPlainCssFunction;
1731+ if (name.asPlain case var name? when equalsIgnoreCase (name, 'function' )) {
1732+ _inPlainCssFunction = true ;
17501733 }
17511734
1752- _inUnknownAtRule = wasInUnknownAtRule;
1753- return rule;
1735+ try {
1736+ if (lookingAtChildren ()) {
1737+ return _withChildren (
1738+ _statement,
1739+ start,
1740+ (children, span) =>
1741+ AtRule (name, span, value: value, children: children),
1742+ );
1743+ } else {
1744+ expectStatementSeparator ();
1745+ return AtRule (name, spanFrom (start), value: value);
1746+ }
1747+ } finally {
1748+ _inUnknownAtRule = wasInUnknownAtRule;
1749+ _inPlainCssFunction = wasInPlainCssFunction;
1750+ }
17541751 }
17551752
17561753 /// Throws a [StringScannerException] indicating that the at-rule starting at
0 commit comments