mirror of
https://github.com/danog/dart-sass.git
synced 2025-01-21 21:31:11 +01:00
Add an explicit IfClause class
This commit is contained in:
parent
ce1ea0d4a3
commit
3de6680bcb
@ -3,7 +3,6 @@
|
||||
// https://opensource.org/licenses/MIT.
|
||||
|
||||
import 'package:source_span/source_span.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
||||
import '../../../visitor/interface/statement.dart';
|
||||
import '../expression.dart';
|
||||
@ -18,30 +17,50 @@ class IfRule implements Statement {
|
||||
/// The first clause whose expression evaluates to `true` will have its
|
||||
/// statements executed. If no expression evaluates to `true`, `lastClause`
|
||||
/// will be executed if it's not `null`.
|
||||
final List<Tuple2<Expression, List<Statement>>> clauses;
|
||||
final List<IfClause> clauses;
|
||||
|
||||
/// The final, unconditional `@else` clause.
|
||||
///
|
||||
/// This is `null` if there is no unconditional `@else`.
|
||||
final List<Statement> lastClause;
|
||||
final IfClause lastClause;
|
||||
|
||||
final FileSpan span;
|
||||
|
||||
IfRule(Iterable<Tuple2<Expression, Iterable<Statement>>> clauses, this.span,
|
||||
{Iterable<Statement> lastClause})
|
||||
: clauses = new List.unmodifiable(clauses.map((pair) =>
|
||||
new Tuple2(pair.item1, new List.unmodifiable(pair.item2)))),
|
||||
lastClause =
|
||||
lastClause == null ? null : new List.unmodifiable(lastClause);
|
||||
IfRule(Iterable<IfClause> clauses, this.span, {this.lastClause})
|
||||
: clauses = new List.unmodifiable(clauses) {
|
||||
assert(clauses.every((clause) => clause.expression != null));
|
||||
assert(lastClause?.expression == null);
|
||||
}
|
||||
|
||||
T accept<T>(StatementVisitor<T> visitor) => visitor.visitIfRule(this);
|
||||
|
||||
String toString() {
|
||||
var first = true;
|
||||
return clauses.map((pair) {
|
||||
return clauses.map((clause) {
|
||||
var name = first ? 'if' : 'else';
|
||||
first = false;
|
||||
return '@$name ${pair.item1} {${pair.item2.join(" ")}}';
|
||||
return '@$name ${clause.expression} {${clause.children.join(" ")}}';
|
||||
}).join(' ');
|
||||
}
|
||||
}
|
||||
|
||||
/// A single clause in an `@if` rule.
|
||||
class IfClause {
|
||||
/// The expression to evaluate to determine whether to run this rule, or
|
||||
/// `null` if this is the final unconditional `@else` clause.
|
||||
final Expression expression;
|
||||
|
||||
/// The statements to evaluate if this clause matches.
|
||||
final List<Statement> children;
|
||||
|
||||
IfClause(this.expression, Iterable<Statement> children)
|
||||
: children = new List.unmodifiable(children);
|
||||
|
||||
IfClause.last(Iterable<Statement> children)
|
||||
: expression = null,
|
||||
children = new List.unmodifiable(children);
|
||||
|
||||
String toString() =>
|
||||
(expression == null ? "@else" : "@if $expression") +
|
||||
" {${children.join(' ')}}";
|
||||
}
|
||||
|
@ -671,16 +671,16 @@ abstract class StylesheetParser extends Parser {
|
||||
var expression = _expression();
|
||||
var children = this.children(child);
|
||||
|
||||
var clauses = [new Tuple2(expression, children)];
|
||||
List<Statement> lastClause;
|
||||
var clauses = [new IfClause(expression, children)];
|
||||
IfClause lastClause;
|
||||
|
||||
while (scanElse(ifIndentation)) {
|
||||
whitespace();
|
||||
if (scanIdentifier("if")) {
|
||||
whitespace();
|
||||
clauses.add(new Tuple2(_expression(), this.children(child)));
|
||||
clauses.add(new IfClause(_expression(), this.children(child)));
|
||||
} else {
|
||||
lastClause = this.children(child);
|
||||
lastClause = new IfClause.last(this.children(child));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -634,16 +634,17 @@ class _EvaluateVisitor
|
||||
|
||||
Future<Value> visitIfRule(IfRule node) async {
|
||||
var clause = node.lastClause;
|
||||
for (var pair in node.clauses) {
|
||||
if ((await pair.item1.accept(this)).isTruthy) {
|
||||
clause = pair.item2;
|
||||
for (var clauseToCheck in node.clauses) {
|
||||
if ((await clauseToCheck.expression.accept(this)).isTruthy) {
|
||||
clause = clauseToCheck;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (clause == null) return null;
|
||||
|
||||
return await _environment.scope(
|
||||
() => _handleReturn<Statement>(clause, (child) => child.accept(this)),
|
||||
() => _handleReturn<Statement>(
|
||||
clause.children, (child) => child.accept(this)),
|
||||
semiGlobal: true);
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
// DO NOT EDIT. This file was generated from async_evaluate.dart.
|
||||
// See tool/synchronize.dart for details.
|
||||
//
|
||||
// Checksum: ae64ba442752642066f0e9e038f5f2c1bbfa866b
|
||||
// Checksum: 33e96540f3e5999ed172d168221b27910e8672b1
|
||||
|
||||
import 'dart:math' as math;
|
||||
|
||||
@ -629,16 +629,17 @@ class _EvaluateVisitor
|
||||
|
||||
Value visitIfRule(IfRule node) {
|
||||
var clause = node.lastClause;
|
||||
for (var pair in node.clauses) {
|
||||
if (pair.item1.accept(this).isTruthy) {
|
||||
clause = pair.item2;
|
||||
for (var clauseToCheck in node.clauses) {
|
||||
if (clauseToCheck.expression.accept(this).isTruthy) {
|
||||
clause = clauseToCheck;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (clause == null) return null;
|
||||
|
||||
return _environment.scope(
|
||||
() => _handleReturn<Statement>(clause, (child) => child.accept(this)),
|
||||
() => _handleReturn<Statement>(
|
||||
clause.children, (child) => child.accept(this)),
|
||||
semiGlobal: true);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user