Skip to content

Commit

Permalink
Add a future global-builtin deprecation (#2336)
Browse files Browse the repository at this point in the history
  • Loading branch information
jathak committed Sep 5, 2024
1 parent 5dff2e8 commit 717867b
Show file tree
Hide file tree
Showing 17 changed files with 163 additions and 61 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## 1.79.0

* Add a `global-builtin` future deprecation, which can be opted-into with the
`--future-deprecation` flag or the `futureDeprecations` option in the JS or
Dart API. This emits warnings when any global built-in functions that are
now available in `sass:` modules are called. It will become active by default
in an upcoming release alongside the `@import` deprecation.

## 1.78.0

* The `meta.feature-exists` function is now deprecated. This deprecation is
Expand Down
3 changes: 2 additions & 1 deletion lib/src/callable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
20 changes: 20 additions & 0 deletions lib/src/callable/async_built_in.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import 'dart:async';

import '../ast/sass.dart';
import '../deprecation.dart';
import '../evaluation_context.dart';
import '../value.dart';
import 'async.dart';

Expand Down Expand Up @@ -83,4 +85,22 @@ class AsyncBuiltInCallable implements AsyncCallable {
(ArgumentDeclaration, Callback) callbackFor(
int positional, Set<String> 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 will be deprecated in the future.\n'
'Remove the --future-deprecation=global-builtin flag to silence this '
'warning for now.',
Deprecation.globalBuiltin);
}
16 changes: 16 additions & 0 deletions lib/src/callable/built_in.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
7 changes: 6 additions & 1 deletion lib/src/deprecation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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: dd5c6aa0f1431fa9fc88bb71a96f832adbc165f5
// Checksum: bf841a728263bf7efc2a85a091330a1f8074e067

/// Deprecation for passing a string directly to meta.call().
callString('call-string',
Expand Down Expand Up @@ -102,6 +102,11 @@ enum Deprecation {
/// Deprecation for @import rules.
import.future('import', description: '@import rules.'),

/// Deprecation for global built-in functions that are available in sass: modules.
globalBuiltin.future('global-builtin',
description:
'Global built-in functions that are available in sass: modules.'),

// END AUTOGENERATED CODE

/// Used for deprecations coming from user-authored code.
Expand Down
41 changes: 26 additions & 15 deletions lib/src/functions/color.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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) =>
Expand Down Expand Up @@ -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);
}),
Expand All @@ -125,23 +129,23 @@ 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");
var amount = arguments[1].assertNumber("amount");
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");
var amount = arguments[1].assertNumber("amount");
return color.changeHsl(
lightness: (color.lightness - amount.valueInRange(0, 100, "amount"))
.clamp(0, 100));
}),
}).withDeprecationWarning('color', 'adjust'),

BuiltInCallable.overloadedFunction("saturate", {
r"$amount": (arguments) {
Expand All @@ -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(
Expand All @@ -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) {
Expand All @@ -185,6 +194,7 @@ final global = UnmodifiableListView([
return _functionString("alpha", arguments);
}

warnForGlobalBuiltIn('color', 'alpha');
var color = argument.assertColor("color");
return SassNumber(color.alpha);
},
Expand Down Expand Up @@ -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.
Expand Down
11 changes: 9 additions & 2 deletions lib/src/functions/list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
12 changes: 6 additions & 6 deletions lib/src/functions/map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
16 changes: 12 additions & 4 deletions lib/src/functions/math.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
22 changes: 14 additions & 8 deletions lib/src/functions/meta.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,12 @@ final _features = {
"custom-property"
};

/// The global definitions of Sass introspection functions.
final global = UnmodifiableListView([
/// 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([
// 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.
Expand All @@ -35,10 +39,8 @@ final global = UnmodifiableListView([
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",
Expand All @@ -58,7 +60,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({
Expand All @@ -71,9 +72,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);
Expand Down
16 changes: 8 additions & 8 deletions lib/src/functions/selector.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
14 changes: 9 additions & 5 deletions lib/src/functions/string.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Loading

0 comments on commit 717867b

Please sign in to comment.