/
list.dart
69 lines (56 loc) · 2.13 KB
/
list.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// Copyright 2016 Google Inc. Use of this source code is governed by an
// MIT-style license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.
import 'package:charcode/charcode.dart';
import 'package:meta/meta.dart';
import 'package:source_span/source_span.dart';
import '../../../value.dart';
import '../../../visitor/interface/expression.dart';
import '../expression.dart';
import 'unary_operation.dart';
/// A list literal.
///
/// {@category AST}
@sealed
class ListExpression implements Expression {
/// The elements of this list.
final List<Expression> contents;
/// Which separator this list uses.
final ListSeparator separator;
/// Whether the list has square brackets or not.
final bool hasBrackets;
final FileSpan span;
ListExpression(Iterable<Expression> contents, this.separator, this.span,
{bool brackets = false})
: contents = List.unmodifiable(contents),
hasBrackets = brackets;
T accept<T>(ExpressionVisitor<T> visitor) =>
visitor.visitListExpression(this);
String toString() {
var buffer = StringBuffer();
if (hasBrackets) buffer.writeCharCode($lbracket);
buffer.write(contents
.map((element) =>
_elementNeedsParens(element) ? "($element)" : element.toString())
.join(separator == ListSeparator.comma ? ", " : " "));
if (hasBrackets) buffer.writeCharCode($rbracket);
return buffer.toString();
}
/// Returns whether [expression], contained in [this], needs parentheses when
/// printed as Sass source.
bool _elementNeedsParens(Expression expression) {
if (expression is ListExpression) {
if (expression.contents.length < 2) return false;
if (expression.hasBrackets) return false;
return separator == ListSeparator.comma
? expression.separator == ListSeparator.comma
: expression.separator != ListSeparator.undecided;
}
if (separator != ListSeparator.space) return false;
if (expression is UnaryOperationExpression) {
return expression.operator == UnaryOperator.plus ||
expression.operator == UnaryOperator.minus;
}
return false;
}
}