Skip to content

Commit 5121eb1

Browse files
authored
Don't treat underscores as hyphens for the purpose of error checking (#2247)
1 parent bdc08fd commit 5121eb1

File tree

7 files changed

+81
-18
lines changed

7 files changed

+81
-18
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
## 1.77.2
22

3+
* Don't emit deprecation warnings for functions and mixins beginning with `__`.
4+
5+
* Allow user-defined functions whose names begin with `_` and otherwise look
6+
like vendor-prefixed functions with special CSS syntax.
7+
38
### Command-Line Interface
49

510
* Properly handle the `--silence-deprecation` flag.

lib/src/ast/sass/expression/function.dart

+8-7
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ final class FunctionExpression
2323
/// without a namespace.
2424
final String? namespace;
2525

26+
/// The name of the function being invoked, with underscores converted to
27+
/// hyphens.
28+
///
29+
/// If this function is a plain CSS function, use [originalName] instead.
30+
final String name;
31+
2632
/// The name of the function being invoked, with underscores left as-is.
2733
final String originalName;
2834

@@ -31,12 +37,6 @@ final class FunctionExpression
3137

3238
final FileSpan span;
3339

34-
/// The name of the function being invoked, with underscores converted to
35-
/// hyphens.
36-
///
37-
/// If this function is a plain CSS function, use [originalName] instead.
38-
String get name => originalName.replaceAll('_', '-');
39-
4040
FileSpan get nameSpan {
4141
if (namespace == null) return span.initialIdentifier();
4242
return span.withoutNamespace().initialIdentifier();
@@ -46,7 +46,8 @@ final class FunctionExpression
4646
namespace == null ? null : span.initialIdentifier();
4747

4848
FunctionExpression(this.originalName, this.arguments, this.span,
49-
{this.namespace});
49+
{this.namespace})
50+
: name = originalName.replaceAll('_', '-');
5051

5152
T accept<T>(ExpressionVisitor<T> visitor) =>
5253
visitor.visitFunctionExpression(this);

lib/src/ast/sass/statement/callable_declaration.dart

+7-3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ abstract base class CallableDeclaration
1818
/// The name of this callable, with underscores converted to hyphens.
1919
final String name;
2020

21+
/// The callable's original name, without underscores converted to hyphens.
22+
final String originalName;
23+
2124
/// The comment immediately preceding this declaration.
2225
final SilentComment? comment;
2326

@@ -26,8 +29,9 @@ abstract base class CallableDeclaration
2629

2730
final FileSpan span;
2831

29-
CallableDeclaration(
30-
this.name, this.arguments, Iterable<Statement> children, this.span,
32+
CallableDeclaration(this.originalName, this.arguments,
33+
Iterable<Statement> children, this.span,
3134
{this.comment})
32-
: super(List.unmodifiable(children));
35+
: name = originalName.replaceAll('_', '-'),
36+
super(List.unmodifiable(children));
3337
}

lib/src/ast/sass/statement/include_rule.dart

+7-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ final class IncludeRule
2525
/// hyphens.
2626
final String name;
2727

28+
/// The original name of the mixin being invoked, without underscores
29+
/// converted to hyphens.
30+
final String originalName;
31+
2832
/// The arguments to pass to the mixin.
2933
final ArgumentInvocation arguments;
3034

@@ -55,8 +59,9 @@ final class IncludeRule
5559
return startSpan.initialIdentifier();
5660
}
5761

58-
IncludeRule(this.name, this.arguments, this.span,
59-
{this.namespace, this.content});
62+
IncludeRule(this.originalName, this.arguments, this.span,
63+
{this.namespace, this.content})
64+
: name = originalName.replaceAll('_', '-');
6065

6166
T accept<T>(StatementVisitor<T> visitor) => visitor.visitIncludeRule(this);
6267

lib/src/parse/stylesheet.dart

