Skip to content

Commit 874c62f

Browse files
authored
Add strict unary migrator (#227)
1 parent ef1de68 commit 874c62f

10 files changed

+139
-6
lines changed

CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## 1.6.0
2+
3+
### Strict Unary Migrator
4+
5+
* Add a new migrator for eliminating ambiguous syntax for the `+` and `-`
6+
operators that will soon be deprecated.
7+
18
## 1.5.6
29

310
* No user-visible changes.

lib/src/migrators/strict_unary.dart

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Use of this source code is governed by an MIT-style
4+
// license that can be found in the LICENSE file or at
5+
// https://opensource.org/licenses/MIT.
6+
7+
import 'package:sass_api/sass_api.dart';
8+
9+
import '../migration_visitor.dart';
10+
import '../migrator.dart';
11+
import '../patch.dart';
12+
13+
/// Migrates deprecated `$a -$b` construct to unambiguous `$a - $b`.
14+
class StrictUnaryMigrator extends Migrator {
15+
final name = "strict-unary";
16+
final description = r"Migrates deprecated `$a -$b` syntax (and similar) to "
17+
r"unambiguous `$a - $b`";
18+
19+
@override
20+
Map<Uri, String> migrateFile(
21+
ImportCache importCache, Stylesheet stylesheet, Importer importer) {
22+
var visitor = _UnaryMigrationVisitor(importCache, migrateDependencies);
23+
var result = visitor.run(stylesheet, importer);
24+
missingDependencies.addAll(visitor.missingDependencies);
25+
return result;
26+
}
27+
}
28+
29+
class _UnaryMigrationVisitor extends MigrationVisitor {
30+
_UnaryMigrationVisitor(ImportCache importCache, bool migrateDependencies)
31+
: super(importCache, migrateDependencies);
32+
33+
@override
34+
void visitBinaryOperationExpression(BinaryOperationExpression node) {
35+
if (node.operator == BinaryOperator.plus ||
36+
node.operator == BinaryOperator.minus) {
37+
var betweenOperands = node.span.file
38+
.span(node.left.span.end.offset, node.right.span.start.offset)
39+
.text;
40+
if (betweenOperands.startsWith(RegExp(r'\s')) &&
41+
betweenOperands.endsWith(node.operator.operator)) {
42+
addPatch(Patch.insert(node.right.span.start, ' '));
43+
}
44+
}
45+
super.visitBinaryOperationExpression(node);
46+
}
47+
}

lib/src/runner.dart

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import 'io.dart';
1616
import 'migrators/division.dart';
1717
import 'migrators/module.dart';
1818
import 'migrators/namespace.dart';
19+
import 'migrators/strict_unary.dart';
1920
import 'exception.dart';
2021

2122
/// A command runner that runs a migrator based on provided arguments.
@@ -55,6 +56,7 @@ class MigratorRunner extends CommandRunner<Map<Uri, String>> {
5556
addCommand(DivisionMigrator());
5657
addCommand(ModuleMigrator());
5758
addCommand(NamespaceMigrator());
59+
addCommand(StrictUnaryMigrator());
5860
}
5961

6062
/// Runs a migrator and then writes the migrated files to disk unless

pubspec.yaml

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

@@ -10,13 +10,12 @@ dependencies:
1010
args: ^2.1.0
1111
charcode: ^1.2.0
1212
collection: ^1.16.0
13-
# Workaround until pulyaevskiy/node-interop#110 is resolved
14-
file: '>=6.1.0 <6.1.2'
13+
file: ^6.1.4
1514
glob: ^2.0.1
1615
js: ^0.6.3
1716
meta: ^1.3.0
1817
node_interop: ^2.0.2
19-
node_io: ^2.1.0
18+
node_io: ^2.2.0
2019
path: ^1.8.0
2120
sass_api: ^3.0.0
2221
source_span: ^1.8.1

test/migrators/namespace_node_test.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ import '../utils.dart';
1212

1313
main() {
1414
runNodeTests = true;
15-
testMigrator("division");
15+
testMigrator("namespace");
1616
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<==> input/entrypoint.scss
2+
$x: 1;
3+
$y: 2;
4+
5+
plus {
6+
a: $x +$y;
7+
b: ($x) +($y);
8+
c: $x +$y +$y;
9+
}
10+
11+
minus {
12+
a: $x -$y;
13+
b: ($x) -($y);
14+
c: $x -$y -$y;
15+
}
16+
17+
<==> output/entrypoint.scss
18+
$x: 1;
19+
$y: 2;
20+
21+
plus {
22+
a: $x + $y;
23+
b: ($x) + ($y);
24+
c: $x + $y + $y;
25+
}
26+
27+
minus {
28+
a: $x - $y;
29+
b: ($x) - ($y);
30+
c: $x - $y - $y;
31+
}
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<==> input/entrypoint.scss
2+
$x: 1;
3+
$y: 2;
4+
5+
plus {
6+
a: $x+$y;
7+
b: $x + $y;
8+
c: $x (+$y);
9+
d: $x+ $y;
10+
}
11+
12+
minus {
13+
a: ($x)-$y;
14+
b: $x - $y;
15+
c: $x (-$y);
16+
d: ($x)- $y;
17+
}
18+
19+
<==> log.txt
20+
Nothing to migrate!
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Use of this source code is governed by an MIT-style
4+
// license that can be found in the LICENSE file or at
5+
// https://opensource.org/licenses/MIT.
6+
7+
import '../utils.dart';
8+
9+
main() {
10+
testMigrator("strict_unary");
11+
}
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Use of this source code is governed by an MIT-style
4+
// license that can be found in the LICENSE file or at
5+
// https://opensource.org/licenses/MIT.
6+
7+
@Tags(["node"])
8+
9+
import 'package:test/test.dart';
10+
11+
import '../utils.dart';
12+
13+
main() {
14+
runNodeTests = true;
15+
testMigrator("strict_unary");
16+
}

test/utils.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ Future<void> _testHrx(File hrxFile, String migrator) async {
5656
await files.unpack();
5757

5858
var process = await runMigrator([
59-
migrator,
59+
migrator.replaceAll('_', '-'),
6060
'--no-unicode',
6161
...files.arguments,
6262
for (var path in files.input.keys)

0 commit comments

Comments
 (0)