From 73ebf92e9f73c464cfea5b7d39571ea7e8daa97f Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 14 Oct 2020 14:10:46 -0700 Subject: [PATCH 1/9] Support the latest version of the analyzer package (#1115) --- pubspec.yaml | 2 +- tool/grind/synchronize.dart | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pubspec.yaml b/pubspec.yaml index ef2e39450..7a618448f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -32,7 +32,7 @@ dependencies: dev_dependencies: archive: ">=1.0.0 <3.0.0" - analyzer: ">=0.37.0 <0.40.0" + analyzer: "^0.40.0" cli_pkg: "^1.0.0-beta.10" crypto: ">=0.9.2 <3.0.0" dart_style: "^1.2.0" diff --git a/tool/grind/synchronize.dart b/tool/grind/synchronize.dart index be3e6e25b..8b171e830 100644 --- a/tool/grind/synchronize.dart +++ b/tool/grind/synchronize.dart @@ -43,7 +43,8 @@ final _sharedClasses = const ['EvaluateResult', 'CompileResult']; void synchronize() { sources.forEach((source, target) { var visitor = _Visitor(File(source).readAsStringSync(), source); - parseFile(path: source, featureSet: FeatureSet.fromEnableFlags([])) + + parseFile(path: source, featureSet: FeatureSet.latestLanguageVersion()) .unit .accept(visitor); var formatted = DartFormatter().format(visitor.result); From 00914eca369cac5f8745a99e685c5b1a690a904a Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 23 Oct 2020 14:25:03 -0700 Subject: [PATCH 2/9] Remove the cli_pkg dependency override (#1118) --- pubspec.yaml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pubspec.yaml b/pubspec.yaml index 7a618448f..5774c25f7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -46,9 +46,3 @@ dev_dependencies: test_process: "^1.0.0-rc.1" test: ">=0.12.42 <2.0.0" yaml: "^2.0.0" - -dependency_overrides: - cli_pkg: - git: - url: git://github.com/google/dart_cli_pkg - ref: 1.0.0-beta.10 From 26ed30bc54d67fad627a412f6937ceb03570432e Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 27 Oct 2020 12:15:06 -0700 Subject: [PATCH 3/9] Avoid build breakages due to fibers and the latest Node (#1126) --- .travis.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4ec6709ac..60a2b49d5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -74,9 +74,10 @@ jobs: # They next need to be rotated April 2021. See # https://github.com/nodejs/Release. - &node-tests - name: Node tests | Dart stable | Node stable + # Run on Node 14 until laverdet/node-fibers#445 is fixed. + name: Node tests | Dart stable | Node 14 language: node_js - node_js: node + node_js: v14 install: pub run grinder before-test script: tool/travis/task/node_tests.sh - <<: *node-tests @@ -90,7 +91,7 @@ jobs: - <<: *node-tests os: osx - <<: *node-tests - name: Node tests | Dart dev | Node stable + name: Node tests | Dart dev | Node 14 env: DART_CHANNEL=dev # Miscellaneous checks. From 197c6dbbdefc102030b748b5dbfba3c4d7cc8b97 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 27 Oct 2020 15:47:48 -0700 Subject: [PATCH 4/9] Emit a proper parse error for = with no RHS in a function (#1071) Closes #1050 --- CHANGELOG.md | 4 ++++ lib/src/parse/stylesheet.dart | 20 +++++--------------- pubspec.yaml | 2 +- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f00053ab5..f3d2b0200 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.27.1 + +* Emit a proper parse error for a `=` with no right-hand side in a function. + ## 1.27.0 * Adds an overload to `map.merge()` that supports merging a nested map. diff --git a/lib/src/parse/stylesheet.dart b/lib/src/parse/stylesheet.dart index 3fea27a0e..2d609626b 100644 --- a/lib/src/parse/stylesheet.dart +++ b/lib/src/parse/stylesheet.dart @@ -1640,8 +1640,6 @@ relase. For details, see http://bit.ly/moz-document. List commaExpressions; - Expression singleEqualsOperand; - List spaceExpressions; // Operators whose right-hand operands are not fully parsed yet, in order of @@ -1718,7 +1716,9 @@ relase. For details, see http://bit.ly/moz-document. } void addOperator(BinaryOperator operator) { - if (plainCss && operator != BinaryOperator.dividedBy) { + if (plainCss && + operator != BinaryOperator.dividedBy && + operator != BinaryOperator.singleEquals) { scanner.error("Operators aren't allowed in plain CSS.", position: scanner.position - operator.operator.length, length: operator.operator.length); @@ -1750,12 +1750,6 @@ relase. For details, see http://bit.ly/moz-document. ListExpression(spaceExpressions, ListSeparator.space); spaceExpressions = null; } - - if (singleEqualsOperand != null) { - singleExpression = BinaryOperationExpression( - BinaryOperator.singleEquals, singleEqualsOperand, singleExpression); - singleEqualsOperand = null; - } } loop: @@ -1794,9 +1788,7 @@ relase. For details, see http://bit.ly/moz-document. case $equal: scanner.readChar(); if (singleEquals && scanner.peekChar() != $equal) { - resolveSpaceExpressions(); - singleEqualsOperand = singleExpression; - singleExpression = null; + addOperator(BinaryOperator.singleEquals); } else { scanner.expectChar($equal); addOperator(BinaryOperator.equals); @@ -2014,9 +2006,7 @@ relase. For details, see http://bit.ly/moz-document. return ListExpression(commaExpressions, ListSeparator.comma, brackets: bracketList, span: bracketList ? scanner.spanFrom(beforeBracket) : null); - } else if (bracketList && - spaceExpressions != null && - singleEqualsOperand == null) { + } else if (bracketList && spaceExpressions != null) { resolveOperations(); return ListExpression( spaceExpressions..add(singleExpression), ListSeparator.space, diff --git a/pubspec.yaml b/pubspec.yaml index 5774c25f7..fe023a40c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: sass -version: 1.27.0 +version: 1.27.1-dev description: A Sass implementation in Dart. author: Sass Team homepage: https://github.com/sass/dart-sass From c4f95d431097413f4884c8e719f3e43d0d7b6962 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 27 Oct 2020 15:54:14 -0700 Subject: [PATCH 5/9] Fix the argument name for meta.load-css() (#1072) Closes #1054 --- CHANGELOG.md | 3 +++ lib/src/visitor/async_evaluate.dart | 4 ++-- lib/src/visitor/evaluate.dart | 6 +++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3d2b0200..6d3a83249 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ## 1.27.1 +* **Potentially breaking bug fix:** `meta.load-css()` now correctly uses the + name `$url` for its first argument, rather than `$module`. + * Emit a proper parse error for a `=` with no right-hand side in a function. ## 1.27.0 diff --git a/lib/src/visitor/async_evaluate.dart b/lib/src/visitor/async_evaluate.dart index 4cb43ad17..b7bbf74b1 100644 --- a/lib/src/visitor/async_evaluate.dart +++ b/lib/src/visitor/async_evaluate.dart @@ -419,9 +419,9 @@ class _EvaluateVisitor ]; var metaMixins = [ - AsyncBuiltInCallable.mixin("load-css", r"$module, $with: null", + AsyncBuiltInCallable.mixin("load-css", r"$url, $with: null", (arguments) async { - var url = Uri.parse(arguments[0].assertString("module").text); + var url = Uri.parse(arguments[0].assertString("url").text); var withMap = arguments[1].realNull?.assertMap("with")?.contents; var configuration = const Configuration.empty(); diff --git a/lib/src/visitor/evaluate.dart b/lib/src/visitor/evaluate.dart index d8e6e71fd..530301c11 100644 --- a/lib/src/visitor/evaluate.dart +++ b/lib/src/visitor/evaluate.dart @@ -5,7 +5,7 @@ // DO NOT EDIT. This file was generated from async_evaluate.dart. // See tool/grind/synchronize.dart for details. // -// Checksum: 651a7e9f78b68bfd440241304301cf78711553a4 +// Checksum: 485fce53ba9f381973c25a69b193a681891be098 // // ignore_for_file: unused_import @@ -425,8 +425,8 @@ class _EvaluateVisitor ]; var metaMixins = [ - BuiltInCallable.mixin("load-css", r"$module, $with: null", (arguments) { - var url = Uri.parse(arguments[0].assertString("module").text); + BuiltInCallable.mixin("load-css", r"$url, $with: null", (arguments) { + var url = Uri.parse(arguments[0].assertString("url").text); var withMap = arguments[1].realNull?.assertMap("with")?.contents; var configuration = const Configuration.empty(); From 300197caf94c459d159f170bd242cb98521d9e80 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 27 Oct 2020 16:38:47 -0700 Subject: [PATCH 6/9] Don't crash when using Infinity or NaN as a key in a map (#1073) Closes #3126 --- CHANGELOG.md | 2 ++ lib/src/util/number.dart | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d3a83249..3b65c85b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ * **Potentially breaking bug fix:** `meta.load-css()` now correctly uses the name `$url` for its first argument, rather than `$module`. +* Don't crash when using `Infinity` or `NaN` as a key in a map. + * Emit a proper parse error for a `=` with no right-hand side in a function. ## 1.27.0 diff --git a/lib/src/util/number.dart b/lib/src/util/number.dart index da9679bc3..53bcf9239 100644 --- a/lib/src/util/number.dart +++ b/lib/src/util/number.dart @@ -19,7 +19,9 @@ bool fuzzyEquals(num number1, num number2) => final _inverseEpsilon = 1 / epsilon; /// Returns a hash code for [number] that matches [fuzzyEquals]. -int fuzzyHashCode(num number) => (number * _inverseEpsilon).round().hashCode; +int fuzzyHashCode(num number) => number.isInfinite || number.isNaN + ? number.hashCode + : (number * _inverseEpsilon).round().hashCode; /// Returns whether [number1] is less than [number2], and not [fuzzyEquals]. bool fuzzyLessThan(num number1, num number2) => From a9a3946fb4f1d7c0dcbeb47d9fd030ddd2f93fce Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 28 Oct 2020 15:00:05 -0700 Subject: [PATCH 7/9] Use node_interop rather than manually declaring Node APIs (#1127) --- lib/src/io/node.dart | 134 ++++++++----------------------- lib/src/node.dart | 18 ++--- lib/src/node/error.dart | 11 --- pubspec.yaml | 1 + test/node_api/api.dart | 9 --- test/node_api/function_test.dart | 5 +- test/node_api/importer_test.dart | 12 +-- test/node_api/utils.dart | 5 +- tool/grind.dart | 6 +- 9 files changed, 58 insertions(+), 143 deletions(-) delete mode 100644 lib/src/node/error.dart diff --git a/lib/src/io/node.dart b/lib/src/io/node.dart index 1e7fc90bc..203ceb3e8 100644 --- a/lib/src/io/node.dart +++ b/lib/src/io/node.dart @@ -7,6 +7,9 @@ import 'dart:convert'; import 'dart:js_util'; import 'package:js/js.dart'; +import 'package:node_interop/fs.dart'; +import 'package:node_interop/node_interop.dart'; +import 'package:node_interop/stream.dart'; import 'package:path/path.dart' as p; import 'package:source_span/source_span.dart'; import 'package:watcher/watcher.dart'; @@ -14,56 +17,6 @@ import 'package:watcher/watcher.dart'; import '../exception.dart'; import '../node/chokidar.dart'; -@JS() -class _FS { - external Object readFileSync(String path, [String encoding]); - external void writeFileSync(String path, String data); - external bool existsSync(String path); - external void mkdirSync(String path); - external _Stat statSync(String path); - external void unlinkSync(String path); - external List readdirSync(String path); -} - -@JS() -class _Stat { - external bool isFile(); - external bool isDirectory(); - external _Date get mtime; -} - -@JS() -class _Date { - external int getTime(); -} - -@JS() -class _Stderr { - external void write(String text); -} - -@JS() -class _Stdin { - external String read(); - - external void on(String event, void callback([Object object])); -} - -@JS() -class _SystemError { - external String get message; - external String get code; - external String get syscall; - external String get path; -} - -@JS() -class _Process { - external String get platform; - external Object get env; - external String cwd(); -} - class FileSystemException { final String message; final String path; @@ -74,7 +27,7 @@ class FileSystemException { } class Stderr { - final _Stderr _stderr; + final Writable _stderr; Stderr(this._stderr); @@ -87,12 +40,6 @@ class Stderr { void flush() {} } -@JS("fs") -external _FS get _fs; - -@JS("process") -external _Process get _process; - String readFile(String path) { // TODO(nweiz): explicitly decode the bytes as UTF-8 like we do in the VM when // it doesn't cause a substantial performance degradation for large files. See @@ -112,13 +59,13 @@ String readFile(String path) { /// Wraps `fs.readFileSync` to throw a [FileSystemException]. Object _readFile(String path, [String encoding]) => - _systemErrorToFileSystemException(() => _fs.readFileSync(path, encoding)); + _systemErrorToFileSystemException(() => fs.readFileSync(path, encoding)); void writeFile(String path, String contents) => - _systemErrorToFileSystemException(() => _fs.writeFileSync(path, contents)); + _systemErrorToFileSystemException(() => fs.writeFileSync(path, contents)); void deleteFile(String path) => - _systemErrorToFileSystemException(() => _fs.unlinkSync(path)); + _systemErrorToFileSystemException(() => fs.unlinkSync(path)); Future readStdin() async { var completer = Completer(); @@ -129,16 +76,16 @@ Future readStdin() async { }); // Node defaults all buffers to 'utf8'. var sink = utf8.decoder.startChunkedConversion(innerSink); - _stdin.on('data', allowInterop(([chunk]) { + process.stdin.on('data', allowInterop(([Object chunk]) { assert(chunk != null); sink.add(chunk as List); })); - _stdin.on('end', allowInterop(([_]) { + process.stdin.on('end', allowInterop(([Object _]) { // Callback for 'end' receives no args. assert(_ == null); sink.close(); })); - _stdin.on('error', allowInterop(([e]) { + process.stdin.on('error', allowInterop(([Object e]) { assert(e != null); stderr.writeln('Failed to read from stdin'); stderr.writeln(e); @@ -148,7 +95,7 @@ Future readStdin() async { } /// Cleans up a Node system error's message. -String _cleanErrorMessage(_SystemError error) { +String _cleanErrorMessage(JsSystemError error) { // The error message is of the form "$code: $text, $syscall '$path'". We just // want the text. return error.message.substring("${error.code}: ".length, @@ -161,12 +108,12 @@ bool fileExists(String path) { // whether the entity in question is a file or a directory. Since false // negatives are much more common than false positives, it works out in our // favor to check this first. - if (!_fs.existsSync(path)) return false; + if (!fs.existsSync(path)) return false; try { - return _fs.statSync(path).isFile(); + return fs.statSync(path).isFile(); } catch (error) { - var systemError = error as _SystemError; + var systemError = error as JsSystemError; if (systemError.code == 'ENOENT') return false; rethrow; } @@ -179,12 +126,12 @@ bool dirExists(String path) { // whether the entity in question is a file or a directory. Since false // negatives are much more common than false positives, it works out in our // favor to check this first. - if (!_fs.existsSync(path)) return false; + if (!fs.existsSync(path)) return false; try { - return _fs.statSync(path).isDirectory(); + return fs.statSync(path).isDirectory(); } catch (error) { - var systemError = error as _SystemError; + var systemError = error as JsSystemError; if (systemError.code == 'ENOENT') return false; rethrow; } @@ -194,13 +141,13 @@ bool dirExists(String path) { void ensureDir(String path) { return _systemErrorToFileSystemException(() { try { - _fs.mkdirSync(path); + fs.mkdirSync(path); } catch (error) { - var systemError = error as _SystemError; + var systemError = error as JsSystemError; if (systemError.code == 'EEXIST') return; if (systemError.code != 'ENOENT') rethrow; ensureDir(p.dirname(path)); - _fs.mkdirSync(path); + fs.mkdirSync(path); } }); } @@ -208,13 +155,13 @@ void ensureDir(String path) { Iterable listDir(String path, {bool recursive = false}) { return _systemErrorToFileSystemException(() { if (!recursive) { - return _fs + return fs .readdirSync(path) .map((child) => p.join(path, child as String)) .where((child) => !dirExists(child)); } else { Iterable list(String parent) => - _fs.readdirSync(parent).expand((child) { + fs.readdirSync(parent).expand((child) { var path = p.join(parent, child as String); return dirExists(path) ? list(path) : [path]; }); @@ -225,55 +172,42 @@ Iterable listDir(String path, {bool recursive = false}) { } DateTime modificationTime(String path) => - _systemErrorToFileSystemException(() => DateTime.fromMillisecondsSinceEpoch( - _fs.statSync(path).mtime.getTime())); + _systemErrorToFileSystemException(() => + DateTime.fromMillisecondsSinceEpoch(fs.statSync(path).mtime.getTime())); String getEnvironmentVariable(String name) => - getProperty(_process.env, name) as String; + getProperty(process.env, name) as String; -/// Runs callback and converts any [_SystemError]s it throws into +/// Runs callback and converts any [JsSystemError]s it throws into /// [FileSystemException]s. T _systemErrorToFileSystemException(T callback()) { try { return callback(); } catch (error) { - var systemError = error as _SystemError; + var systemError = error as JsSystemError; throw FileSystemException._( _cleanErrorMessage(systemError), systemError.path); } } -@JS("process.stderr") -external _Stderr get _stderr; - -final stderr = Stderr(_stderr); +final stderr = Stderr(process.stderr); -@JS("process.stdin") -external _Stdin get _stdin; +bool get hasTerminal => process.stdout.isTTY ?? false; -bool get hasTerminal => _hasTerminal ?? false; +bool get isWindows => process.platform == 'win32'; -bool get isWindows => _process.platform == 'win32'; - -bool get isMacOS => _process.platform == 'darwin'; +bool get isMacOS => process.platform == 'darwin'; bool get isNode => true; // Node seems to support ANSI escapes on all terminals. bool get supportsAnsiEscapes => hasTerminal; -String get currentPath => _process.cwd(); - -@JS("process.stdout.isTTY") -external bool get _hasTerminal; +String get currentPath => process.cwd(); -@JS("process.exitCode") -external int get exitCode; +int get exitCode => process.exitCode; -// TODO(nweiz): remove this ignore when dart-lang/sdk#39250 is fixed. -// ignore: inference_failure_on_function_return_type -@JS("process.exitCode") -external set exitCode(int code); +set exitCode(int code) => process.exitCode = code; Future> watchDir(String path, {bool poll = false}) { var watcher = chokidar.watch( diff --git a/lib/src/node.dart b/lib/src/node.dart index f52e0d0f9..b5c500dfc 100644 --- a/lib/src/node.dart +++ b/lib/src/node.dart @@ -8,6 +8,7 @@ import 'dart:js_util'; import 'dart:typed_data'; import 'package:js/js.dart'; +import 'package:node_interop/js.dart'; import 'package:path/path.dart' as p; import 'package:tuple/tuple.dart'; @@ -17,7 +18,6 @@ import 'compile.dart'; import 'exception.dart'; import 'io.dart'; import 'importer/node.dart'; -import 'node/error.dart'; import 'node/exports.dart'; import 'node/function.dart'; import 'node/render_context.dart'; @@ -65,13 +65,13 @@ void main() { /// /// [render]: https://github.com/sass/node-sass#options void _render( - RenderOptions options, void callback(JSError error, RenderResult result)) { + RenderOptions options, void callback(JsError error, RenderResult result)) { if (options.fiber != null) { options.fiber.call(allowInterop(() { try { callback(null, _renderSync(options)); } catch (error) { - callback(error as JSError, null); + callback(error as JsError, null); } return null; })).run(); @@ -166,8 +166,8 @@ RenderResult _renderSync(RenderOptions options) { throw "unreachable"; } -/// Converts an exception to a [JSError]. -JSError _wrapException(Object exception) { +/// Converts an exception to a [JsError]. +JsError _wrapException(Object exception) { if (exception is SassException) { return _newRenderError(exception.toString().replaceFirst("Error: ", ""), line: exception.span.start.line + 1, @@ -177,7 +177,7 @@ JSError _wrapException(Object exception) { : p.fromUri(exception.span.sourceUrl), status: 1); } else { - return JSError(exception.toString()); + return JsError(exception.toString()); } } @@ -388,11 +388,11 @@ bool _enableSourceMaps(RenderOptions options) => options.sourceMap is String || (isTruthy(options.sourceMap) && options.outFile != null); -/// Creates a [JSError] with the given fields added to it so it acts like a Node +/// Creates a [JsError] with the given fields added to it so it acts like a Node /// Sass error. -JSError _newRenderError(String message, +JsError _newRenderError(String message, {int line, int column, String file, int status}) { - var error = JSError(message); + var error = JsError(message); setProperty(error, 'formatted', 'Error: $message'); if (line != null) setProperty(error, 'line', line); if (column != null) setProperty(error, 'column', column); diff --git a/lib/src/node/error.dart b/lib/src/node/error.dart deleted file mode 100644 index f33ca45de..000000000 --- a/lib/src/node/error.dart +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2016 Google Inc. Use of this source code is governed by an -// MIT-style license that can be found in the LICENSE file or at -// https://opensource.org/licenses/MIT. - -import 'package:js/js.dart'; - -@JS("Error") -class JSError { - external String get message; - external JSError(String message); -} diff --git a/pubspec.yaml b/pubspec.yaml index fe023a40c..4e8cba170 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,6 +18,7 @@ dependencies: cli_repl: ">=0.1.3 <0.3.0" collection: "^1.8.0" meta: "^1.1.7" + node_interop: "^1.1.0" js: "^0.6.0" package_resolver: "^1.0.0" path: "^1.6.0" diff --git a/test/node_api/api.dart b/test/node_api/api.dart index 68bf4a6aa..772bed676 100644 --- a/test/node_api/api.dart +++ b/test/node_api/api.dart @@ -9,7 +9,6 @@ import 'package:js/js.dart'; import 'package:path/path.dart' as p; -export 'package:sass/src/node/error.dart'; export 'package:sass/src/node/importer_result.dart'; export 'package:sass/src/node/render_context.dart'; export 'package:sass/src/node/render_options.dart'; @@ -24,11 +23,6 @@ final sass = _requireSass(p.absolute("build/npm/sass.dart")); /// The Fiber class. final fiber = _requireFiber("fibers"); -/// A `null` that's guaranteed to be represented by JavaScript's `undefined` -/// value, not by `null`. -@JS() -external Object get undefined; - /// A `null` that's guaranteed to be represented by JavaScript's `null` value, /// not by `undefined`. /// @@ -39,9 +33,6 @@ final Object jsNull = _eval("null"); @JS("eval") external Object _eval(String js); -@JS("process.chdir") -external void chdir(String directory); - @JS("require") external Sass _requireSass(String path); diff --git a/test/node_api/function_test.dart b/test/node_api/function_test.dart index e42ef79a9..e50600963 100644 --- a/test/node_api/function_test.dart +++ b/test/node_api/function_test.dart @@ -9,6 +9,7 @@ import 'dart:async'; import 'dart:js_util'; import 'package:js/js.dart'; +import 'package:node_interop/js.dart'; import 'package:test/test.dart'; import '../ensure_npm_package.dart'; @@ -236,7 +237,7 @@ void main() { functions: jsify({ "foo": allowInterop((void done(Object result)) { Timer(Duration.zero, () { - done(JSError("aw beans")); + done(JsError("aw beans")); }); }) }))); @@ -340,7 +341,7 @@ void main() { functions: jsify({ "foo": allowInterop((void done(Object result)) { Timer(Duration.zero, () { - done(JSError("aw beans")); + done(JsError("aw beans")); }); }) }), diff --git a/test/node_api/importer_test.dart b/test/node_api/importer_test.dart index 07badf3df..f475cc93f 100644 --- a/test/node_api/importer_test.dart +++ b/test/node_api/importer_test.dart @@ -8,6 +8,8 @@ import 'dart:async'; import 'package:js/js.dart'; +import 'package:node_interop/js.dart'; +import 'package:node_interop/node.dart'; import 'package:path/path.dart' as p; import 'package:test/test.dart'; @@ -275,10 +277,10 @@ void main() { String oldWorkingDirectory; setUp(() { oldWorkingDirectory = currentPath; - chdir(sandbox); + process.chdir(sandbox); }); - tearDown(() => chdir(oldWorkingDirectory)); + tearDown(() => process.chdir(oldWorkingDirectory)); test("is resolved relative to the CWD", () { expect( @@ -575,7 +577,7 @@ void main() { test("an error is returned", () { var error = renderSyncError(RenderOptions( data: "@import 'foo'", - importer: allowInterop((void _, void __) => JSError("oh no")))); + importer: allowInterop((void _, void __) => JsError("oh no")))); expect( error, @@ -654,7 +656,7 @@ void main() { importer: allowInterop((void _, void __, void done(Object result)) { Timer(Duration.zero, () { - done(JSError('oh no')); + done(JsError('oh no')); }); }))), completion(toStringAndMessageEqual("oh no\n" @@ -742,7 +744,7 @@ void main() { importer: allowInterop((void _, void __, void done(Object result)) { Timer(Duration.zero, () { - done(JSError('oh no')); + done(JsError('oh no')); }); }), fiber: fiber)), diff --git a/test/node_api/utils.dart b/test/node_api/utils.dart index 554c706ff..3e5aff785 100644 --- a/test/node_api/utils.dart +++ b/test/node_api/utils.dart @@ -8,6 +8,7 @@ import 'dart:js_util'; import 'package:js/js.dart'; import 'package:test/test.dart'; +import 'package:node_interop/node_interop.dart'; import 'package:sass/src/io.dart'; import 'package:sass/src/node/function.dart'; @@ -97,8 +98,8 @@ void runTestInSandbox() { sass; var oldWorkingDirectory = currentPath; - chdir(sandbox); - addTearDown(() => chdir(oldWorkingDirectory)); + process.chdir(sandbox); + addTearDown(() => process.chdir(oldWorkingDirectory)); } /// Sets the environment variable [name] to [value] within this process. diff --git a/tool/grind.dart b/tool/grind.dart index 7dbd15b30..5e5a77b88 100644 --- a/tool/grind.dart +++ b/tool/grind.dart @@ -26,11 +26,7 @@ void main(List args) { pkg.chocolateyNuspec.value = _nuspec; pkg.homebrewRepo.value = "sass/homebrew-sass"; pkg.homebrewFormula.value = "sass.rb"; - pkg.jsRequires.value = { - "fs": "fs", - "chokidar": "chokidar", - "readline": "readline" - }; + pkg.jsRequires.value = {"chokidar": "chokidar", "readline": "readline"}; pkg.jsModuleMainLibrary.value = "lib/src/node.dart"; pkg.npmPackageJson.fn = () => json.decode(File("package/package.json").readAsStringSync()) From 290e55c2f1c13da2c8098e479d1e53576227d92a Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 28 Oct 2020 15:11:22 -0700 Subject: [PATCH 8/9] Trim extends at the compound selector level (#1124) This reverts a portion of #460 (15202c4). It turns out that trimming compound selector extends allows us to avoid exponential behavior in certain recursive @extend cases. See sass/dart-sass#1109 --- CHANGELOG.md | 2 ++ lib/src/extend/extender.dart | 18 ++++++++++++++---- pubspec.yaml | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b65c85b7..a188ed4a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ * Emit a proper parse error for a `=` with no right-hand side in a function. +* Avoid going exponential on certain recursive `@extend` edge cases. + ## 1.27.0 * Adds an overload to `map.merge()` that supports merging a nested map. diff --git a/lib/src/extend/extender.dart b/lib/src/extend/extender.dart index be90ba97b..32ca2ef23 100644 --- a/lib/src/extend/extender.dart +++ b/lib/src/extend/extender.dart @@ -684,10 +684,20 @@ class Extender { .toList(); }); - return unifiedPaths - .where((complexes) => complexes != null) - .expand((l) => l) - .toList(); + // If we're preserving the original selector, mark the first unification as + // such so [_trim] doesn't get rid of it. + var isOriginal = (ComplexSelector _) => false; + if (inOriginal && _mode != ExtendMode.replace) { + var original = unifiedPaths.first.first; + isOriginal = (complex) => complex == original; + } + + return _trim( + unifiedPaths + .where((complexes) => complexes != null) + .expand((l) => l) + .toList(), + isOriginal); } Iterable> _extendSimple( diff --git a/pubspec.yaml b/pubspec.yaml index 4e8cba170..e4a52a6f4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: sass -version: 1.27.1-dev +version: 1.27.1 description: A Sass implementation in Dart. author: Sass Team homepage: https://github.com/sass/dart-sass From 5c3f550a05cc4f9931f0f41814a7a6c61b937039 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 28 Oct 2020 15:47:31 -0700 Subject: [PATCH 9/9] Revert "Temporarily disable deploying to Chocolatey (#960)" (#1128) This reverts commit 01ed720e9c2eacd8d9f6f085ad5480ce1d3eec3f. Now that google/dart_cli_pkg#56 has landed, Chocolatey deployment should work again. --- .travis.yml | 14 ++++++++++++++ pubspec.yaml | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 60a2b49d5..0eca7da13 100644 --- a/.travis.yml +++ b/.travis.yml @@ -182,6 +182,20 @@ jobs: skip_cleanup: true on: {tags: true} + # Deploy to Chocolatey. + - name: Chocolatey + if: *deploy-if + os: windows + env: + # CHOCOLATEY_TOKEN="..." + - secure: "EnII3YAGESEl9g9rQDcrL1Sw9eww80VJP0qZHz8Da07GB0hUrDQBJ372Zs2A4qaH/GOm7cknszEPOnkE4w3IBwe5idj31Q+WJbcvqqAB1gex3bLYyStdHeohculqmPgpuEPD3yVT59viJIn6L9+GEKNtnCygDpgxMilXzDIXi6vtLqovJc6q09i7XCSnf2IVjzKv0VBSUV0lU9QOZui5/zLN0sCSzE8QKYj0QSoQ8Th3ZTuWn3/CtRYhIaw4/12oepHyXRvieMeNGnhv8O4d1lAOiXKn28COJWA+xvCOZSxIrBCc0k8VzanYftTcp1Zf0Lxkm0ObmFXWaoHATFWjkvW6G34kQrzRpUlWUMmxIxBukHc2ZFuGnVi6pL9ANI8BVh6m8M1ojRqtKCFvBbgDDdxD7qqBQSfdtssEL+m6O0U9A5/xnQxHPbuyL/Y9ww9p/ohEFaaF3MK/qjiWKQJR+TXspmNDBhFC+w2vQ6zetEx787V6POS8ma5MX1+WWOecDtaDuEMv4bzjkTuYk9tuBC4GR/KrdUNbFtcNXCk5To4Du4FBdOW/+yoVg+ZHtgOzSDehgMJMeFM2fTYNt55iwmjwDyS4XcqsWoHHCDMEhIcuXL5XV5VBENFgs98EGofja70Lp05oLH2W7100OuyG0H18lpECx15OXSFnHQh+91g=" + script: skip + deploy: + provider: script + script: pub run grinder pkg-chocolatey-deploy + skip_cleanup: true + on: {tags: true} + # Redeploy sass-lang.com. - name: sass-lang.com if: *deploy-if diff --git a/pubspec.yaml b/pubspec.yaml index e4a52a6f4..21f8c0dd9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -34,7 +34,7 @@ dependencies: dev_dependencies: archive: ">=1.0.0 <3.0.0" analyzer: "^0.40.0" - cli_pkg: "^1.0.0-beta.10" + cli_pkg: "^1.0.0-beta.12" crypto: ">=0.9.2 <3.0.0" dart_style: "^1.2.0" grinder: "^0.8.0"