Skip to content
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

Merged
merged 4 commits into from
Jan 4, 2024
Merged

Conversation

jathak
Copy link
Member

@jathak jathak commented Jan 3, 2024

  • 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.

- 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.
@jathak jathak requested a review from nex3 January 3, 2024 04:33
return false;
}
var channels = switch (node.arguments) {
ArgumentInvocation(positional: [ListExpression arg, ...], named: Map()) =>
Copy link
Contributor

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).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment on lines 296 to 297
left: NumberExpression _,
right: NumberExpression _
Copy link
Contributor

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

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment on lines 294 to 303
switch (last) {
case BinaryOperationExpression(
left: NumberExpression _,
right: NumberExpression _
):
break;
default:
_patchSpacesToCommas(channels);
_patchOperatorToComma(last);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could just be:

Suggested change
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);

Copy link
Member Author

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?

Copy link
Contributor

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.

Copy link
Member Author

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?

Copy link
Contributor

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.

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;
Copy link
Contributor

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.

Copy link
Member Author

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.

return node.operator == BinaryOperator.dividedBy &&
_onlySlash(node.left) &&
_onlySlash(node.right);
switch (node) {
Copy link
Contributor

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

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 769 to 770
var tuple = importCache.canonicalize(ruleUrl,
baseImporter: importer, baseUrl: currentUrl, forImport: true);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Destructure this tuple

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 1269 to 1270
var tuple = _originalImports[url];
if (tuple != null && tuple.item2 is NodeModulesImporter) {
return Tuple2(tuple.item1, false);
if (tuple case (var url, NodeModulesImporter _)) {
Copy link
Contributor

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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

/// current scope.
abstract class ScopedAstVisitor
with RecursiveStatementVisitor, RecursiveAstVisitor {
/// The current scope, containing any visible without a namespace to the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any visible what?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment on lines 67 to 68
var defaultValue = argument.defaultValue;
if (defaultValue != null) visitExpression(defaultValue);
Copy link
Contributor

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

Copy link
Member Author

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;
Copy link
Contributor

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.

Copy link
Member Author

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.

@jathak jathak requested a review from nex3 January 4, 2024 00:57
@jathak jathak merged commit 387292f into main Jan 4, 2024
17 checks passed
@jathak jathak deleted the support-latest-sass branch January 4, 2024 22:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants