Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 13c98af

Browse files
committedJan 21, 2025·
Migrate nested color functions
Fixes #268.
1 parent e3712be commit 13c98af

File tree

4 files changed

+80
-41
lines changed

4 files changed

+80
-41
lines changed
 

‎CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## 2.3.1
2+
3+
### Color Function Migrator
4+
5+
* Fix a bug where deprecated color functions nested inside other functions would
6+
not be migrated.
7+
18
## 2.3.0
29

310
* Add a `--pkg-importer` flag to enable loading dependencies from `pkg:` URLs

‎lib/src/migrators/color.dart

+51-40
Original file line numberDiff line numberDiff line change
@@ -72,40 +72,49 @@ class _ColorMigrationVisitor extends MigrationVisitor {
7272
@override
7373
void visitFunctionExpression(FunctionExpression node) {
7474
var source = references.sources[node];
75-
if (source is! BuiltInSource || source.url != _colorUrl) return;
75+
if (source is BuiltInSource && source.url == _colorUrl) {
76+
var colorPatches = _makeColorPatches(node);
77+
if (colorPatches.isNotEmpty && node.namespace == null) {
78+
addPatch(patchBefore(
79+
node, '${_getOrAddColorModuleNamespace(node.span.file)}.'));
80+
}
81+
colorPatches.forEach(addPatch);
82+
}
83+
super.visitFunctionExpression(node);
84+
}
85+
86+
/// Returns the patches necessary to convert legacy color functions to
87+
/// `color.adjust` or `color.channel`.
88+
Iterable<Patch> _makeColorPatches(FunctionExpression node) {
7689
switch (node.name) {
7790
case 'red' || 'green' || 'blue':
78-
_patchChannel(node, 'rgb');
91+
return _makeChannelPatches(node, 'rgb');
7992
case 'hue' || 'saturation' || 'lightness':
80-
_patchChannel(node, 'hsl');
93+
return _makeChannelPatches(node, 'hsl');
8194
case 'whiteness' || 'blackness':
82-
_patchChannel(node, 'hwb');
95+
return _makeChannelPatches(node, 'hwb');
8396
case 'alpha':
84-
_patchChannel(node);
97+
return _makeChannelPatches(node);
8598
case 'adjust-hue':
86-
_patchAdjust(node, channel: 'hue', space: 'hsl');
99+
return _makeAdjustPatches(node, channel: 'hue', space: 'hsl');
87100
case 'saturate'
88101
when node.arguments.named.length + node.arguments.positional.length !=
89102
1:
90-
_patchAdjust(node, channel: 'saturation', space: 'hsl');
103+
return _makeAdjustPatches(node, channel: 'saturation', space: 'hsl');
91104
case 'desaturate':
92-
_patchAdjust(node, channel: 'saturation', negate: true, space: 'hsl');
105+
return _makeAdjustPatches(node,
106+
channel: 'saturation', negate: true, space: 'hsl');
93107
case 'transparentize' || 'fade-out':
94-
_patchAdjust(node, channel: 'alpha', negate: true);
108+
return _makeAdjustPatches(node, channel: 'alpha', negate: true);
95109
case 'opacify' || 'fade-in':
96-
_patchAdjust(node, channel: 'alpha');
110+
return _makeAdjustPatches(node, channel: 'alpha');
97111
case 'lighten':
98-
_patchAdjust(node, channel: 'lightness', space: 'hsl');
112+
return _makeAdjustPatches(node, channel: 'lightness', space: 'hsl');
99113
case 'darken':
100-
_patchAdjust(node, channel: 'lightness', negate: true, space: 'hsl');
114+
return _makeAdjustPatches(node,
115+
channel: 'lightness', negate: true, space: 'hsl');
101116
default:
102-
return;
103-
}
104-
if (node.namespace == null) {
105-
addPatch(
106-
patchBefore(
107-
node, '${_getOrAddColorModuleNamespace(node.span.file)}.'),
108-
beforeExisting: true);
117+
return [];
109118
}
110119
}
111120

@@ -134,36 +143,38 @@ class _ColorMigrationVisitor extends MigrationVisitor {
134143
return namespace;
135144
}
136145

137-
/// Patches a deprecated channel function to use `color.channel` instead.
138-
void _patchChannel(FunctionExpression node, [String? colorSpace]) {
139-
addPatch(Patch(node.nameSpan, 'channel'));
140-
146+
/// Returns the patches to make a deprecated channel function use
147+
/// `color.channel` instead.
148+
Iterable<Patch> _makeChannelPatches(FunctionExpression node,
149+
[String? colorSpace]) sync* {
150+
yield Patch(node.nameSpan, 'channel');
141151
if (node.arguments.named.isEmpty) {
142-
addPatch(patchAfter(
152+
yield patchAfter(
143153
node.arguments.positional.last,
144154
", '${node.name}'"
145-
"${colorSpace == null ? '' : ', \$space: $colorSpace'}"));
155+
"${colorSpace == null ? '' : ', \$space: $colorSpace'}");
146156
} else {
147-
addPatch(patchAfter(
157+
yield patchAfter(
148158
[...node.arguments.positional, ...node.arguments.named.values].last,
149159
", \$channel: '${node.name}'"
150-
"${colorSpace == null ? '' : ', \$space: $colorSpace'}"));
160+
"${colorSpace == null ? '' : ', \$space: $colorSpace'}");
151161
}
152162
}
153163

154-
/// Patches a deprecated adjustment function to use `color.adjust` instead.
155-
void _patchAdjust(FunctionExpression node,
156-
{required String channel, bool negate = false, String? space}) {
157-
addPatch(Patch(node.nameSpan, 'adjust'));
164+
/// Returns the patches to make a deprecated adjustment function use
165+
/// `color.adjust` instead.
166+
Iterable<Patch> _makeAdjustPatches(FunctionExpression node,
167+
{required String channel, bool negate = false, String? space}) sync* {
168+
yield Patch(node.nameSpan, 'adjust');
158169
switch (node.arguments) {
159170
case ArgumentInvocation(positional: [_, var adjustment]):
160-
addPatch(patchBefore(adjustment, '\$$channel: ${negate ? '-' : ''}'));
171+
yield patchBefore(adjustment, '\$$channel: ${negate ? '-' : ''}');
161172
if (negate && adjustment.needsParens) {
162-
addPatch(patchBefore(adjustment, '('));
163-
addPatch(patchAfter(adjustment, ')'));
173+
yield patchBefore(adjustment, '(');
174+
yield patchAfter(adjustment, ')');
164175
}
165176
if (space != null) {
166-
addPatch(patchAfter(adjustment, ', \$space: $space'));
177+
yield patchAfter(adjustment, ', \$space: $space');
167178
}
168179

169180
case ArgumentInvocation(
@@ -178,16 +189,16 @@ class _ColorMigrationVisitor extends MigrationVisitor {
178189
.pointSpan()
179190
.extendIfMatches('amount')
180191
.extendIfMatches('degrees');
181-
addPatch(Patch(argNameSpan, channel));
192+
yield Patch(argNameSpan, channel);
182193
if (negate) {
183-
addPatch(patchBefore(adjustment, '-'));
194+
yield patchBefore(adjustment, '-');
184195
if (adjustment.needsParens) {
185-
addPatch(patchBefore(adjustment, '('));
186-
addPatch(patchAfter(adjustment, ')'));
196+
yield patchBefore(adjustment, '(');
197+
yield patchAfter(adjustment, ')');
187198
}
188199
}
189200
if (space != null) {
190-
addPatch(patchAfter(adjustment, ', \$space: $space'));
201+
yield patchAfter(adjustment, ', \$space: $space');
191202
}
192203

193204
default:

‎pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: sass_migrator
2-
version: 2.3.0
2+
version: 2.3.1
33
description: A tool for running migrations on Sass files
44
homepage: https://github.com/sass/migrator
55

‎test/migrators/color/nested.hrx

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<==> input/entrypoint.scss
2+
$color: gold;
3+
4+
a {
5+
b: saturate(desaturate($color, 10%), 10%);
6+
c: rgba(red($color), green($color), blue($color), 0.5);
7+
d: lighten($color, red($color));
8+
e: darken($color, blue($color));
9+
}
10+
11+
<==> output/entrypoint.scss
12+
@use "sass:color";
13+
14+
$color: gold;
15+
16+
a {
17+
b: color.adjust(color.adjust($color, $saturation: -10%, $space: hsl), $saturation: 10%, $space: hsl);
18+
c: rgba(color.channel($color, 'red', $space: rgb), color.channel($color, 'green', $space: rgb), color.channel($color, 'blue', $space: rgb), 0.5);
19+
d: color.adjust($color, $lightness: color.channel($color, 'red', $space: rgb), $space: hsl);
20+
e: color.adjust($color, $lightness: -(color.channel($color, 'blue', $space: rgb)), $space: hsl);
21+
}

0 commit comments

Comments
 (0)
Please sign in to comment.