From 3f09d46aff5edd473e212d9124989443f01fb9f5 Mon Sep 17 00:00:00 2001 From: Jennifer Thakar Date: Wed, 17 Jul 2024 13:13:03 -0700 Subject: [PATCH 1/7] Deprecate @import and global builtins --- CHANGELOG.md | 8 ++++++ lib/src/callable.dart | 3 +- lib/src/callable/async_built_in.dart | 21 ++++++++++++++ lib/src/callable/built_in.dart | 16 +++++++++++ lib/src/deprecation.dart | 10 +++++-- lib/src/functions/color.dart | 41 ++++++++++++++++++---------- lib/src/functions/list.dart | 11 ++++++-- lib/src/functions/map.dart | 12 ++++---- lib/src/functions/math.dart | 16 ++++++++--- lib/src/functions/meta.dart | 25 +++++++++-------- lib/src/functions/selector.dart | 16 +++++------ lib/src/functions/string.dart | 14 ++++++---- lib/src/parse/stylesheet.dart | 7 +++-- lib/src/visitor/async_evaluate.dart | 11 ++++++-- lib/src/visitor/evaluate.dart | 13 +++++++-- pkg/sass_api/CHANGELOG.md | 4 +++ pkg/sass_api/pubspec.yaml | 2 +- pubspec.yaml | 2 +- 18 files changed, 168 insertions(+), 64 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8533ae1c8..42dece320 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.78.0 + +* `@import` is now officially deprecated, as are global built-in functions that + are available within built-in modules. See [the Sass blog post] for more + details on the deprecation process. + +[the Sass blog]: https://sass-lang.com/blog/import-is-deprecated/ + ## 1.77.8 * No user-visible changes. diff --git a/lib/src/callable.dart b/lib/src/callable.dart index 2d2ed1e26..1fda63247 100644 --- a/lib/src/callable.dart +++ b/lib/src/callable.dart @@ -11,7 +11,8 @@ import 'utils.dart'; import 'value.dart'; export 'callable/async.dart'; -export 'callable/async_built_in.dart' show AsyncBuiltInCallable; +export 'callable/async_built_in.dart' + show AsyncBuiltInCallable, warnForGlobalBuiltIn; export 'callable/built_in.dart' show BuiltInCallable; export 'callable/plain_css.dart'; export 'callable/user_defined.dart'; diff --git a/lib/src/callable/async_built_in.dart b/lib/src/callable/async_built_in.dart index 7dba7e1cd..f75fa0055 100644 --- a/lib/src/callable/async_built_in.dart +++ b/lib/src/callable/async_built_in.dart @@ -5,6 +5,8 @@ import 'dart:async'; import '../ast/sass.dart'; +import '../deprecation.dart'; +import '../evaluation_context.dart'; import '../value.dart'; import 'async.dart'; @@ -83,4 +85,23 @@ class AsyncBuiltInCallable implements AsyncCallable { (ArgumentDeclaration, Callback) callbackFor( int positional, Set names) => (_arguments, _callback); + + /// Returns a copy of this callable that emits a deprecation warning. + AsyncBuiltInCallable withDeprecationWarning(String module, + [String? newName]) => + AsyncBuiltInCallable.parsed(name, _arguments, (args) { + warnForGlobalBuiltIn(module, newName ?? name); + return _callback(args); + }, acceptsContent: acceptsContent); +} + +/// Emits a deprecation warning for a global built-in function that is now +/// available as function [name] in built-in module [module]. +void warnForGlobalBuiltIn(String module, String name) { + warnForDeprecation( + 'Global built-in functions are deprecated and ' + 'will be removed in Dart Sass 3.0.0.\n' + 'Use $module.$name instead.\n\n' + 'More info and automated migrator: https://sass-lang.com/d/import', + Deprecation.globalBuiltin); } diff --git a/lib/src/callable/built_in.dart b/lib/src/callable/built_in.dart index a52662fa0..1d58df9fe 100644 --- a/lib/src/callable/built_in.dart +++ b/lib/src/callable/built_in.dart @@ -123,4 +123,20 @@ final class BuiltInCallable implements Callable, AsyncBuiltInCallable { /// Returns a copy of this callable with the given [name]. BuiltInCallable withName(String name) => BuiltInCallable._(name, _overloads, acceptsContent); + + /// Returns a copy of this callable that emits a deprecation warning. + BuiltInCallable withDeprecationWarning(String module, [String? newName]) => + BuiltInCallable._( + name, + [ + for (var (declaration, function) in _overloads) + ( + declaration, + (args) { + warnForGlobalBuiltIn(module, newName ?? name); + return function(args); + } + ) + ], + acceptsContent); } diff --git a/lib/src/deprecation.dart b/lib/src/deprecation.dart index b71960c47..12d7344b6 100644 --- a/lib/src/deprecation.dart +++ b/lib/src/deprecation.dart @@ -15,7 +15,7 @@ enum Deprecation { // DO NOT EDIT. This section was generated from the language repo. // See tool/grind/generate_deprecations.dart for details. // - // Checksum: 309e4f1f008f08379b824ab6094e13df2e18e187 + // Checksum: 89166027dc458357cbea646fd77fa44d9d7461cb /// Deprecation for passing a string directly to meta.call(). callString('call-string', @@ -96,7 +96,13 @@ enum Deprecation { description: 'Declarations after or between nested rules.'), /// Deprecation for @import rules. - import.future('import', description: '@import rules.'), + import('import', deprecatedIn: '1.78.0', description: '@import rules.'), + + /// Deprecation for global built-in functions that are available in sass: modules. + globalBuiltin('global-builtin', + deprecatedIn: '1.78.0', + description: + 'Global built-in functions that are available in sass: modules.'), // END AUTOGENERATED CODE diff --git a/lib/src/functions/color.dart b/lib/src/functions/color.dart index f71c8080f..11da3d638 100644 --- a/lib/src/functions/color.dart +++ b/lib/src/functions/color.dart @@ -23,7 +23,8 @@ final _microsoftFilterStart = RegExp(r'^[a-zA-Z]+\s*='); /// The global definitions of Sass color functions. final global = UnmodifiableListView([ // ### RGB - _red, _green, _blue, _mix, + _red.withDeprecationWarning('color'), _green.withDeprecationWarning('color'), + _blue.withDeprecationWarning('color'), _mix.withDeprecationWarning('color'), BuiltInCallable.overloadedFunction("rgb", { r"$red, $green, $blue, $alpha": (arguments) => _rgb("rgb", arguments), @@ -66,10 +67,13 @@ final global = UnmodifiableListView([ red: 255 - color.red, green: 255 - color.green, blue: 255 - color.blue); return _mixColors(inverse, color, weight); - }), + }).withDeprecationWarning('color'), // ### HSL - _hue, _saturation, _lightness, _complement, + _hue.withDeprecationWarning('color'), + _saturation.withDeprecationWarning('color'), + _lightness.withDeprecationWarning('color'), + _complement.withDeprecationWarning('color'), BuiltInCallable.overloadedFunction("hsl", { r"$hue, $saturation, $lightness, $alpha": (arguments) => @@ -116,7 +120,7 @@ final global = UnmodifiableListView([ // Use the native CSS `grayscale` filter function. return _functionString('grayscale', arguments); } - + warnForGlobalBuiltIn('color', 'grayscale'); var color = arguments[0].assertColor("color"); return color.changeHsl(saturation: 0); }), @@ -125,7 +129,7 @@ final global = UnmodifiableListView([ var color = arguments[0].assertColor("color"); var degrees = _angleValue(arguments[1], "degrees"); return color.changeHsl(hue: color.hue + degrees); - }), + }).withDeprecationWarning('color', 'adjust'), _function("lighten", r"$color, $amount", (arguments) { var color = arguments[0].assertColor("color"); @@ -133,7 +137,7 @@ final global = UnmodifiableListView([ return color.changeHsl( lightness: (color.lightness + amount.valueInRange(0, 100, "amount")) .clamp(0, 100)); - }), + }).withDeprecationWarning('color', 'adjust'), _function("darken", r"$color, $amount", (arguments) { var color = arguments[0].assertColor("color"); @@ -141,7 +145,7 @@ final global = UnmodifiableListView([ return color.changeHsl( lightness: (color.lightness - amount.valueInRange(0, 100, "amount")) .clamp(0, 100)); - }), + }).withDeprecationWarning('color', 'adjust'), BuiltInCallable.overloadedFunction("saturate", { r"$amount": (arguments) { @@ -153,6 +157,7 @@ final global = UnmodifiableListView([ return SassString("saturate(${number.toCssString()})", quotes: false); }, r"$color, $amount": (arguments) { + warnForGlobalBuiltIn('color', 'adjust'); var color = arguments[0].assertColor("color"); var amount = arguments[1].assertNumber("amount"); return color.changeHsl( @@ -167,13 +172,17 @@ final global = UnmodifiableListView([ return color.changeHsl( saturation: (color.saturation - amount.valueInRange(0, 100, "amount")) .clamp(0, 100)); - }), + }).withDeprecationWarning('color', 'adjust'), // ### Opacity - _function("opacify", r"$color, $amount", _opacify), - _function("fade-in", r"$color, $amount", _opacify), - _function("transparentize", r"$color, $amount", _transparentize), - _function("fade-out", r"$color, $amount", _transparentize), + _function("opacify", r"$color, $amount", _opacify) + .withDeprecationWarning('color', 'adjust'), + _function("fade-in", r"$color, $amount", _opacify) + .withDeprecationWarning('color', 'adjust'), + _function("transparentize", r"$color, $amount", _transparentize) + .withDeprecationWarning('color', 'adjust'), + _function("fade-out", r"$color, $amount", _transparentize) + .withDeprecationWarning('color', 'adjust'), BuiltInCallable.overloadedFunction("alpha", { r"$color": (arguments) { @@ -184,6 +193,7 @@ final global = UnmodifiableListView([ // Support the proprietary Microsoft alpha() function. return _functionString("alpha", arguments); } + warnForGlobalBuiltIn('color', 'alpha'); var color = argument.assertColor("color"); return SassNumber(color.alpha); @@ -215,15 +225,16 @@ final global = UnmodifiableListView([ return _functionString("opacity", arguments); } + warnForGlobalBuiltIn('color', 'opacity'); var color = arguments[0].assertColor("color"); return SassNumber(color.alpha); }), // ### Miscellaneous _ieHexStr, - _adjust.withName("adjust-color"), - _scale.withName("scale-color"), - _change.withName("change-color") + _adjust.withDeprecationWarning('color').withName("adjust-color"), + _scale.withDeprecationWarning('color').withName("scale-color"), + _change.withDeprecationWarning('color').withName("change-color") ]); /// The Sass color module. diff --git a/lib/src/functions/list.dart b/lib/src/functions/list.dart index 1d911a88d..c0fd0ac2c 100644 --- a/lib/src/functions/list.dart +++ b/lib/src/functions/list.dart @@ -13,8 +13,15 @@ import '../value.dart'; /// The global definitions of Sass list functions. final global = UnmodifiableListView([ - _length, _nth, _setNth, _join, _append, _zip, _index, _isBracketed, // - _separator.withName("list-separator") + _length.withDeprecationWarning('list'), + _nth.withDeprecationWarning('list'), + _setNth.withDeprecationWarning('list'), + _join.withDeprecationWarning('list'), + _append.withDeprecationWarning('list'), + _zip.withDeprecationWarning('list'), + _index.withDeprecationWarning('list'), + _isBracketed.withDeprecationWarning('list'), + _separator.withDeprecationWarning('list').withName("list-separator") ]); /// The Sass list module. diff --git a/lib/src/functions/map.dart b/lib/src/functions/map.dart index 97628c1fd..50274da08 100644 --- a/lib/src/functions/map.dart +++ b/lib/src/functions/map.dart @@ -15,12 +15,12 @@ import '../value.dart'; /// The global definitions of Sass map functions. final global = UnmodifiableListView([ - _get.withName("map-get"), - _merge.withName("map-merge"), - _remove.withName("map-remove"), - _keys.withName("map-keys"), - _values.withName("map-values"), - _hasKey.withName("map-has-key") + _get.withDeprecationWarning('map').withName("map-get"), + _merge.withDeprecationWarning('map').withName("map-merge"), + _remove.withDeprecationWarning('map').withName("map-remove"), + _keys.withDeprecationWarning('map').withName("map-keys"), + _values.withDeprecationWarning('map').withName("map-values"), + _hasKey.withDeprecationWarning('map').withName("map-has-key") ]); /// The Sass map module. diff --git a/lib/src/functions/math.dart b/lib/src/functions/math.dart index bca609d0d..3f3e3bbbe 100644 --- a/lib/src/functions/math.dart +++ b/lib/src/functions/math.dart @@ -30,15 +30,23 @@ final global = UnmodifiableListView([ "To emit a CSS abs() now: abs(#{$number})\n" "More info: https://sass-lang.com/d/abs-percent", Deprecation.absPercent); + } else { + warnForGlobalBuiltIn('math', 'abs'); } return SassNumber.withUnits(number.value.abs(), numeratorUnits: number.numeratorUnits, denominatorUnits: number.denominatorUnits); }), - - _ceil, _floor, _max, _min, _percentage, _randomFunction, _round, _unit, // - _compatible.withName("comparable"), - _isUnitless.withName("unitless"), + _ceil.withDeprecationWarning('math'), + _floor.withDeprecationWarning('math'), + _max.withDeprecationWarning('math'), + _min.withDeprecationWarning('math'), + _percentage.withDeprecationWarning('math'), + _randomFunction.withDeprecationWarning('math'), + _round.withDeprecationWarning('math'), + _unit.withDeprecationWarning('math'), + _compatible.withDeprecationWarning('math').withName("comparable"), + _isUnitless.withDeprecationWarning('math').withName("unitless"), ]); /// The Sass math module. diff --git a/lib/src/functions/meta.dart b/lib/src/functions/meta.dart index a3b683b9a..532f4de47 100644 --- a/lib/src/functions/meta.dart +++ b/lib/src/functions/meta.dart @@ -20,19 +20,18 @@ final _features = { "custom-property" }; -/// The global definitions of Sass introspection functions. -final global = UnmodifiableListView([ - // This is only a partial list of meta functions. The rest are defined in the - // evaluator, because they need access to context that's only available at - // runtime. +/// Sass introspection functions that exist as both global functions and in the +/// `sass:meta` module that do not require access to context that's only +/// available at runtime. +/// +/// Additional functions are defined in the evaluator. +final _shared = UnmodifiableListView([ _function("feature-exists", r"$feature", (arguments) { var feature = arguments[0].assertString("feature"); return SassBoolean(_features.contains(feature.text)); }), - _function("inspect", r"$value", (arguments) => SassString(arguments.first.toString(), quotes: false)), - _function( "type-of", r"$value", @@ -52,7 +51,6 @@ final global = UnmodifiableListView([ _ => throw "[BUG] Unknown value type ${arguments[0]}" }, quotes: false)), - _function("keywords", r"$args", (arguments) { if (arguments[0] case SassArgumentList(:var keywords)) { return SassMap({ @@ -65,9 +63,14 @@ final global = UnmodifiableListView([ }) ]); -/// The definitions of Sass introspection functions that are only available from -/// the `sass:meta` module, not as global functions. -final local = UnmodifiableListView([ +/// The global definitions of Sass introspection functions. +final global = UnmodifiableListView( + [for (var function in _shared) function.withDeprecationWarning('meta')]); + +/// The versions of Sass introspection functions defined in the `sass:meta` +/// module. +final moduleFunctions = UnmodifiableListView([ + ..._shared, _function("calc-name", r"$calc", (arguments) { var calculation = arguments[0].assertCalculation("calc"); return SassString(calculation.name); diff --git a/lib/src/functions/selector.dart b/lib/src/functions/selector.dart index 08e133dbf..7a32af1a2 100644 --- a/lib/src/functions/selector.dart +++ b/lib/src/functions/selector.dart @@ -16,14 +16,14 @@ import '../value.dart'; /// The global definitions of Sass selector functions. final global = UnmodifiableListView([ - _isSuperselector, - _simpleSelectors, - _parse.withName("selector-parse"), - _nest.withName("selector-nest"), - _append.withName("selector-append"), - _extend.withName("selector-extend"), - _replace.withName("selector-replace"), - _unify.withName("selector-unify") + _isSuperselector.withDeprecationWarning('selector'), + _simpleSelectors.withDeprecationWarning('selector'), + _parse.withDeprecationWarning('selector').withName("selector-parse"), + _nest.withDeprecationWarning('selector').withName("selector-nest"), + _append.withDeprecationWarning('selector').withName("selector-append"), + _extend.withDeprecationWarning('selector').withName("selector-extend"), + _replace.withDeprecationWarning('selector').withName("selector-replace"), + _unify.withDeprecationWarning('selector').withName("selector-unify") ]); /// The Sass selector module. diff --git a/lib/src/functions/string.dart b/lib/src/functions/string.dart index 99d1ee6d2..100337de9 100644 --- a/lib/src/functions/string.dart +++ b/lib/src/functions/string.dart @@ -22,11 +22,15 @@ var _previousUniqueId = _random.nextInt(math.pow(36, 6) as int); /// The global definitions of Sass string functions. final global = UnmodifiableListView([ - _unquote, _quote, _toUpperCase, _toLowerCase, _uniqueId, // - _length.withName("str-length"), - _insert.withName("str-insert"), - _index.withName("str-index"), - _slice.withName("str-slice") + _unquote.withDeprecationWarning('string'), + _quote.withDeprecationWarning('string'), + _toUpperCase.withDeprecationWarning('string'), + _toLowerCase.withDeprecationWarning('string'), + _uniqueId.withDeprecationWarning('string'), + _length.withDeprecationWarning('string').withName("str-length"), + _insert.withDeprecationWarning('string').withName("str-insert"), + _index.withDeprecationWarning('string').withName("str-index"), + _slice.withDeprecationWarning('string').withName("str-slice") ]); /// The Sass string module. diff --git a/lib/src/parse/stylesheet.dart b/lib/src/parse/stylesheet.dart index eace75790..ae0bd3cf2 100644 --- a/lib/src/parse/stylesheet.dart +++ b/lib/src/parse/stylesheet.dart @@ -1052,9 +1052,10 @@ abstract class StylesheetParser extends Parser { if (argument is DynamicImport) { logger.warnForDeprecation( Deprecation.import, - 'Sass @import rules will be deprecated in the future.\n' - 'Remove the --future-deprecation=import flag to silence this ' - 'warning for now.', + 'Sass @import rules are deprecated ' + 'and will be removed in Dart Sass 3.0.0.\n\n' + 'More info and automated migrator: ' + 'https://sass-lang.com/d/import', span: argument.span); } if ((_inControlDirective || _inMixin) && argument is DynamicImport) { diff --git a/lib/src/visitor/async_evaluate.dart b/lib/src/visitor/async_evaluate.dart index e4a65d12e..c15e89ead 100644 --- a/lib/src/visitor/async_evaluate.dart +++ b/lib/src/visitor/async_evaluate.dart @@ -575,14 +575,21 @@ final class _EvaluateVisitor ]; var metaModule = BuiltInModule("meta", - functions: [...meta.global, ...meta.local, ...metaFunctions], + functions: [...meta.moduleFunctions, ...metaFunctions], mixins: metaMixins); for (var module in [...coreModules, metaModule]) { _builtInModules[module.url] = module; } - functions = [...?functions, ...globalFunctions, ...metaFunctions]; + functions = [ + ...?functions, + ...globalFunctions, + ...[ + for (var function in metaFunctions) + function.withDeprecationWarning('meta') + ] + ]; for (var function in functions) { _builtInFunctions[function.name.replaceAll("_", "-")] = function; } diff --git a/lib/src/visitor/evaluate.dart b/lib/src/visitor/evaluate.dart index cc2458bab..ea269eca7 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: ebf292c26dcfdd7f61fd70ce3dc9e0be2b6708b3 +// Checksum: 7c9bf2bbcb89bc05c6b05f171bed504f3d8fe2a4 // // ignore_for_file: unused_import @@ -577,14 +577,21 @@ final class _EvaluateVisitor ]; var metaModule = BuiltInModule("meta", - functions: [...meta.global, ...meta.local, ...metaFunctions], + functions: [...meta.moduleFunctions, ...metaFunctions], mixins: metaMixins); for (var module in [...coreModules, metaModule]) { _builtInModules[module.url] = module; } - functions = [...?functions, ...globalFunctions, ...metaFunctions]; + functions = [ + ...?functions, + ...globalFunctions, + ...[ + for (var function in metaFunctions) + function.withDeprecationWarning('meta') + ] + ]; for (var function in functions) { _builtInFunctions[function.name.replaceAll("_", "-")] = function; } diff --git a/pkg/sass_api/CHANGELOG.md b/pkg/sass_api/CHANGELOG.md index 7753afacf..00dc18b80 100644 --- a/pkg/sass_api/CHANGELOG.md +++ b/pkg/sass_api/CHANGELOG.md @@ -1,3 +1,7 @@ +## 10.4.9 + +* No user-visible changes. + ## 10.4.8 * No user-visible changes. diff --git a/pkg/sass_api/pubspec.yaml b/pkg/sass_api/pubspec.yaml index 565bb7d8d..238d3ce4d 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: 10.4.8 +version: 10.4.9 description: Additional APIs for Dart Sass. homepage: https://github.com/sass/dart-sass diff --git a/pubspec.yaml b/pubspec.yaml index 1c78769ae..4b0f45913 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: sass -version: 1.77.8 +version: 1.78.0 description: A Sass implementation in Dart. homepage: https://github.com/sass/dart-sass From db077c4f0f30d482e2d020b2309d9b61e59247c3 Mon Sep 17 00:00:00 2001 From: Jennifer Thakar Date: Wed, 17 Jul 2024 17:43:01 -0700 Subject: [PATCH 2/7] Update cli and API tests --- pkg/sass_api/CHANGELOG.md | 2 +- pkg/sass_api/pubspec.yaml | 6 +- pubspec.yaml | 2 +- test/cli/dart/errors_test.dart | 8 +-- test/cli/node/errors_test.dart | 8 +-- test/cli/shared.dart | 57 ++++++++++++------ test/cli/shared/deprecations.dart | 9 +-- test/cli/shared/source_maps.dart | 6 +- test/cli/shared/update.dart | 14 ++--- test/cli/shared/watch.dart | 39 ++++++------ test/dart_api/importer_test.dart | 46 +++++++------- test/dart_api/logger_test.dart | 8 +-- test/dart_api_test.dart | 46 +++++++------- test/embedded/file_importer_test.dart | 41 +++++++------ test/embedded/function_test.dart | 25 +++++--- test/embedded/importer_test.dart | 86 +++++++++++++-------------- test/embedded/protocol_test.dart | 2 +- 17 files changed, 215 insertions(+), 190 deletions(-) diff --git a/pkg/sass_api/CHANGELOG.md b/pkg/sass_api/CHANGELOG.md index 00dc18b80..cbedd7005 100644 --- a/pkg/sass_api/CHANGELOG.md +++ b/pkg/sass_api/CHANGELOG.md @@ -1,4 +1,4 @@ -## 10.4.9 +## 10.5.0 * No user-visible changes. diff --git a/pkg/sass_api/pubspec.yaml b/pkg/sass_api/pubspec.yaml index 238d3ce4d..8366c2b06 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: 10.4.9 +version: 10.5.0 description: Additional APIs for Dart Sass. homepage: https://github.com/sass/dart-sass @@ -10,10 +10,10 @@ environment: sdk: ">=3.0.0 <4.0.0" dependencies: - sass: 1.77.8 + sass: 1.78.0 dev_dependencies: - dartdoc: ">=6.0.0 <9.0.0" + dartdoc: ^8.0.11 dependency_overrides: sass: { path: ../.. } diff --git a/pubspec.yaml b/pubspec.yaml index 4b0f45913..f03108c2d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -42,7 +42,7 @@ dev_dependencies: archive: ^3.1.2 crypto: ^3.0.0 dart_style: ^2.0.0 - dartdoc: ">=6.0.0 <9.0.0" + dartdoc: ^8.0.11 grinder: ^0.9.0 node_preamble: ^2.0.2 lints: ">=2.0.0 <5.0.0" diff --git a/test/cli/dart/errors_test.dart b/test/cli/dart/errors_test.dart index 478d2129f..e9d18da8d 100644 --- a/test/cli/dart/errors_test.dart +++ b/test/cli/dart/errors_test.dart @@ -15,7 +15,7 @@ void main() { sharedTests(runSass); test("for package urls", () async { - await d.file("test.scss", "@import 'package:nope/test';").create(); + await d.file("test.scss", "@use 'package:nope/test';").create(); var sass = await runSass(["--no-unicode", "test.scss"]); expect( @@ -23,10 +23,10 @@ void main() { emitsInOrder([ "Error: Can't find stylesheet to import.", " ,", - "1 | @import 'package:nope/test';", - " | ^^^^^^^^^^^^^^^^^^^", + "1 | @use 'package:nope/test';", + " | ^^^^^^^^^^^^^^^^^^^^^^^^", " '", - " test.scss 1:9 root stylesheet" + " test.scss 1:1 root stylesheet" ])); await sass.shouldExit(65); }); diff --git a/test/cli/node/errors_test.dart b/test/cli/node/errors_test.dart index 87220b350..29b4ae689 100644 --- a/test/cli/node/errors_test.dart +++ b/test/cli/node/errors_test.dart @@ -17,7 +17,7 @@ void main() { sharedTests(runSass); test("for package urls", () async { - await d.file("test.scss", "@import 'package:nope/test';").create(); + await d.file("test.scss", "@use 'package:nope/test';").create(); var sass = await runSass(["--no-unicode", "test.scss"]); expect( @@ -25,10 +25,10 @@ void main() { emitsInOrder([ "Error: \"package:\" URLs aren't supported on this platform.", " ,", - "1 | @import 'package:nope/test';", - " | ^^^^^^^^^^^^^^^^^^^", + "1 | @use 'package:nope/test';", + " | ^^^^^^^^^^^^^^^^^^^^^^^^", " '", - " test.scss 1:9 root stylesheet" + " test.scss 1:1 root stylesheet" ])); await sass.shouldExit(65); }); diff --git a/test/cli/shared.dart b/test/cli/shared.dart index 63c990685..09ea953bd 100644 --- a/test/cli/shared.dart +++ b/test/cli/shared.dart @@ -110,7 +110,7 @@ void sharedTests( group("can import files", () { test("relative to the entrypoint", () async { - await d.file("test.scss", "@import 'dir/test'").create(); + await d.file("test.scss", "@use 'dir/test'").create(); await d.dir("dir", [d.file("test.scss", "a {b: 1 + 2}")]).create(); @@ -119,7 +119,7 @@ void sharedTests( }); test("from the load path", () async { - await d.file("test.scss", "@import 'test2'").create(); + await d.file("test.scss", "@use 'test2'").create(); await d.dir("dir", [d.file("test2.scss", "a {b: c}")]).create(); @@ -129,8 +129,8 @@ void sharedTests( test("from SASS_PATH", () async { await d.file("test.scss", """ - @import 'test2'; - @import 'test3'; + @use 'test2'; + @use 'test3'; """).create(); await d.dir("dir2", [d.file("test2.scss", "a {b: c}")]).create(); @@ -145,12 +145,12 @@ void sharedTests( // Regression test for #369 test("from within a directory, relative to a file on the load path", () async { - await d.dir( - "dir1", [d.file("test.scss", "@import 'subdir/test2'")]).create(); + await d + .dir("dir1", [d.file("test.scss", "@use 'subdir/test2'")]).create(); await d.dir("dir2", [ d.dir("subdir", [ - d.file("test2.scss", "@import 'test3'"), + d.file("test2.scss", "@use 'test3'"), d.file("test3.scss", "a {b: c}") ]) ]).create(); @@ -160,7 +160,7 @@ void sharedTests( }); test("relative in preference to from the load path", () async { - await d.file("test.scss", "@import 'test2'").create(); + await d.file("test.scss", "@use 'test2'").create(); await d.file("test2.scss", "x {y: z}").create(); await d.dir("dir", [d.file("test2.scss", "a {b: c}")]).create(); @@ -170,7 +170,7 @@ void sharedTests( }); test("in load path order", () async { - await d.file("test.scss", "@import 'test2'").create(); + await d.file("test.scss", "@use 'test2'").create(); await d.dir("dir1", [d.file("test2.scss", "a {b: c}")]).create(); await d.dir("dir2", [d.file("test2.scss", "x {y: z}")]).create(); @@ -181,7 +181,7 @@ void sharedTests( }); test("from the load path in preference to from SASS_PATH", () async { - await d.file("test.scss", "@import 'test2'").create(); + await d.file("test.scss", "@use 'test2'").create(); await d.dir("dir1", [d.file("test2.scss", "a {b: c}")]).create(); await d.dir("dir2", [d.file("test2.scss", "x {y: z}")]).create(); @@ -192,7 +192,7 @@ void sharedTests( }); test("in SASS_PATH order", () async { - await d.file("test.scss", "@import 'test2'").create(); + await d.file("test.scss", "@use 'test2'").create(); await d.dir("dir1", [d.file("test2.scss", "a {b: c}")]).create(); await d.dir("dir2", [d.file("test2.scss", "x {y: z}")]).create(); @@ -224,6 +224,8 @@ void sharedTests( "grandparent", "--load-path", "grandparent/parent", + "--silence-deprecation", + "import", "test.scss" ], equalsIgnoringWhitespace("a { b: c; } a { b: c; }")); }); @@ -240,8 +242,13 @@ void sharedTests( d.file("_library.import.scss", "a { b: import-only }") ]).create(); - await expectCompiles(["--load-path", "load-path", "test.scss"], - equalsIgnoringWhitespace("a { b: regular; } a { b: import-only; }")); + await expectCompiles([ + "--load-path", + "load-path", + "--silence-deprecation", + "import", + "test.scss" + ], equalsIgnoringWhitespace("a { b: regular; } a { b: import-only; }")); }); }); @@ -487,7 +494,14 @@ void sharedTests( await d.file("test.scss", "@import 'other'").create(); await d.dir("dir", [d.file("_other.scss", "#{blue} {x: y}")]).create(); - var sass = await runSass(["--quiet-deps", "-I", "dir", "test.scss"]); + var sass = await runSass([ + "--quiet-deps", + "-I", + "dir", + "--silence-deprecation", + "import", + "test.scss" + ]); expect(sass.stderr, emitsDone); await sass.shouldExit(0); }); @@ -501,7 +515,14 @@ void sharedTests( """) ]).create(); - var sass = await runSass(["--quiet-deps", "-I", "dir", "test.scss"]); + var sass = await runSass([ + "--quiet-deps", + "-I", + "dir", + "--silence-deprecation", + "import", + "test.scss" + ]); expect(sass.stderr, emitsDone); await sass.shouldExit(0); }); @@ -877,7 +898,8 @@ void sharedTests( expect(sass.stdout, emitsDone); await sass.shouldExit(65); }); - }); + // Skipping while no future deprecations exist + }, skip: true); test("doesn't unassign variables", () async { // This is a regression test for one of the strangest errors I've ever @@ -896,7 +918,8 @@ void sharedTests( await d.file("_midstream.scss", "@forward 'upstream'").create(); await d.file("_upstream.scss", r"$c: g").create(); - var sass = await runSass(["input.scss", "output.css"]); + var sass = await runSass( + ["--silence-deprecation", "import", "input.scss", "output.css"]); await sass.shouldExit(0); await d.file("output.css", equalsIgnoringWhitespace(""" diff --git a/test/cli/shared/deprecations.dart b/test/cli/shared/deprecations.dart index 03f1b4dc2..a956a9572 100644 --- a/test/cli/shared/deprecations.dart +++ b/test/cli/shared/deprecations.dart @@ -29,7 +29,7 @@ void sharedTests(Future runSass(Iterable arguments)) { var sass = await runSass(["--silence-deprecation=import", "test.scss"]); expect(sass.stderr, emits(contains("Future import deprecation"))); await sass.shouldExit(0); - }); + }, skip: true); test("for an active future deprecation", () async { var sass = await runSass([ @@ -39,7 +39,7 @@ void sharedTests(Future runSass(Iterable arguments)) { ]); expect(sass.stderr, emits(contains("Conflicting options for future"))); await sass.shouldExit(0); - }); + }, skip: true); test("in watch mode", () async { var sass = await runSass([ @@ -183,7 +183,7 @@ void sharedTests(Future runSass(Iterable arguments)) { var sass = await runSass(["--fatal-deprecation=import", "test.scss"]); expect(sass.stderr, emits(contains("Future import deprecation"))); await sass.shouldExit(0); - }); + }, skip: true); test("for a silent deprecation", () async { var sass = await runSass([ @@ -493,5 +493,6 @@ void sharedTests(Future runSass(Iterable arguments)) { }); }); }); - }); + // Skipping while no future deprecations exist + }, skip: true); } diff --git a/test/cli/shared/source_maps.dart b/test/cli/shared/source_maps.dart index 75035b3b4..a2d0ad2e4 100644 --- a/test/cli/shared/source_maps.dart +++ b/test/cli/shared/source_maps.dart @@ -43,7 +43,7 @@ void sharedTests(Future runSass(Iterable arguments)) { group("with multiple sources", () { setUp(() async { await d.file("test.scss", """ - @import 'dir/other'; + @use 'dir/other'; x {y: z} """).create(); await d.dir("dir", [d.file("other.scss", "a {b: 1 + 2}")]).create(); @@ -96,7 +96,7 @@ void sharedTests(Future runSass(Iterable arguments)) { }); test("when imported with the same case", () async { - await d.file("importer.scss", "@import 'TeSt.scss'").create(); + await d.file("importer.scss", "@use 'TeSt.scss'").create(); await (await runSass(["importer.scss", "out.css"])).shouldExit(0); expect(_readJson("out.css.map"), containsPair("sources", ["TeSt.scss"])); }); @@ -109,7 +109,7 @@ void sharedTests(Future runSass(Iterable arguments)) { }, testOn: "windows"); test("when imported with a different case", () async { - await d.file("importer.scss", "@import 'test.scss'").create(); + await d.file("importer.scss", "@use 'test.scss'").create(); await (await runSass(["importer.scss", "out.css"])).shouldExit(0); expect(_readJson("out.css.map"), containsPair("sources", ["TeSt.scss"])); }, testOn: "windows"); diff --git a/test/cli/shared/update.dart b/test/cli/shared/update.dart index 73b8a21df..260c1d132 100644 --- a/test/cli/shared/update.dart +++ b/test/cli/shared/update.dart @@ -43,7 +43,7 @@ void sharedTests(Future runSass(Iterable arguments)) { test("whose source was transitively modified", () async { await d.file("other.scss", "a {b: c}").create(); - await d.file("test.scss", "@import 'other'").create(); + await d.file("test.scss", "@use 'other'").create(); var sass = await update(["test.scss:out.css"]); expect(sass.stdout, emits(endsWith('Compiled test.scss to out.css.'))); @@ -177,26 +177,26 @@ void sharedTests(Future runSass(Iterable arguments)) { }); test("with a missing import", () async { - await d.file("test.scss", "@import 'other'").create(); + await d.file("test.scss", "@use 'other'").create(); var message = "Error: Can't find stylesheet to import."; var sass = await update(["test.scss:out.css"]); expect(sass.stderr, emits(message)); - expect(sass.stderr, emitsThrough(contains("test.scss 1:9"))); + expect(sass.stderr, emitsThrough(contains("test.scss 1:1"))); await sass.shouldExit(65); await d.file("out.css", contains(message)).validate(); }); test("with a conflicting import", () async { - await d.file("test.scss", "@import 'other'").create(); + await d.file("test.scss", "@use 'other'").create(); await d.file("other.scss", "a {b: c}").create(); await d.file("_other.scss", "x {y: z}").create(); var message = "Error: It's not clear which file to import. Found:"; var sass = await update(["test.scss:out.css"]); expect(sass.stderr, emits(message)); - expect(sass.stderr, emitsThrough(contains("test.scss 1:9"))); + expect(sass.stderr, emitsThrough(contains("test.scss 1:1"))); await sass.shouldExit(65); await d.file("out.css", contains(message)).validate(); @@ -257,7 +257,7 @@ void sharedTests(Future runSass(Iterable arguments)) { }); test("when an import is removed", () async { - await d.file("test.scss", "@import 'other'").create(); + await d.file("test.scss", "@use 'other'").create(); await d.file("_other.scss", "a {b: c}").create(); await (await update(["test.scss:out.css"])).shouldExit(0); await d.file("out.css", anything).validate(); @@ -266,7 +266,7 @@ void sharedTests(Future runSass(Iterable arguments)) { d.file("_other.scss").io.deleteSync(); var sass = await update(["test.scss:out.css"]); expect(sass.stderr, emits(message)); - expect(sass.stderr, emitsThrough(contains("test.scss 1:9"))); + expect(sass.stderr, emitsThrough(contains("test.scss 1:1"))); await sass.shouldExit(65); await d.file("out.css", contains(message)).validate(); diff --git a/test/cli/shared/watch.dart b/test/cli/shared/watch.dart index b80b33e64..f2bfc6d12 100644 --- a/test/cli/shared/watch.dart +++ b/test/cli/shared/watch.dart @@ -208,7 +208,8 @@ void sharedTests(Future runSass(Iterable arguments)) { await d.file("_other.scss", "a {b: c}").create(); await d.file("test.scss", "@import 'other'").create(); - var sass = await watch(["test.scss:out.css"]); + var sass = await watch( + ["--silence-deprecation", "import", "test.scss:out.css"]); await expectLater( sass.stdout, emits(endsWith('Compiled test.scss to out.css.'))); await expectLater(sass.stdout, _watchingForChanges); @@ -361,7 +362,7 @@ void sharedTests(Future runSass(Iterable arguments)) { // Regression test for #550 test("with an error that's later fixed", () async { await d.file("_other.scss", "a {b: c}").create(); - await d.file("test.scss", "@import 'other'").create(); + await d.file("test.scss", "@use 'other'").create(); var sass = await watch(["test.scss:out.css"]); await expectLater( @@ -373,7 +374,7 @@ void sharedTests(Future runSass(Iterable arguments)) { await expectLater( sass.stderr, emits('Error: Expected expression.')); await expectLater( - sass.stderr, emitsThrough(contains('test.scss 1:9'))); + sass.stderr, emitsThrough(contains('test.scss 1:1'))); await tickIfPoll(); await d.file("_other.scss", "q {r: s}").create(); @@ -466,7 +467,7 @@ void sharedTests(Future runSass(Iterable arguments)) { group("when its dependency is deleted", () { test("and updates the output", () async { await d.file("_other.scss", "a {b: c}").create(); - await d.file("test.scss", "@import 'other'").create(); + await d.file("test.scss", "@use 'other'").create(); var sass = await watch(["test.scss:out.css"]); await expectLater( @@ -478,7 +479,7 @@ void sharedTests(Future runSass(Iterable arguments)) { d.file("_other.scss").io.deleteSync(); await expectLater(sass.stderr, emits(message)); await expectLater( - sass.stderr, emitsThrough(contains('test.scss 1:9'))); + sass.stderr, emitsThrough(contains('test.scss 1:1'))); await sass.kill(); await d.file("out.css", contains(message)).validate(); @@ -486,7 +487,7 @@ void sharedTests(Future runSass(Iterable arguments)) { test("but another is available", () async { await d.file("_other.scss", "a {b: c}").create(); - await d.file("test.scss", "@import 'other'").create(); + await d.file("test.scss", "@use 'other'").create(); await d.dir("dir", [d.file("_other.scss", "x {y: z}")]).create(); var sass = await watch(["-I", "dir", "test.scss:out.css"]); @@ -508,7 +509,7 @@ void sharedTests(Future runSass(Iterable arguments)) { test("which resolves a conflict", () async { await d.file("_other.scss", "a {b: c}").create(); await d.file("_other.sass", "x\n y: z").create(); - await d.file("test.scss", "@import 'other'").create(); + await d.file("test.scss", "@use 'other'").create(); var sass = await watch(["test.scss:out.css"]); await expectLater(sass.stderr, @@ -530,13 +531,13 @@ void sharedTests(Future runSass(Iterable arguments)) { group("when a dependency is added", () { group("that was missing", () { test("relative to the file", () async { - await d.file("test.scss", "@import 'other'").create(); + await d.file("test.scss", "@use 'other'").create(); var sass = await watch(["test.scss:out.css"]); await expectLater(sass.stderr, emits("Error: Can't find stylesheet to import.")); await expectLater( - sass.stderr, emitsThrough(contains("test.scss 1:9"))); + sass.stderr, emitsThrough(contains("test.scss 1:1"))); await expectLater(sass.stdout, _watchingForChanges); await tickIfPoll(); @@ -551,14 +552,14 @@ void sharedTests(Future runSass(Iterable arguments)) { }); test("on a load path", () async { - await d.file("test.scss", "@import 'other'").create(); + await d.file("test.scss", "@use 'other'").create(); await d.dir("dir").create(); var sass = await watch(["-I", "dir", "test.scss:out.css"]); await expectLater(sass.stderr, emits("Error: Can't find stylesheet to import.")); await expectLater( - sass.stderr, emitsThrough(contains("test.scss 1:9"))); + sass.stderr, emitsThrough(contains("test.scss 1:1"))); await expectLater(sass.stdout, _watchingForChanges); await tickIfPoll(); @@ -573,14 +574,14 @@ void sharedTests(Future runSass(Iterable arguments)) { }); test("on a load path that was created", () async { - await d.dir( - "dir1", [d.file("test.scss", "@import 'other'")]).create(); + await d + .dir("dir1", [d.file("test.scss", "@use 'other'")]).create(); var sass = await watch(["-I", "dir2", "dir1:out"]); await expectLater(sass.stderr, emits("Error: Can't find stylesheet to import.")); await expectLater(sass.stderr, - emitsThrough(contains("${p.join('dir1', 'test.scss')} 1:9"))); + emitsThrough(contains("${p.join('dir1', 'test.scss')} 1:1"))); await expectLater(sass.stdout, _watchingForChanges); await tickIfPoll(); @@ -597,7 +598,7 @@ void sharedTests(Future runSass(Iterable arguments)) { test("that conflicts with the previous dependency", () async { await d.file("_other.scss", "a {b: c}").create(); - await d.file("test.scss", "@import 'other'").create(); + await d.file("test.scss", "@use 'other'").create(); var sass = await watch(["test.scss:out.css"]); await expectLater( @@ -615,7 +616,7 @@ void sharedTests(Future runSass(Iterable arguments)) { group("that overrides the previous dependency", () { test("on an import path", () async { - await d.file("test.scss", "@import 'other'").create(); + await d.file("test.scss", "@use 'other'").create(); await d.dir("dir2", [d.file("_other.scss", "a {b: c}")]).create(); await d.dir("dir1").create(); @@ -637,7 +638,7 @@ void sharedTests(Future runSass(Iterable arguments)) { }); test("because it's relative", () async { - await d.file("test.scss", "@import 'other'").create(); + await d.file("test.scss", "@use 'other'").create(); await d.dir("dir", [d.file("_other.scss", "a {b: c}")]).create(); var sass = await watch(["-I", "dir", "test.scss:out.css"]); @@ -657,7 +658,7 @@ void sharedTests(Future runSass(Iterable arguments)) { }); test("because it's not an index", () async { - await d.file("test.scss", "@import 'other'").create(); + await d.file("test.scss", "@use 'other'").create(); await d .dir("other", [d.file("_index.scss", "a {b: c}")]).create(); @@ -755,7 +756,7 @@ void sharedTests(Future runSass(Iterable arguments)) { test( "when a potential dependency that's not actually imported is added", () async { - await d.file("test.scss", "@import 'other'").create(); + await d.file("test.scss", "@use 'other'").create(); await d.file("_other.scss", "a {b: c}").create(); await d.dir("dir").create(); diff --git a/test/dart_api/importer_test.dart b/test/dart_api/importer_test.dart index 28ec53bee..0dc29b973 100644 --- a/test/dart_api/importer_test.dart +++ b/test/dart_api/importer_test.dart @@ -15,8 +15,8 @@ import 'test_importer.dart'; import '../utils.dart'; void main() { - test("uses an importer to resolve an @import", () { - var css = compileString('@import "orange";', importers: [ + test("uses an importer to resolve a @use", () { + var css = compileString('@use "orange";', importers: [ TestImporter((url) => Uri.parse("u:$url"), (url) { var color = url.path; return ImporterResult('.$color {color: $color}', indented: false); @@ -27,7 +27,7 @@ void main() { }); test("passes the canonicalized URL to the importer", () { - var css = compileString('@import "orange";', importers: [ + var css = compileString('@use "orange";', importers: [ TestImporter((url) => Uri.parse('u:blue'), (url) { var color = url.path; return ImporterResult('.$color {color: $color}', indented: false); @@ -62,7 +62,7 @@ void main() { test("resolves URLs relative to the pre-canonicalized URL", () { var times = 0; - var css = compileString('@import "foo:bar/baz";', + var css = compileString('@use "foo:bar/baz";', importers: [ TestImporter( expectAsync1((url) { @@ -94,7 +94,7 @@ void main() { group("the imported URL", () { // Regression test for #1137. test("isn't changed if it's root-relative", () { - compileString('@import "/orange";', importers: [ + compileString('@use "/orange";', importers: [ TestImporter(expectAsync1((url) { expect(url, equals(Uri.parse("/orange"))); return Uri.parse("u:$url"); @@ -115,7 +115,7 @@ void main() { group("the containing URL", () { test("is null for a potentially canonical scheme", () { late TestImporter importer; - compileString('@import "u:orange";', + compileString('@use "u:orange";', importers: [ importer = TestImporter(expectAsync1((url) { expect(importer.publicContainingUrl, isNull); @@ -127,7 +127,7 @@ void main() { test("throws an error outside canonicalize", () { late TestImporter importer; - compileString('@import "orange";', importers: [ + compileString('@use "orange";', importers: [ importer = TestImporter((url) => Uri.parse("u:$url"), expectAsync1((url) { expect(() => importer.publicContainingUrl, throwsStateError); @@ -139,7 +139,7 @@ void main() { group("for a non-canonical scheme", () { test("is set to the original URL", () { late TestImporter importer; - compileString('@import "u:orange";', + compileString('@use "u:orange";', importers: [ importer = TestImporter(expectAsync1((url) { expect(importer.publicContainingUrl, @@ -153,7 +153,7 @@ void main() { test("is null if the original URL is null", () { late TestImporter importer; - compileString('@import "u:orange";', importers: [ + compileString('@use "u:orange";', importers: [ importer = TestImporter(expectAsync1((url) { expect(importer.publicContainingUrl, isNull); return url.replace(scheme: 'x'); @@ -166,7 +166,7 @@ void main() { group("for a schemeless load", () { test("is set to the original URL", () { late TestImporter importer; - compileString('@import "orange";', + compileString('@use "orange";', importers: [ importer = TestImporter(expectAsync1((url) { expect(importer.publicContainingUrl, @@ -179,7 +179,7 @@ void main() { test("is null if the original URL is null", () { late TestImporter importer; - compileString('@import "orange";', importers: [ + compileString('@use "orange";', importers: [ importer = TestImporter(expectAsync1((url) { expect(importer.publicContainingUrl, isNull); return Uri.parse("u:$url"); @@ -193,7 +193,7 @@ void main() { "throws an error if the importer returns a canonical URL with a " "non-canonical scheme", () { expect( - () => compileString('@import "orange";', importers: [ + () => compileString('@use "orange";', importers: [ TestImporter(expectAsync1((url) => Uri.parse("u:$url")), (_) => ImporterResult('', indented: false), nonCanonicalSchemes: {'u'}) @@ -206,7 +206,7 @@ void main() { }); test("uses an importer's source map URL", () { - var result = compileStringToResult('@import "orange";', + var result = compileStringToResult('@use "orange";', importers: [ TestImporter((url) => Uri.parse("u:$url"), (url) { var color = url.path; @@ -220,7 +220,7 @@ void main() { }); test("uses a data: source map URL if the importer doesn't provide one", () { - var result = compileStringToResult('@import "orange";', + var result = compileStringToResult('@use "orange";', importers: [ TestImporter((url) => Uri.parse("u:$url"), (url) { var color = url.path; @@ -237,7 +237,7 @@ void main() { test("wraps an error in canonicalize()", () { expect(() { - compileString('@import "orange";', importers: [ + compileString('@use "orange";', importers: [ TestImporter((url) { throw "this import is bad actually"; }, expectNever1) @@ -252,7 +252,7 @@ void main() { test("wraps an error in load()", () { expect(() { - compileString('@import "orange";', importers: [ + compileString('@use "orange";', importers: [ TestImporter((url) => Uri.parse("u:$url"), (url) { throw "this import is bad actually"; }) @@ -267,7 +267,7 @@ void main() { test("prefers .message to .toString() for an importer error", () { expect(() { - compileString('@import "orange";', importers: [ + compileString('@use "orange";', importers: [ TestImporter((url) => Uri.parse("u:$url"), (url) { throw FormatException("bad format somehow"); }) @@ -283,7 +283,7 @@ void main() { test("avoids importer when only load() returns null", () { expect(() { - compileString('@import "orange";', importers: [ + compileString('@use "orange";', importers: [ TestImporter((url) => Uri.parse("u:$url"), (url) => null) ]); }, throwsA(predicate((error) { @@ -296,7 +296,7 @@ void main() { group("compileString()'s importer option", () { test("loads relative imports from the entrypoint", () { - var css = compileString('@import "orange";', + var css = compileString('@use "orange";', importer: TestImporter((url) => Uri.parse("u:$url"), (url) { var color = url.path; return ImporterResult('.$color {color: $color}', indented: false); @@ -306,7 +306,7 @@ void main() { }); test("loads imports relative to the entrypoint's URL", () { - var css = compileString('@import "baz/qux";', + var css = compileString('@use "baz/qux";', importer: TestImporter((url) => url.resolve("bang"), (url) { return ImporterResult('a {result: "${url.path}"}', indented: false); }), @@ -316,7 +316,7 @@ void main() { }); test("doesn't load absolute imports", () { - var css = compileString('@import "u:orange";', + var css = compileString('@use "u:orange";', importer: TestImporter((_) => throw "Should not be called", (_) => throw "Should not be called"), importers: [ @@ -330,13 +330,13 @@ void main() { }); test("doesn't load from other importers", () { - var css = compileString('@import "u:midstream";', + var css = compileString('@use "u:midstream";', importer: TestImporter((_) => throw "Should not be called", (_) => throw "Should not be called"), importers: [ TestImporter((url) => url, (url) { if (url.path == "midstream") { - return ImporterResult("@import 'orange';", indented: false); + return ImporterResult("@use 'orange';", indented: false); } else { var color = url.path; return ImporterResult('.$color {color: $color}', diff --git a/test/dart_api/logger_test.dart b/test/dart_api/logger_test.dart index 979b2ba11..9fc1971d2 100644 --- a/test/dart_api/logger_test.dart +++ b/test/dart_api/logger_test.dart @@ -193,7 +193,7 @@ void main() { test("from an importer", () { var mustBeCalled = expectAsync0(() {}); - compileString("@import 'foo';", importers: [ + compileString("@use 'foo';", importers: [ TestImporter((url) => Uri.parse("u:$url"), (url) { warn("heck"); return ImporterResult("", indented: false); @@ -203,11 +203,11 @@ void main() { expect(message, equals("heck")); expect(span!.start.line, equals(0)); - expect(span.start.column, equals(8)); + expect(span.start.column, equals(0)); expect(span.end.line, equals(0)); - expect(span.end.column, equals(13)); + expect(span.end.column, equals(10)); - expect(trace!.frames.first.member, equals('@import')); + expect(trace!.frames.first.member, equals('@use')); expect(deprecation, isFalse); mustBeCalled(); })); diff --git a/test/dart_api_test.dart b/test/dart_api_test.dart index 2fd8d6737..f84b39d52 100644 --- a/test/dart_api_test.dart +++ b/test/dart_api_test.dart @@ -20,7 +20,7 @@ void main() { group("importers", () { test("is used to resolve imports", () async { await d.dir("subdir", [d.file("subtest.scss", "a {b: c}")]).create(); - await d.file("test.scss", '@import "subtest.scss";').create(); + await d.file("test.scss", '@use "subtest.scss";').create(); var css = compile(d.path("test.scss"), importers: [FilesystemImporter(d.path('subdir'))]); @@ -32,7 +32,7 @@ void main() { .dir("first", [d.file("other.scss", "a {b: from-first}")]).create(); await d .dir("second", [d.file("other.scss", "a {b: from-second}")]).create(); - await d.file("test.scss", '@import "other";').create(); + await d.file("test.scss", '@use "other";').create(); var css = compile(d.path("test.scss"), importers: [ FilesystemImporter(d.path('first')), @@ -45,7 +45,7 @@ void main() { group("loadPaths", () { test("is used to import file: URLs", () async { await d.dir("subdir", [d.file("subtest.scss", "a {b: c}")]).create(); - await d.file("test.scss", '@import "subtest.scss";').create(); + await d.file("test.scss", '@use "subtest.scss";').create(); var css = compile(d.path("test.scss"), loadPaths: [d.path('subdir')]); expect(css, equals("a {\n b: c;\n}")); @@ -53,7 +53,7 @@ void main() { test("can import partials", () async { await d.dir("subdir", [d.file("_subtest.scss", "a {b: c}")]).create(); - await d.file("test.scss", '@import "subtest.scss";').create(); + await d.file("test.scss", '@use "subtest.scss";').create(); var css = compile(d.path("test.scss"), loadPaths: [d.path('subdir')]); expect(css, equals("a {\n b: c;\n}")); @@ -61,7 +61,7 @@ void main() { test("adds a .scss extension", () async { await d.dir("subdir", [d.file("subtest.scss", "a {b: c}")]).create(); - await d.file("test.scss", '@import "subtest";').create(); + await d.file("test.scss", '@use "subtest";').create(); var css = compile(d.path("test.scss"), loadPaths: [d.path('subdir')]); expect(css, equals("a {\n b: c;\n}")); @@ -69,7 +69,7 @@ void main() { test("adds a .sass extension", () async { await d.dir("subdir", [d.file("subtest.sass", "a\n b: c")]).create(); - await d.file("test.scss", '@import "subtest";').create(); + await d.file("test.scss", '@use "subtest";').create(); var css = compile(d.path("test.scss"), loadPaths: [d.path('subdir')]); expect(css, equals("a {\n b: c;\n}")); @@ -80,7 +80,7 @@ void main() { .dir("first", [d.file("other.scss", "a {b: from-first}")]).create(); await d .dir("second", [d.file("other.scss", "a {b: from-second}")]).create(); - await d.file("test.scss", '@import "other";').create(); + await d.file("test.scss", '@use "other";').create(); var css = compile(d.path("test.scss"), loadPaths: [d.path('first'), d.path('second')]); @@ -92,9 +92,7 @@ void main() { test("is used to import package: URLs", () async { await d.dir("subdir", [d.file("test.scss", "a {b: 1 + 2}")]).create(); - await d - .file("test.scss", '@import "package:fake_package/test";') - .create(); + await d.file("test.scss", '@use "package:fake_package/test";').create(); var config = PackageConfig([Package('fake_package', p.toUri(d.path('subdir/')))]); @@ -104,13 +102,11 @@ void main() { test("can resolve relative paths in a package", () async { await d.dir("subdir", [ - d.file("test.scss", "@import 'other'"), + d.file("test.scss", "@use 'other'"), d.file("_other.scss", "a {b: 1 + 2}"), ]).create(); - await d - .file("test.scss", '@import "package:fake_package/test";') - .create(); + await d.file("test.scss", '@use "package:fake_package/test";').create(); var config = PackageConfig([Package('fake_package', p.toUri(d.path('subdir/')))]); @@ -120,7 +116,7 @@ void main() { test("doesn't import a package URL from a missing package", () async { await d - .file("test.scss", '@import "package:fake_package/test_aux";') + .file("test.scss", '@use "package:fake_package/test_aux";') .create(); expect( @@ -134,7 +130,7 @@ void main() { await d.dir( "subdir", [d.file("other.scss", "a {b: from-load-path}")]).create(); await d.file("other.scss", "a {b: from-relative}").create(); - await d.file("test.scss", '@import "other";').create(); + await d.file("test.scss", '@use "other";').create(); var css = compile(d.path("test.scss"), importers: [FilesystemImporter(d.path('subdir'))]); @@ -149,7 +145,7 @@ void main() { await d .dir("other", [d.file("other.scss", "a {b: from-other}")]).create(); - var css = compileString('@import "other";', + var css = compileString('@use "other";', importer: FilesystemImporter(d.path('original')), url: p.toUri(d.path('original/test.scss')), importers: [FilesystemImporter(d.path('other'))]); @@ -157,7 +153,7 @@ void main() { }); test("importer order is preserved for absolute imports", () { - var css = compileString('@import "second:other";', importers: [ + var css = compileString('@use "second:other";', importers: [ TestImporter((url) => url.scheme == 'first' ? url : null, (url) => ImporterResult('a {from: first}', indented: false)), // This importer should only be invoked once, because when the @@ -166,7 +162,7 @@ void main() { TestImporter( expectAsync1((url) => url.scheme == 'second' ? url : null, count: 1), - (url) => ImporterResult('@import "first:other";', indented: false)), + (url) => ImporterResult('@use "first:other";', indented: false)), ]); expect(css, equals("a {\n from: first;\n}")); }); @@ -176,7 +172,7 @@ void main() { [d.file("other.scss", "a {b: from-load-path}")]).create(); await d.dir( "importer", [d.file("other.scss", "a {b: from-importer}")]).create(); - await d.file("test.scss", '@import "other";').create(); + await d.file("test.scss", '@use "other";').create(); var css = compile(d.path("test.scss"), importers: [FilesystemImporter(d.path('importer'))], @@ -189,9 +185,7 @@ void main() { [d.file("other.scss", "a {b: from-package-config}")]).create(); await d.dir( "importer", [d.file("other.scss", "a {b: from-importer}")]).create(); - await d - .file("test.scss", '@import "package:fake_package/other";') - .create(); + await d.file("test.scss", '@use "package:fake_package/other";').create(); var css = compile(d.path("test.scss"), importers: [ @@ -268,7 +262,8 @@ a { test("contains a URL loaded via @import", () async { await d.file("_other.scss", "a {b: c}").create(); await d.file("input.scss", "@import 'other';").create(); - var result = compileToResult(d.path('input.scss')); + var result = compileToResult(d.path('input.scss'), + silenceDeprecations: [Deprecation.import]); expect(result.loadedUrls, contains(p.toUri(d.path('_other.scss')))); }); @@ -305,7 +300,8 @@ a { @use 'sass:meta'; @include meta.load-css('venus'); """).create(); - var result = compileToResult(d.path('mercury.scss')); + var result = compileToResult(d.path('mercury.scss'), + silenceDeprecations: [Deprecation.import]); expect( result.loadedUrls, unorderedEquals([ diff --git a/test/embedded/file_importer_test.dart b/test/embedded/file_importer_test.dart index 8d5bf4ec2..4620fe622 100644 --- a/test/embedded/file_importer_test.dart +++ b/test/embedded/file_importer_test.dart @@ -24,7 +24,7 @@ void main() { late OutboundMessage_FileImportRequest request; setUp(() async { - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ InboundMessage_CompileRequest_Importer()..fileImporterId = 1 ])); @@ -63,7 +63,7 @@ void main() { late OutboundMessage_FileImportRequest request; setUp(() async { - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ InboundMessage_CompileRequest_Importer()..fileImporterId = 1 ])); @@ -77,7 +77,7 @@ void main() { ..id = request.id ..fileUrl = "")); - await _expectImportError( + await _expectUseError( process, 'The file importer must return an absolute URL, was ""'); await process.close(); }); @@ -88,7 +88,7 @@ void main() { ..id = request.id ..fileUrl = "foo")); - await _expectImportError(process, + await _expectUseError(process, 'The file importer must return an absolute URL, was "foo"'); await process.close(); }); @@ -99,7 +99,7 @@ void main() { ..id = request.id ..fileUrl = "other:foo")); - await _expectImportError(process, + await _expectUseError(process, 'The file importer must return a file: URL, was "other:foo"'); await process.close(); }); @@ -111,8 +111,7 @@ void main() { var importerId = 5679; late OutboundMessage_FileImportRequest request; setUp(() async { - process.send( - compileString("@import 'other'", id: compilationId, importers: [ + process.send(compileString("@use 'other'", id: compilationId, importers: [ InboundMessage_CompileRequest_Importer()..fileImporterId = importerId ])); request = await getFileImportRequest(process); @@ -129,13 +128,13 @@ void main() { }); test("whether the import came from an @import", () async { - expect(request.fromImport, isTrue); + expect(request.fromImport, isFalse); await process.kill(); }); }); test("errors cause compilation to fail", () async { - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ InboundMessage_CompileRequest_Importer()..fileImporterId = 1 ])); @@ -147,13 +146,13 @@ void main() { var failure = await getCompileFailure(process); expect(failure.message, equals('oh no')); - expect(failure.span.text, equals("'other'")); - expect(failure.stackTrace, equals('- 1:9 root stylesheet\n')); + expect(failure.span.text, equals("@use 'other'")); + expect(failure.stackTrace, equals('- 1:1 root stylesheet\n')); await process.close(); }); test("null results count as not found", () async { - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ InboundMessage_CompileRequest_Importer()..fileImporterId = 1 ])); @@ -164,13 +163,13 @@ void main() { var failure = await getCompileFailure(process); expect(failure.message, equals("Can't find stylesheet to import.")); - expect(failure.span.text, equals("'other'")); + expect(failure.span.text, equals("@use 'other'")); await process.close(); }); group("attempts importers in order", () { test("with multiple file importers", () async { - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ for (var i = 0; i < 10; i++) InboundMessage_CompileRequest_Importer()..fileImporterId = i ])); @@ -187,7 +186,7 @@ void main() { }); test("with a mixture of file and normal importers", () async { - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ for (var i = 0; i < 10; i++) if (i % 2 == 0) InboundMessage_CompileRequest_Importer()..fileImporterId = i @@ -217,9 +216,9 @@ void main() { test("tries resolved URL as a relative path first", () async { await d.file("upstream.scss", "a {b: c}").create(); - await d.file("midstream.scss", "@import 'upstream';").create(); + await d.file("midstream.scss", "@use 'upstream';").create(); - process.send(compileString("@import 'midstream'", importers: [ + process.send(compileString("@use 'midstream'", importers: [ for (var i = 0; i < 10; i++) InboundMessage_CompileRequest_Importer()..fileImporterId = i ])); @@ -250,7 +249,7 @@ void main() { }); test("without a base URL", () async { - process.send(compileString("@import 'other'", + process.send(compileString("@use 'other'", importer: InboundMessage_CompileRequest_Importer() ..fileImporterId = 1)); @@ -267,7 +266,7 @@ void main() { }); test("with a base URL", () async { - process.send(compileString("@import 'other'", + process.send(compileString("@use 'other'", url: p.toUri(d.path("input")).toString(), importer: InboundMessage_CompileRequest_Importer() ..fileImporterId = 1)); @@ -280,8 +279,8 @@ void main() { /// Asserts that [process] emits a [CompileFailure] result with the given /// [message] on its protobuf stream and causes the compilation to fail. -Future _expectImportError(EmbeddedProcess process, Object message) async { +Future _expectUseError(EmbeddedProcess process, Object message) async { var failure = await getCompileFailure(process); expect(failure.message, equals(message)); - expect(failure.span.text, equals("'other'")); + expect(failure.span.text, equals("@use 'other'")); } diff --git a/test/embedded/function_test.dart b/test/embedded/function_test.dart index 97e79f334..017e02543 100644 --- a/test/embedded/function_test.dart +++ b/test/embedded/function_test.dart @@ -209,7 +209,7 @@ void main() { @use "sass:math"; @use "sass:meta"; - a {b: call(foo(meta.get-function("abs", $module: "math")), -1)} + a {b: meta.call(foo(meta.get-function("abs", $module: "math")), -1)} """, functions: [r"foo($arg)"])); var request = await getFunctionCallRequest(_process); @@ -225,8 +225,11 @@ void main() { }); test("defined in the host", () async { - _process.send( - compileString("a {b: call(foo(), true)}", functions: [r"foo()"])); + _process.send(compileString(""" + @use "sass:meta"; + + a {b: meta.call(foo(), true)} + """, functions: [r"foo()"])); var hostFunctionId = 5678; var request = await getFunctionCallRequest(_process); @@ -253,9 +256,11 @@ void main() { test("defined in the host and passed to and from the host", () async { _process.send(compileString(r""" + @use "sass:meta"; + $function: get-host-function(); $function: round-trip($function); - a {b: call($function, true)} + a {b: meta.call($function, true)} """, functions: [r"get-host-function()", r"round-trip($function)"])); var hostFunctionId = 5678; @@ -310,7 +315,7 @@ void main() { group("unquoted", () { test("and empty", () async { - var value = (await _protofy('unquote("")')).string; + var value = (await _protofy('string.unquote("")')).string; expect(value.text, isEmpty); expect(value.quoted, isFalse); }); @@ -1764,8 +1769,9 @@ void main() { group("reports a compilation error for a function with a signature", () { Future expectSignatureError( String signature, Object message) async { - _process.send( - compileString("a {b: inspect(foo())}", functions: [r"foo()"])); + _process.send(compileString( + "@use 'sass:meta';\na {b: meta.inspect(foo())}", + functions: [r"foo()"])); var request = await getFunctionCallRequest(_process); expect(request.arguments, isEmpty); @@ -1819,6 +1825,7 @@ Future _protofy(String sassScript) async { @use 'sass:map'; @use 'sass:math'; @use 'sass:meta'; +@use 'sass:string'; @function capture-args(\$args...) { \$_: meta.keywords(\$args); @@ -1852,7 +1859,9 @@ void _testSerializationAndRoundTrip(Value value, String expected, /// `meta.inspect()` function. Future _deprotofy(Value value, {bool inspect = false}) async { _process.send(compileString( - inspect ? "a {b: inspect(foo())}" : "a {b: foo()}", + inspect + ? "@use 'sass:meta';\na {b: meta.inspect(foo())}" + : "a {b: foo()}", functions: [r"foo()"])); var request = await getFunctionCallRequest(_process); diff --git a/test/embedded/importer_test.dart b/test/embedded/importer_test.dart index fdfc904d2..adfcaa455 100644 --- a/test/embedded/importer_test.dart +++ b/test/embedded/importer_test.dart @@ -22,7 +22,7 @@ void main() { group("emits a protocol error", () { test("for a response without a corresponding request ID", () async { - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ InboundMessage_CompileRequest_Importer()..importerId = 1 ])); @@ -40,7 +40,7 @@ void main() { }); test("for a response that doesn't match the request type", () async { - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ InboundMessage_CompileRequest_Importer()..importerId = 1 ])); @@ -109,7 +109,7 @@ void main() { group("canonicalization", () { group("emits a compile failure", () { test("for a canonicalize response with an empty URL", () async { - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ InboundMessage_CompileRequest_Importer()..importerId = 1 ])); @@ -125,7 +125,7 @@ void main() { }); test("for a canonicalize response with a relative URL", () async { - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ InboundMessage_CompileRequest_Importer()..importerId = 1 ])); @@ -145,7 +145,7 @@ void main() { var importerId = 5679; late OutboundMessage_CanonicalizeRequest request; setUp(() async { - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ InboundMessage_CompileRequest_Importer()..importerId = importerId ])); request = await getCanonicalizeRequest(process); @@ -163,7 +163,7 @@ void main() { }); test("errors cause compilation to fail", () async { - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ InboundMessage_CompileRequest_Importer()..importerId = 1 ])); @@ -175,13 +175,13 @@ void main() { var failure = await getCompileFailure(process); expect(failure.message, equals('oh no')); - expect(failure.span.text, equals("'other'")); - expect(failure.stackTrace, equals('- 1:9 root stylesheet\n')); + expect(failure.span.text, equals("@use 'other'")); + expect(failure.stackTrace, equals('- 1:1 root stylesheet\n')); await process.close(); }); test("null results count as not found", () async { - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ InboundMessage_CompileRequest_Importer()..importerId = 1 ])); @@ -192,13 +192,13 @@ void main() { var failure = await getCompileFailure(process); expect(failure.message, equals("Can't find stylesheet to import.")); - expect(failure.span.text, equals("'other'")); + expect(failure.span.text, equals("@use 'other'")); await process.close(); }); group("the containing URL", () { test("is unset for a potentially canonical scheme", () async { - process.send(compileString('@import "u:orange"', importers: [ + process.send(compileString('@use "u:orange"', importers: [ InboundMessage_CompileRequest_Importer(importerId: 1) ])); @@ -209,7 +209,7 @@ void main() { group("for a non-canonical scheme", () { test("is set to the original URL", () async { - process.send(compileString('@import "u:orange"', + process.send(compileString('@use "u:orange"', importers: [ InboundMessage_CompileRequest_Importer( importerId: 1, nonCanonicalScheme: ["u"]) @@ -222,7 +222,7 @@ void main() { }); test("is unset to the original URL is unset", () async { - process.send(compileString('@import "u:orange"', importers: [ + process.send(compileString('@use "u:orange"', importers: [ InboundMessage_CompileRequest_Importer( importerId: 1, nonCanonicalScheme: ["u"]) ])); @@ -235,7 +235,7 @@ void main() { group("for a schemeless load", () { test("is set to the original URL", () async { - process.send(compileString('@import "orange"', + process.send(compileString('@use "orange"', importers: [ InboundMessage_CompileRequest_Importer(importerId: 1) ], @@ -247,7 +247,7 @@ void main() { }); test("is unset to the original URL is unset", () async { - process.send(compileString('@import "u:orange"', importers: [ + process.send(compileString('@use "u:orange"', importers: [ InboundMessage_CompileRequest_Importer(importerId: 1) ])); @@ -261,7 +261,7 @@ void main() { test( "fails if the importer returns a canonical URL with a non-canonical " "scheme", () async { - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ InboundMessage_CompileRequest_Importer( importerId: 1, nonCanonicalScheme: ["u"]) ])); @@ -277,7 +277,7 @@ void main() { }); test("attempts importers in order", () async { - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ for (var i = 0; i < 10; i++) InboundMessage_CompileRequest_Importer()..importerId = i ])); @@ -294,7 +294,7 @@ void main() { }); test("tries resolved URL using the original importer first", () async { - process.send(compileString("@import 'midstream'", importers: [ + process.send(compileString("@use 'midstream'", importers: [ for (var i = 0; i < 10; i++) InboundMessage_CompileRequest_Importer()..importerId = i ])); @@ -320,7 +320,7 @@ void main() { ..importResponse = (InboundMessage_ImportResponse() ..id = import.id ..success = (InboundMessage_ImportResponse_ImportSuccess() - ..contents = "@import 'upstream'"))); + ..contents = "@use 'upstream'"))); canonicalize = await getCanonicalizeRequest(process); expect(canonicalize.importerId, equals(5)); @@ -333,7 +333,7 @@ void main() { group("importing", () { group("emits a compile failure", () { test("for an import result with a relative sourceMapUrl", () async { - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ InboundMessage_CompileRequest_Importer()..importerId = 1 ])); await _canonicalize(process); @@ -355,7 +355,7 @@ void main() { var importerId = 5678; late OutboundMessage_ImportRequest request; setUp(() async { - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ InboundMessage_CompileRequest_Importer()..importerId = importerId ])); @@ -380,7 +380,7 @@ void main() { }); test("null results count as not found", () async { - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ InboundMessage_CompileRequest_Importer()..importerId = 1 ])); @@ -397,12 +397,12 @@ void main() { var failure = await getCompileFailure(process); expect(failure.message, equals("Can't find stylesheet to import.")); - expect(failure.span.text, equals("'other'")); + expect(failure.span.text, equals("@use 'other'")); await process.close(); }); test("errors cause compilation to fail", () async { - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ InboundMessage_CompileRequest_Importer()..importerId = 1 ])); await _canonicalize(process); @@ -415,13 +415,13 @@ void main() { var failure = await getCompileFailure(process); expect(failure.message, equals('oh no')); - expect(failure.span.text, equals("'other'")); - expect(failure.stackTrace, equals('- 1:9 root stylesheet\n')); + expect(failure.span.text, equals("@use 'other'")); + expect(failure.stackTrace, equals('- 1:1 root stylesheet\n')); await process.close(); }); test("can return an SCSS file", () async { - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ InboundMessage_CompileRequest_Importer()..importerId = 1 ])); await _canonicalize(process); @@ -438,7 +438,7 @@ void main() { }); test("can return an indented syntax file", () async { - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ InboundMessage_CompileRequest_Importer()..importerId = 1 ])); await _canonicalize(process); @@ -456,7 +456,7 @@ void main() { }); test("can return a plain CSS file", () async { - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ InboundMessage_CompileRequest_Importer()..importerId = 1 ])); await _canonicalize(process); @@ -474,11 +474,9 @@ void main() { }); test("uses a data: URL rather than an empty source map URL", () async { - process.send(compileString("@import 'other'", - sourceMap: true, - importers: [ - InboundMessage_CompileRequest_Importer()..importerId = 1 - ])); + process.send(compileString("@use 'other'", sourceMap: true, importers: [ + InboundMessage_CompileRequest_Importer()..importerId = 1 + ])); await _canonicalize(process); var request = await getImportRequest(process); @@ -497,11 +495,9 @@ void main() { }); test("uses a non-empty source map URL", () async { - process.send(compileString("@import 'other'", - sourceMap: true, - importers: [ - InboundMessage_CompileRequest_Importer()..importerId = 1 - ])); + process.send(compileString("@use 'other'", sourceMap: true, importers: [ + InboundMessage_CompileRequest_Importer()..importerId = 1 + ])); await _canonicalize(process); var request = await getImportRequest(process); @@ -521,7 +517,7 @@ void main() { }); test("handles an importer for a string compile request", () async { - process.send(compileString("@import 'other'", + process.send(compileString("@use 'other'", importer: InboundMessage_CompileRequest_Importer()..importerId = 1)); await _canonicalize(process); @@ -540,7 +536,7 @@ void main() { test("are used to load imports", () async { await d.dir("dir", [d.file("other.scss", "a {b: c}")]).create(); - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ InboundMessage_CompileRequest_Importer()..path = d.path("dir") ])); @@ -553,7 +549,7 @@ void main() { await d.dir("dir$i", [d.file("other$i.scss", "a {b: $i}")]).create(); } - process.send(compileString("@import 'other2'", importers: [ + process.send(compileString("@use 'other2'", importers: [ for (var i = 0; i < 3; i++) InboundMessage_CompileRequest_Importer()..path = d.path("dir$i") ])); @@ -565,7 +561,7 @@ void main() { test("take precedence over later importers", () async { await d.dir("dir", [d.file("other.scss", "a {b: c}")]).create(); - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ InboundMessage_CompileRequest_Importer()..path = d.path("dir"), InboundMessage_CompileRequest_Importer()..importerId = 1 ])); @@ -577,7 +573,7 @@ void main() { test("yield precedence to earlier importers", () async { await d.dir("dir", [d.file("other.scss", "a {b: c}")]).create(); - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ InboundMessage_CompileRequest_Importer()..importerId = 1, InboundMessage_CompileRequest_Importer()..path = d.path("dir") ])); @@ -653,5 +649,5 @@ Future _canonicalize(EmbeddedProcess process) async { Future _expectImportError(EmbeddedProcess process, Object message) async { var failure = await getCompileFailure(process); expect(failure.message, equals(message)); - expect(failure.span.text, equals("'other'")); + expect(failure.span.text, equals("@use 'other'")); } diff --git a/test/embedded/protocol_test.dart b/test/embedded/protocol_test.dart index b77d376e0..2bbf64439 100644 --- a/test/embedded/protocol_test.dart +++ b/test/embedded/protocol_test.dart @@ -67,7 +67,7 @@ void main() { }); test("caused by duplicate compilation IDs", () async { - process.send(compileString("@import 'other'", importers: [ + process.send(compileString("@use 'other'", importers: [ InboundMessage_CompileRequest_Importer()..importerId = 1 ])); await getCanonicalizeRequest(process); From e66b8a29ef8130425c02af0950cb067b1c56b224 Mon Sep 17 00:00:00 2001 From: Jennifer Thakar Date: Thu, 18 Jul 2024 13:07:40 -0700 Subject: [PATCH 3/7] Migrate warning limiter test --- test/cli/shared.dart | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/test/cli/shared.dart b/test/cli/shared.dart index 09ea953bd..d9264bde2 100644 --- a/test/cli/shared.dart +++ b/test/cli/shared.dart @@ -658,12 +658,15 @@ void sharedTests( group("with a bunch of deprecation warnings", () { setUp(() async { await d.file("test.scss", r""" - $_: call("inspect", null); - $_: call("rgb", 0, 0, 0); - $_: call("nth", null, 1); - $_: call("join", null, null); - $_: call("if", true, 1, 2); - $_: call("hsl", 0, 100%, 100%); + @use "sass:list"; + @use "sass:meta"; + + $_: meta.call("inspect", null); + $_: meta.call("rgb", 0, 0, 0); + $_: meta.call("nth", null, 1); + $_: meta.call("join", null, null); + $_: meta.call("if", true, 1, 2); + $_: meta.call("hsl", 0, 100%, 100%); $_: 1/2; $_: 1/3; From 8d30cee242006ee25e24c50638687408dde97658 Mon Sep 17 00:00:00 2001 From: Jennifer Thakar Date: Mon, 14 Oct 2024 14:18:23 -0700 Subject: [PATCH 4/7] Fix TOC --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ee3e4b0c..ef6f6375f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ are available within built-in modules. See [the Sass blog post] for more details on the deprecation process. -[the Sass blog]: https://sass-lang.com/blog/import-is-deprecated/ +[the Sass blog post]: https://sass-lang.com/blog/import-is-deprecated/ ## 1.79.6 From 094b5a1f8531803476b60a0b8e95c8cb4f004cb9 Mon Sep 17 00:00:00 2001 From: Jennifer Thakar Date: Mon, 14 Oct 2024 14:58:52 -0700 Subject: [PATCH 5/7] Fix changelog --- pkg/sass-parser/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/sass-parser/CHANGELOG.md b/pkg/sass-parser/CHANGELOG.md index 3b35d6f72..86f01f5d2 100644 --- a/pkg/sass-parser/CHANGELOG.md +++ b/pkg/sass-parser/CHANGELOG.md @@ -1,5 +1,7 @@ ## 0.3.0 +* No user-visible changes. + ## 0.2.6 * No user-visible changes. From a895b40338894afc959b63e3754a0a51d85d34c5 Mon Sep 17 00:00:00 2001 From: Jennifer Thakar Date: Tue, 15 Oct 2024 13:34:19 -0700 Subject: [PATCH 6/7] Update changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef6f6375f..9269480b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ [the Sass blog post]: https://sass-lang.com/blog/import-is-deprecated/ +### Embedded Host + +* Fix an error that would sometimes occur when deprecation warnings were + emitted when using a custom importer with the legacy API. + ## 1.79.6 * Fix a bug where Sass would add an extra `*/` after loud comments with From d75694e3f4c4a9c3704cfe2e2f43bceb8ecdb45d Mon Sep 17 00:00:00 2001 From: Jennifer Thakar Date: Tue, 15 Oct 2024 15:39:45 -0700 Subject: [PATCH 7/7] Code review --- lib/src/callable/async_built_in.dart | 4 ++-- lib/src/parse/stylesheet.dart | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/src/callable/async_built_in.dart b/lib/src/callable/async_built_in.dart index f75fa0055..4e479c148 100644 --- a/lib/src/callable/async_built_in.dart +++ b/lib/src/callable/async_built_in.dart @@ -99,8 +99,8 @@ class AsyncBuiltInCallable implements AsyncCallable { /// available as function [name] in built-in module [module]. void warnForGlobalBuiltIn(String module, String name) { warnForDeprecation( - 'Global built-in functions are deprecated and ' - 'will be removed in Dart Sass 3.0.0.\n' + 'Global built-in functions are deprecated and will be removed in Dart ' + 'Sass 3.0.0.\n' 'Use $module.$name instead.\n\n' 'More info and automated migrator: https://sass-lang.com/d/import', Deprecation.globalBuiltin); diff --git a/lib/src/parse/stylesheet.dart b/lib/src/parse/stylesheet.dart index ff970216c..3fab4e0ba 100644 --- a/lib/src/parse/stylesheet.dart +++ b/lib/src/parse/stylesheet.dart @@ -1057,10 +1057,9 @@ abstract class StylesheetParser extends Parser { if (argument is DynamicImport) { logger.warnForDeprecation( Deprecation.import, - 'Sass @import rules are deprecated ' - 'and will be removed in Dart Sass 3.0.0.\n\n' - 'More info and automated migrator: ' - 'https://sass-lang.com/d/import', + 'Sass @import rules are deprecated and will be removed in Dart ' + 'Sass 3.0.0.\n\n' + 'More info and automated migrator: https://sass-lang.com/d/import', span: argument.span); } if ((_inControlDirective || _inMixin) && argument is DynamicImport) {