From 90b6190027088dc58c9413cf1ed25550a268b1fe Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 15 Sep 2022 13:58:12 -0700 Subject: [PATCH] Add a deprecation warning for strict unary operations (#1800) Closes #1721 --- CHANGELOG.md | 5 +++++ lib/src/callable/built_in.dart | 3 +-- lib/src/parse/stylesheet.dart | 28 ++++++++++++++++++++++++++++ pkg/sass_api/pubspec.yaml | 2 +- 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ebee22e1..132a4eba4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ ## 1.55.0 +* 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. + ### Dart API * Add an optional `argumentName` parameter to `SassScriptException()` to make it 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/pubspec.yaml b/pkg/sass_api/pubspec.yaml index ac509de08..c1f10ffa1 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.1.0 +version: 3.1.0-dev description: Additional APIs for Dart Sass. homepage: https://github.com/sass/dart-sass