From a56085b1647d6ed1e5c8511a9c0e7550f33d9c7b Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 13 Sep 2022 15:23:54 -0700 Subject: [PATCH] Add a deprecation warning for strict unary operations Closes #1721 --- CHANGELOG.md | 7 +++++++ lib/src/callable/built_in.dart | 3 +-- lib/src/parse/stylesheet.dart | 28 ++++++++++++++++++++++++++++ pkg/sass_api/CHANGELOG.md | 4 ++++ pkg/sass_api/pubspec.yaml | 4 ++-- pubspec.yaml | 2 +- 6 files changed, 43 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 566d20f85..f2a521fb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 1.54.10 + +* Emit a deprecation warning for `$a -$b` and `$a +$b`, since these look like + they could be unary operations but they're actually parsed as binary + operations. Either explicitly write `$a - $b` or `$a (-$b)`. See + https://sass-lang.com/d/strict-unary for more details. + ## 1.54.9 * Fix an incorrect span in certain `@media` query deprecation warnings. diff --git a/lib/src/callable/built_in.dart b/lib/src/callable/built_in.dart index 8576c5c0c..a6bad3414 100644 --- a/lib/src/callable/built_in.dart +++ b/lib/src/callable/built_in.dart @@ -72,8 +72,7 @@ class BuiltInCallable implements Callable, AsyncBuiltInCallable { /// /// If passed, [url] is the URL of the module in which the function is /// defined. - BuiltInCallable.overloadedFunction( - this.name, Map overloads, + BuiltInCallable.overloadedFunction(this.name, Map overloads, {Object? url}) : _overloads = [ for (var entry in overloads.entries) diff --git a/lib/src/parse/stylesheet.dart b/lib/src/parse/stylesheet.dart index f4dc5ca20..a76bef0e4 100644 --- a/lib/src/parse/stylesheet.dart +++ b/lib/src/parse/stylesheet.dart @@ -1788,6 +1788,34 @@ abstract class StylesheetParser extends Parser { } else { singleExpression_ = BinaryOperationExpression(operator, left, right); allowSlash = false; + + if (operator == BinaryOperator.plus || + operator == BinaryOperator.minus) { + if (scanner.string.substring( + right.span.start.offset - 1, right.span.start.offset) == + operator.operator && + isWhitespace(scanner.string.codeUnitAt(left.span.end.offset))) { + logger.warn( + "This operation is parsed as:\n" + "\n" + " $left ${operator.operator} $right\n" + "\n" + "but you may have intended it to mean:\n" + "\n" + " $left (${operator.operator}$right)\n" + "\n" + "Add a space after ${operator.operator} to clarify that it's " + "meant to be a binary operation, or wrap\n" + "it in parentheses to make it a unary operation. This will be " + "an error in future\n" + "versions of Sass.\n" + "\n" + "More info and automated migrator: " + "https://sass-lang.com/d/strict-unary", + span: singleExpression_!.span, + deprecation: true); + } + } } } diff --git a/pkg/sass_api/CHANGELOG.md b/pkg/sass_api/CHANGELOG.md index bbcab2bb6..2656ebf3b 100644 --- a/pkg/sass_api/CHANGELOG.md +++ b/pkg/sass_api/CHANGELOG.md @@ -1,3 +1,7 @@ +## 3.0.5 + +* No user-visible changes. + ## 3.0.4 * `UnaryOperationExpression`s with operator `not` now include a correct span, diff --git a/pkg/sass_api/pubspec.yaml b/pkg/sass_api/pubspec.yaml index bf8ff8e8d..4f0a971db 100644 --- a/pkg/sass_api/pubspec.yaml +++ b/pkg/sass_api/pubspec.yaml @@ -2,7 +2,7 @@ name: sass_api # Note: Every time we add a new Sass AST node, we need to bump the *major* # version because it's a breaking change for anyone who's implementing the # visitor interface(s). -version: 3.0.4 +version: 3.0.5-dev description: Additional APIs for Dart Sass. homepage: https://github.com/sass/dart-sass @@ -10,7 +10,7 @@ environment: sdk: ">=2.17.0 <3.0.0" dependencies: - sass: 1.54.9 + sass: 1.54.10 dev_dependencies: dartdoc: ^5.0.0 diff --git a/pubspec.yaml b/pubspec.yaml index 15b5bab9a..262ebcdc9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: sass -version: 1.54.9 +version: 1.54.10-dev description: A Sass implementation in Dart. homepage: https://github.com/sass/dart-sass