Skip to content

Commit

Permalink
Convert visitor classes to mixins (#1784)
Browse files Browse the repository at this point in the history
Co-authored-by: Jennifer Thakar <jathak@google.com>
  • Loading branch information
nex3 and jathak committed Aug 19, 2022
1 parent 7695332 commit 98f326b
Show file tree
Hide file tree
Showing 12 changed files with 30 additions and 40 deletions.
2 changes: 1 addition & 1 deletion lib/src/ast/css/node.dart
Expand Up @@ -62,7 +62,7 @@ abstract class CssParentNode extends CssNode {
}

/// The visitor used to implement [CssNode.isInvisible]
class _IsInvisibleVisitor extends EveryCssVisitor {
class _IsInvisibleVisitor with EveryCssVisitor {
/// Whether to consider selectors with bogus combinators invisible.
final bool includeBogus;

Expand Down
2 changes: 1 addition & 1 deletion lib/src/ast/sass/statement/mixin_rule.dart
Expand Up @@ -50,7 +50,7 @@ class MixinRule extends CallableDeclaration implements SassDeclaration {

/// A visitor for determining whether a [MixinRule] recursively contains a
/// [ContentRule].
class _HasContentVisitor extends StatementSearchVisitor<bool> {
class _HasContentVisitor with StatementSearchVisitor<bool> {
const _HasContentVisitor();

bool visitContentRule(_) => true;
Expand Down
6 changes: 3 additions & 3 deletions lib/src/ast/selector.dart
Expand Up @@ -98,7 +98,7 @@ abstract class Selector {
}

/// The visitor used to implement [Selector.isInvisible].
class _IsInvisibleVisitor extends AnySelectorVisitor {
class _IsInvisibleVisitor with AnySelectorVisitor {
/// Whether to consider selectors with bogus combinators invisible.
final bool includeBogus;

Expand Down Expand Up @@ -128,7 +128,7 @@ class _IsInvisibleVisitor extends AnySelectorVisitor {
}

/// The visitor used to implement [Selector.isBogus].
class _IsBogusVisitor extends AnySelectorVisitor {
class _IsBogusVisitor with AnySelectorVisitor {
/// Whether to consider selectors with leading combinators as bogus.
final bool includeLeadingCombinator;

Expand Down Expand Up @@ -159,7 +159,7 @@ class _IsBogusVisitor extends AnySelectorVisitor {
}

/// The visitor used to implement [Selector.isUseless]
class _IsUselessVisitor extends AnySelectorVisitor {
class _IsUselessVisitor with AnySelectorVisitor {
const _IsUselessVisitor();

bool visitComplexSelector(ComplexSelector complex) =>
Expand Down
4 changes: 1 addition & 3 deletions lib/src/visitor/any_selector.dart
Expand Up @@ -12,9 +12,7 @@ import 'interface/selector.dart';
///
/// Each method returns `false` by default.
@internal
abstract class AnySelectorVisitor implements SelectorVisitor<bool> {
const AnySelectorVisitor();

mixin AnySelectorVisitor implements SelectorVisitor<bool> {
bool visitComplexSelector(ComplexSelector complex) => complex.components
.any((component) => visitCompoundSelector(component.selector));

Expand Down
4 changes: 1 addition & 3 deletions lib/src/visitor/every_css.dart
Expand Up @@ -12,9 +12,7 @@ import 'interface/css.dart';
///
/// Each method returns `false` by default.
@internal
abstract class EveryCssVisitor implements CssVisitor<bool> {
const EveryCssVisitor();

mixin EveryCssVisitor implements CssVisitor<bool> {
bool visitCssAtRule(CssAtRule node) =>
node.children.every((child) => child.accept(this));
bool visitCssComment(CssComment node) => false;
Expand Down
2 changes: 1 addition & 1 deletion lib/src/visitor/find_dependencies.dart
Expand Up @@ -19,7 +19,7 @@ Tuple2<List<Uri>, List<Uri>> findDependencies(Stylesheet stylesheet) =>

/// A visitor that traverses a stylesheet and records, all `@import`, `@use`,
/// and `@forward` rules (excluding built-in modules) it contains.
class _FindDependenciesVisitor extends RecursiveStatementVisitor {
class _FindDependenciesVisitor with RecursiveStatementVisitor {
final _usesAndForwards = <Uri>[];
final _imports = <Uri>[];

Expand Down
4 changes: 1 addition & 3 deletions lib/src/visitor/recursive_ast.dart
Expand Up @@ -20,10 +20,8 @@ import 'recursive_statement.dart';
/// * [visitInterpolation]
///
/// {@category Visitor}
abstract class RecursiveAstVisitor extends RecursiveStatementVisitor
mixin RecursiveAstVisitor on RecursiveStatementVisitor
implements ExpressionVisitor<void> {
const RecursiveAstVisitor();

void visitAtRootRule(AtRootRule node) {
node.query.andThen(visitInterpolation);
super.visitAtRootRule(node);
Expand Down
4 changes: 1 addition & 3 deletions lib/src/visitor/recursive_selector.dart
Expand Up @@ -9,9 +9,7 @@ import 'interface/selector.dart';
/// A visitor that recursively traverses each component of a Selector AST.
///
/// {@category Visitor}
abstract class RecursiveSelectorVisitor implements SelectorVisitor<void> {
const RecursiveSelectorVisitor();

mixin RecursiveSelectorVisitor implements SelectorVisitor<void> {
void visitAttributeSelector(AttributeSelector attribute) {}
void visitClassSelector(ClassSelector klass) {}
void visitIDSelector(IDSelector id) {}
Expand Down
4 changes: 1 addition & 3 deletions lib/src/visitor/recursive_statement.dart
Expand Up @@ -18,9 +18,7 @@ import 'interface/statement.dart';
/// * [visitChildren]
///
/// {@category Visitor}
abstract class RecursiveStatementVisitor implements StatementVisitor<void> {
const RecursiveStatementVisitor();

mixin RecursiveStatementVisitor implements StatementVisitor<void> {
void visitAtRootRule(AtRootRule node) {
visitChildren(node.children);
}
Expand Down
4 changes: 1 addition & 3 deletions lib/src/visitor/statement_search.dart
Expand Up @@ -18,9 +18,7 @@ import 'recursive_statement.dart';
/// This supports the same additional methods as [RecursiveStatementVisitor].
///
/// {@category Visitor}
abstract class StatementSearchVisitor<T> implements StatementVisitor<T?> {
const StatementSearchVisitor();

mixin StatementSearchVisitor<T> implements StatementVisitor<T?> {
T? visitAtRootRule(AtRootRule node) => visitChildren(node.children);

T? visitAtRule(AtRule node) => node.children.andThen(visitChildren);
Expand Down
20 changes: 18 additions & 2 deletions pkg/sass_api/CHANGELOG.md
@@ -1,7 +1,23 @@
## 3.0.0

* Replace the `minSpecificity` and `maxSpecificity` fields on `ComplexSelector`,
`CompoundSelector`, and `SimpleSelector` with a single `specificity` field.
* **Breaking change:** Convert all visitor superclasses into mixins. This
includes `RecursiveAstVisitor`, `RecursiveSelectorVisitor`,
`RecursiveStatementVisitor`, and `StatementSearchVisitor`. This has several
effects;

* You must use `with` to mix in visitors rather than `extends`.

* It's now possible to mix multiple visitors into the same class, which wasn't
possible with `extends`.

* Because [mixins can't be composed], when mixing in `RecursiveAstVisitor` you
must explicitly mix in `RecursiveStatementVisitor` as well.

[mixins can't be composed]: https://github.com/dart-lang/language/issues/540

* **Breaking change:** Replace the `minSpecificity` and `maxSpecificity` fields
on `ComplexSelector`, `CompoundSelector`, and `SimpleSelector` with a single
`specificity` field.

## 2.0.4

Expand Down
14 changes: 0 additions & 14 deletions test/dart_api/visitor_test.dart

This file was deleted.

0 comments on commit 98f326b

Please sign in to comment.