Skip to content

Commit 387292f

Browse files
authored
Use latest Dart Sass and release migrator 2.0.0 (#251)
- Deleted the obsolete `media-logic` migrator (breaking change bumps version to 2.0.0). - Moved off of the tuple package to native Dart tuples. - Fixed the `calc-interpolation` and `division` migrators to eliminate their use of the removed `CalculationExpression` AST node. - Created a new `ScopedAstVisitor` that uses `Scope` to track Sass member declarations. `MigrationVisitor` and `_ReferenceVisitor` now extend this. - Refactored the `division` migrator to use patterns.
1 parent 31ea60a commit 387292f

18 files changed

+456
-386
lines changed

CHANGELOG.md

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,40 @@
1-
## 1.8.2
1+
## 2.0.0
2+
3+
* **Breaking change**: The `media-logic` migrator has been removed as the
4+
[corresponding breaking change][media logic] has been completed in Dart Sass.
5+
If you still need to migrate legacy code, use migrator version 1.8.1.
6+
7+
[media logic]: https://sass-lang.com/documentation/breaking-changes/media-logic/
8+
9+
* Update to be compatible with the latest version of the Dart Sass AST.
210

311
### Calc Functions Interpolation Migrator
412

5-
* Add parentheses in place of interpolation when necessary to preserve the evaluation order.
13+
* Add parentheses in place of interpolation when necessary to preserve the
14+
evaluation order.
15+
16+
### Division Migrator
17+
18+
* `/` division should now be left untouched in all CSS calculation functions.
19+
This was already the case for `calc`, `clamp`, `min`, and `max`, but it now
20+
applies to the new functions that Dart Sass 1.67.0 added support for.
621

722
## 1.8.1
823

924
### Calc Functions Interpolation Migrator
1025

11-
* Migration for more than one interpolation or expressions in a calc function parameter.
26+
* Migration for more than one interpolation or expressions in a calc function
27+
parameter.
1228

1329
## 1.8.0
1430

1531
### Calc Functions Interpolation Migrator
1632

17-
* Removes interpolation in calculation functions `calc()`, `clamp()`, `min()`, and `max()`.
18-
See the [scss/function-calculation-no-interpolation](https://github.com/stylelint-scss/stylelint-scss/tree/master/src/rules/function-calculation-no-interpolation) rule for more information.
33+
* Removes interpolation in calculation functions `calc()`, `clamp()`, `min()`,
34+
and `max()`. See the [scss/function-calculation-no-interpolation] rule for
35+
more information.
36+
37+
[scss/function-calculation-no-interpolation]: https://github.com/stylelint-scss/stylelint-scss/tree/master/src/rules/function-calculation-no-interpolation
1938

2039
## 1.7.3
2140

lib/src/migration_visitor.dart

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import 'package:source_span/source_span.dart';
1313

1414
import 'exception.dart';
1515
import 'patch.dart';
16+
import 'util/scope.dart';
17+
import 'util/scoped_ast_visitor.dart';
1618

1719
/// A visitor that migrates a stylesheet.
1820
///
@@ -24,8 +26,7 @@ import 'patch.dart';
2426
/// If [migrateDependencies] is enabled, this visitor will construct and run a
2527
/// new instance of itself (using [newInstance]) each time it encounters an
2628
/// `@import` or `@use` rule.
27-
abstract class MigrationVisitor
28-
with RecursiveStatementVisitor, RecursiveAstVisitor {
29+
abstract class MigrationVisitor extends ScopedAstVisitor {
2930
/// A mapping from URLs to migrated contents for stylesheets already migrated.
3031
final _migrated = <Uri, String>{};
3132

@@ -117,26 +118,31 @@ abstract class MigrationVisitor
117118

118119
/// Visits the stylesheet at [dependency], resolved based on the current
119120
/// stylesheet's URL and importer.
121+
///
122+
/// When [forImport] is true, this preserves the [currentScope]. Otherwise,
123+
/// the dependency is visited with a new global scope for the new module.
120124
@protected
121125
void visitDependency(Uri dependency, FileSpan context,
122126
{bool forImport = false}) {
123127
if (dependency.scheme == 'sass') return;
124128
var result = importCache.import(dependency,
125129
baseImporter: _importer, baseUrl: _currentUrl, forImport: forImport);
126-
if (result != null) {
130+
if (result case (var newImporter, var stylesheet)) {
127131
// If [dependency] comes from a non-relative import, don't migrate it,
128132
// because it's likely to be outside the user's repository and may even be
129133
// authored by a different person.
130134
//
131135
// TODO(nweiz): Add a flag to override this behavior for load paths
132136
// (#104).
133-
if (result.item1 != _importer) return;
137+
if (newImporter != _importer) return;
134138

135139
var oldImporter = _importer;
136-
_importer = result.item1;
137-
var stylesheet = result.item2;
140+
var oldScope = currentScope;
141+
_importer = newImporter;
142+
if (!forImport) currentScope = Scope();
138143
visitStylesheet(stylesheet);
139144
_importer = oldImporter;
145+
currentScope = oldScope;
140146
} else {
141147
_missingDependencies.putIfAbsent(
142148
context.sourceUrl!.resolveUri(dependency), () => context);

lib/src/migrator.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ abstract class Migrator extends Command<Map<Uri, String>> {
9393
throw MigrationException("Could not find Sass file at '$entrypoint'.");
9494
}
9595

96-
var migrated = migrateFile(importCache, tuple.item2, tuple.item1);
96+
var migrated = migrateFile(importCache, tuple.$2, tuple.$1);
9797
migrated.forEach((file, contents) {
9898
if (allMigrated.containsKey(file) && contents != allMigrated[file]) {
9999
throw MigrationException(

lib/src/migrators/calc_interpolation.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ class _CalculationInterpolationVisitor extends MigrationVisitor {
3333
: super(importCache, migrateDependencies);
3434

3535
@override
36-
void visitCalculationExpression(CalculationExpression node) {
36+
void visitFunctionExpression(FunctionExpression node) {
3737
const calcFunctions = ['calc', 'clamp', 'min', 'max'];
3838
final interpolation = RegExp(r'\#{\s*[^}]+\s*}');
3939
final hasOperation = RegExp(r'[-+*/]+');
4040
if (calcFunctions.contains(node.name)) {
41-
for (var arg in node.arguments) {
41+
for (var arg in node.arguments.positional) {
4242
var newArg = arg.toString();
4343
for (var match in interpolation.allMatches(arg.toString())) {
4444
var noInterpolation =
@@ -58,6 +58,6 @@ class _CalculationInterpolationVisitor extends MigrationVisitor {
5858
}
5959
}
6060
}
61-
super.visitCalculationExpression(node);
61+
super.visitFunctionExpression(node);
6262
}
6363
}

0 commit comments

Comments
 (0)