+3-5
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,7 @@ abstract class StylesheetParser extends Parser {
847847
var precedingComment = lastSilentComment;
848848
lastSilentComment = null;
849849
var beforeName = scanner.state;
850-
var name = identifier(normalize: true);
850+
var name = identifier();
851851

852852
if (name.startsWith('--')) {
853853
logger.warnForDeprecation(
@@ -1221,8 +1221,6 @@ abstract class StylesheetParser extends Parser {
12211221
if (scanner.scanChar($dot)) {
12221222
namespace = name;
12231223
name = _publicIdentifier();
1224-
} else {
1225-
name = name.replaceAll("_", "-");
12261224
}
12271225

12281226
whitespace();
@@ -1274,7 +1272,7 @@ abstract class StylesheetParser extends Parser {
12741272
var precedingComment = lastSilentComment;
12751273
lastSilentComment = null;
12761274
var beforeName = scanner.state;
1277-
var name = identifier(normalize: true);
1275+
var name = identifier();
12781276

12791277
if (name.startsWith('--')) {
12801278
logger.warnForDeprecation(
@@ -3457,7 +3455,7 @@ abstract class StylesheetParser extends Parser {
34573455
/// Like [identifier], but rejects identifiers that begin with `_` or `-`.
34583456
String _publicIdentifier() {
34593457
var start = scanner.state;
3460-
var result = identifier(normalize: true);
3458+
var result = identifier();
34613459
_assertPublic(result, () => scanner.spanFrom(start));
34623460
return result;
34633461
}

lib/src/visitor/async_evaluate.dart

+25
Original file line numberDiff line numberDiff line change
@@ -1853,6 +1853,18 @@ final class _EvaluateVisitor
18531853
Future<Value?> visitIncludeRule(IncludeRule node) async {
18541854
var mixin = _addExceptionSpan(node,
18551855
() => _environment.getMixin(node.name, namespace: node.namespace));
1856+
if (node.originalName.startsWith('--') &&
1857+
mixin is UserDefinedCallable &&
1858+
!mixin.declaration.originalName.startsWith('--')) {
1859+
_warn(
1860+
'Sass @mixin names beginning with -- are deprecated for forward-'
1861+
'compatibility with plain CSS mixins.\n'
1862+
'\n'
1863+
'For details, see https://sass-lang.com/d/css-function-mixin',
1864+
node.nameSpan,
1865+
Deprecation.cssFunctionMixin);
1866+
}
1867+
18561868
var contentCallable = node.content.andThen((content) => UserDefinedCallable(
18571869
content, _environment.closure(),
18581870
inDependency: _inDependency));
@@ -2510,6 +2522,19 @@ final class _EvaluateVisitor
25102522
PlainCssCallable(node.originalName);
25112523
}
25122524

2525+
if (node.originalName.startsWith('--') &&
2526+
function is UserDefinedCallable &&
2527+
!function.declaration.originalName.startsWith('--')) {
2528+
_warn(
2529+
'Sass @function names beginning with -- are deprecated for forward-'
2530+
'compatibility with plain CSS functions.\n'
2531+
'\n'
2532+
'For details, see https://sass-lang.com/d/css-function-mixin',
2533+
node.nameSpan,
2534+
Deprecation.cssFunctionMixin,
2535+
);
2536+
}
2537+
25132538
var oldInFunction = _inFunction;
25142539
_inFunction = true;
25152540
var result = await _addErrorSpan(

lib/src/visitor/evaluate.dart

+26-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// DO NOT EDIT. This file was generated from async_evaluate.dart.
66
// See tool/grind/synchronize.dart for details.
77
//
8-
// Checksum: 7788c21fd8c721992490ac01d0ef4783dddf3f1f
8+
// Checksum: 116b8079719577ac6e4dad4aebe403282136e611
99
//
1010
// ignore_for_file: unused_import
1111

@@ -1845,6 +1845,18 @@ final class _EvaluateVisitor
18451845
Value? visitIncludeRule(IncludeRule node) {
18461846
var mixin = _addExceptionSpan(node,
18471847
() => _environment.getMixin(node.name, namespace: node.namespace));
1848+
if (node.originalName.startsWith('--') &&
1849+
mixin is UserDefinedCallable &&
1850+
!mixin.declaration.originalName.startsWith('--')) {
1851+
_warn(
1852+
'Sass @mixin names beginning with -- are deprecated for forward-'
1853+
'compatibility with plain CSS mixins.\n'
1854+
'\n'
1855+
'For details, see https://sass-lang.com/d/css-function-mixin',
1856+
node.nameSpan,
1857+
Deprecation.cssFunctionMixin);
1858+
}
1859+
18481860
var contentCallable = node.content.andThen((content) => UserDefinedCallable(
18491861
content, _environment.closure(),
18501862
inDependency: _inDependency));
@@ -2486,6 +2498,19 @@ final class _EvaluateVisitor
24862498
PlainCssCallable(node.originalName);
24872499
}
24882500

2501+
if (node.originalName.startsWith('--') &&
2502+
function is UserDefinedCallable &&
2503+
!function.declaration.originalName.startsWith('--')) {
2504+
_warn(
2505+
'Sass @function names beginning with -- are deprecated for forward-'
2506+
'compatibility with plain CSS functions.\n'
2507+
'\n'
2508+
'For details, see https://sass-lang.com/d/css-function-mixin',
2509+
node.nameSpan,
2510+
Deprecation.cssFunctionMixin,
2511+
);
2512+
}
2513+
24892514
var oldInFunction = _inFunction;
24902515
_inFunction = true;
24912516
var result = _addErrorSpan(

0 commit comments

Comments
 (0)