-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use latest Dart Sass and release migrator 2.0.0 #251
Conversation
- 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` now extends this. - Refactored the `division` migrator to use patterns.
lib/src/migrators/division.dart
Outdated
return false; | ||
} | ||
var channels = switch (node.arguments) { | ||
ArgumentInvocation(positional: [ListExpression arg, ...], named: Map()) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be [ListExpression arg]
? The old code only matches if there's only one positional argument.
Also, I think named: Map()
just checks that named
's type is Map
. If you want to check that it's empty, you'll need to do named: Map(length: 0)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
lib/src/migrators/division.dart
Outdated
left: NumberExpression _, | ||
right: NumberExpression _ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here I think NumberExpression()
is more idiomatic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
lib/src/migrators/division.dart
Outdated
switch (last) { | ||
case BinaryOperationExpression( | ||
left: NumberExpression _, | ||
right: NumberExpression _ | ||
): | ||
break; | ||
default: | ||
_patchSpacesToCommas(channels); | ||
_patchOperatorToComma(last); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could just be:
switch (last) { | |
case BinaryOperationExpression( | |
left: NumberExpression _, | |
right: NumberExpression _ | |
): | |
break; | |
default: | |
_patchSpacesToCommas(channels); | |
_patchOperatorToComma(last); | |
} | |
if (last case BinaryOperationExpression( | |
left: NumberExpression(), | |
right: NumberExpression() | |
)) { | |
break; | |
} | |
_patchSpacesToCommas(channels); | |
_patchOperatorToComma(last); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The break was to break out of the switch, since we only want to call the _patch*
functions when the pattern is not matched, but we do still want to do the _withContext
part either way. Is this structure (with an empty if
and the patch calls in an else
) better than the switch?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I see. In Dart 3 you no longer need a break
at the end of a case
block; they don't fall through unless either the block is empty or you explicitly opt into it with continue
.
In this case I'd like if
/case
/else
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the idiomatic way to have an empty case
block that doesn't fall through?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case you need break
, but only that case.
lib/src/migrators/division.dart
Outdated
addPatch(Patch(node.right.span, '${1 / divisor.value}')); | ||
return true; | ||
if (node.right case NumberExpression(unit: null, value: var divisor)) { | ||
if (!_allowedDivisors.contains(divisor)) return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd put this in a when
clause since it's logically part of the same condition as the if
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Forgot that when clauses where an option.
lib/src/migrators/division.dart
Outdated
return node.operator == BinaryOperator.dividedBy && | ||
_onlySlash(node.left) && | ||
_onlySlash(node.right); | ||
switch (node) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd make this a switch expression
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
lib/src/migrators/module.dart
Outdated
var tuple = importCache.canonicalize(ruleUrl, | ||
baseImporter: importer, baseUrl: currentUrl, forImport: true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Destructure this tuple
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
lib/src/migrators/module.dart
Outdated
var tuple = _originalImports[url]; | ||
if (tuple != null && tuple.item2 is NodeModulesImporter) { | ||
return Tuple2(tuple.item1, false); | ||
if (tuple case (var url, NodeModulesImporter _)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I'd inline the variable here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
lib/src/util/scoped_ast_visitor.dart
Outdated
/// current scope. | ||
abstract class ScopedAstVisitor | ||
with RecursiveStatementVisitor, RecursiveAstVisitor { | ||
/// The current scope, containing any visible without a namespace to the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any visible what?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
lib/src/util/scoped_ast_visitor.dart
Outdated
var defaultValue = argument.defaultValue; | ||
if (defaultValue != null) visitExpression(defaultValue); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Prefer if
/case
for situations where a variable is only used within a null-check block, so the variable's scope matches its usage
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
||
var oldImporter = _importer; | ||
_importer = result.item1; | ||
var stylesheet = result.item2; | ||
var oldScope = currentScope; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding a when:
parameter to scoped()
and using that here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scoped()
adds a new child scope, whereas here we're creating a new empty scope for a new module.
media-logic
migrator (breaking change bumps version to 2.0.0).calc-interpolation
anddivision
migrators to eliminate their use of the removedCalculationExpression
AST node.ScopedAstVisitor
that usesScope
to track Sass member declarations.MigrationVisitor
and_ReferenceVisitor
now extend this.division
migrator to use patterns.