mirror of
https://github.com/danog/dart-sass.git
synced 2025-01-21 21:31:11 +01:00
InterpolationExpression -> Interpolation
This commit is contained in:
parent
860f761c27
commit
0498e8a95c
@ -5,13 +5,12 @@
|
||||
import 'package:source_span/source_span.dart';
|
||||
|
||||
import '../../visitor/interface/statement.dart';
|
||||
import 'expression/interpolation.dart';
|
||||
import 'statement.dart';
|
||||
|
||||
class AtRule implements Statement {
|
||||
final String name;
|
||||
|
||||
final InterpolationExpression value;
|
||||
final Interpolation value;
|
||||
|
||||
final List<Statement> children;
|
||||
|
||||
|
@ -6,11 +6,10 @@ import 'package:source_span/source_span.dart';
|
||||
|
||||
import '../../visitor/interface/statement.dart';
|
||||
import 'expression.dart';
|
||||
import 'expression/interpolation.dart';
|
||||
import 'statement.dart';
|
||||
|
||||
class Declaration implements Statement {
|
||||
final InterpolationExpression name;
|
||||
final Interpolation name;
|
||||
|
||||
final Expression value;
|
||||
|
||||
|
@ -9,7 +9,6 @@ export 'expression/boolean.dart';
|
||||
export 'expression/color.dart';
|
||||
export 'expression/function.dart';
|
||||
export 'expression/identifier.dart';
|
||||
export 'expression/interpolation.dart';
|
||||
export 'expression/list.dart';
|
||||
export 'expression/map.dart';
|
||||
export 'expression/number.dart';
|
||||
|
@ -10,7 +10,7 @@ import '../expression.dart';
|
||||
import '../statement.dart';
|
||||
|
||||
class FunctionExpression implements Expression {
|
||||
final InterpolationExpression name;
|
||||
final Interpolation name;
|
||||
|
||||
final ArgumentInvocation arguments;
|
||||
|
||||
|
@ -6,10 +6,10 @@ import 'package:source_span/source_span.dart';
|
||||
|
||||
import '../../../visitor/interface/expression.dart';
|
||||
import '../expression.dart';
|
||||
import 'interpolation.dart';
|
||||
import '../statement.dart';
|
||||
|
||||
class IdentifierExpression implements Expression {
|
||||
final InterpolationExpression text;
|
||||
final Interpolation text;
|
||||
|
||||
FileSpan get span => text.span;
|
||||
|
||||
|
@ -9,7 +9,7 @@ import '../../../interpolation_buffer.dart';
|
||||
import '../../../util/character.dart';
|
||||
import '../../../visitor/interface/expression.dart';
|
||||
import '../expression.dart';
|
||||
import 'interpolation.dart';
|
||||
import '../statement.dart';
|
||||
|
||||
class StringExpression implements Expression {
|
||||
/// Interpolation that, when evaluated, produces the semantic content of the
|
||||
@ -17,7 +17,7 @@ class StringExpression implements Expression {
|
||||
///
|
||||
/// Unlike [asInterpolation], escapes are resolved and quotes are not
|
||||
/// included.
|
||||
final InterpolationExpression text;
|
||||
final Interpolation text;
|
||||
|
||||
FileSpan get span => text.span;
|
||||
|
||||
@ -29,11 +29,11 @@ class StringExpression implements Expression {
|
||||
/// Interpolation that, when evaluated, produces the syntax of the string.
|
||||
///
|
||||
/// Unlike [text], his doesn't resolve escapes and does include quotes.
|
||||
InterpolationExpression asInterpolation({bool static: false, int quote}) {
|
||||
Interpolation asInterpolation({bool static: false, int quote}) {
|
||||
quote ??= _bestQuote();
|
||||
var buffer = new InterpolationBuffer()..writeCharCode(quote);
|
||||
for (var value in text.contents) {
|
||||
if (value is InterpolationExpression) {
|
||||
if (value is Interpolation) {
|
||||
buffer.addInterpolation(value);
|
||||
} else if (value is String) {
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
|
@ -5,11 +5,10 @@
|
||||
import 'package:source_span/source_span.dart';
|
||||
|
||||
import '../../visitor/interface/statement.dart';
|
||||
import 'expression.dart';
|
||||
import 'statement.dart';
|
||||
|
||||
class ExtendRule implements Statement {
|
||||
final InterpolationExpression selector;
|
||||
final Interpolation selector;
|
||||
|
||||
final FileSpan span;
|
||||
|
||||
|
@ -4,10 +4,10 @@
|
||||
|
||||
import 'package:source_span/source_span.dart';
|
||||
|
||||
import '../../../visitor/interface/expression.dart';
|
||||
import '../expression.dart';
|
||||
import 'expression.dart';
|
||||
import 'node.dart';
|
||||
|
||||
class InterpolationExpression implements Expression {
|
||||
class Interpolation implements SassNode {
|
||||
final List contents;
|
||||
|
||||
final FileSpan span;
|
||||
@ -24,7 +24,7 @@ class InterpolationExpression implements Expression {
|
||||
/// Returns the plain text before the interpolation, or the empty string.
|
||||
String get initialPlain => contents.first is String ? contents.first : '';
|
||||
|
||||
InterpolationExpression(Iterable/*(String|Expression)*/ contents, {this.span})
|
||||
Interpolation(Iterable/*(String|Expression)*/ contents, {this.span})
|
||||
: contents = new List.unmodifiable(contents) {
|
||||
for (var i = 0; i < this.contents.length; i++) {
|
||||
if (this.contents[i] is! String && this.contents[i] is! Expression) {
|
||||
@ -40,9 +40,6 @@ class InterpolationExpression implements Expression {
|
||||
}
|
||||
}
|
||||
|
||||
/*=T*/ accept/*<T>*/(ExpressionVisitor/*<T>*/ visitor) =>
|
||||
visitor.visitInterpolationExpression(this);
|
||||
|
||||
String toString() =>
|
||||
contents.map((value) => value is String ? value : "#{$value}").join();
|
||||
}
|
@ -6,15 +6,15 @@ import 'package:source_span/source_span.dart';
|
||||
|
||||
import '../../utils.dart';
|
||||
import '../node.dart';
|
||||
import 'expression.dart';
|
||||
import 'node.dart';
|
||||
import 'statement.dart';
|
||||
|
||||
class MediaQuery implements SassNode {
|
||||
final InterpolationExpression modifier;
|
||||
final Interpolation modifier;
|
||||
|
||||
final InterpolationExpression type;
|
||||
final Interpolation type;
|
||||
|
||||
final List<InterpolationExpression> features;
|
||||
final List<Interpolation> features;
|
||||
|
||||
FileSpan get span {
|
||||
var components = <AstNode>[];
|
||||
@ -25,12 +25,12 @@ class MediaQuery implements SassNode {
|
||||
}
|
||||
|
||||
MediaQuery(this.type, {this.modifier,
|
||||
Iterable<InterpolationExpression> features})
|
||||
Iterable<Interpolation> features})
|
||||
: features = features == null
|
||||
? const []
|
||||
: new List.unmodifiable(features);
|
||||
|
||||
MediaQuery.condition(Iterable<InterpolationExpression> features,
|
||||
MediaQuery.condition(Iterable<Interpolation> features,
|
||||
{this.modifier, this.type})
|
||||
: features = new List.unmodifiable(features);
|
||||
|
||||
|
@ -13,6 +13,7 @@ export 'comment.dart';
|
||||
export 'declaration.dart';
|
||||
export 'extend_rule.dart';
|
||||
export 'function_declaration.dart';
|
||||
export 'interpolation.dart';
|
||||
export 'media_query.dart';
|
||||
export 'media_rule.dart';
|
||||
export 'return.dart';
|
||||
|
@ -5,11 +5,10 @@
|
||||
import 'package:source_span/source_span.dart';
|
||||
|
||||
import '../../visitor/interface/statement.dart';
|
||||
import 'expression/interpolation.dart';
|
||||
import 'statement.dart';
|
||||
|
||||
class StyleRule implements Statement {
|
||||
final InterpolationExpression selector;
|
||||
final Interpolation selector;
|
||||
|
||||
final List<Statement> children;
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
import 'package:source_span/source_span.dart';
|
||||
|
||||
import 'ast/sass/expression.dart';
|
||||
import 'ast/sass/statement.dart';
|
||||
|
||||
class InterpolationBuffer implements StringSink {
|
||||
final _text = new StringBuffer();
|
||||
@ -29,7 +30,7 @@ class InterpolationBuffer implements StringSink {
|
||||
_contents.add(expression);
|
||||
}
|
||||
|
||||
void addInterpolation(InterpolationExpression expression) {
|
||||
void addInterpolation(Interpolation expression) {
|
||||
if (expression.contents.isEmpty) return;
|
||||
|
||||
var toAdd = expression.contents;
|
||||
@ -50,10 +51,10 @@ class InterpolationBuffer implements StringSink {
|
||||
_text.clear();
|
||||
}
|
||||
|
||||
InterpolationExpression interpolation([FileSpan span]) {
|
||||
Interpolation interpolation([FileSpan span]) {
|
||||
var contents = _contents.toList();
|
||||
if (_text.isNotEmpty) contents.add(_text.toString());
|
||||
return new InterpolationExpression(contents, span: span);
|
||||
return new Interpolation(contents, span: span);
|
||||
}
|
||||
|
||||
String toString() => "${_contents.join('')}$_text";
|
||||
|
@ -132,7 +132,7 @@ class Parser {
|
||||
span: _scanner.spanFrom(start));
|
||||
}
|
||||
|
||||
InterpolationExpression value;
|
||||
Interpolation value;
|
||||
var next = _scanner.peekChar();
|
||||
if (next != $exclamation && next != $semicolon && next != $lbrace &&
|
||||
next != $rbrace && next != null) {
|
||||
@ -213,7 +213,7 @@ class Parser {
|
||||
Expression _declarationExpression() {
|
||||
if (_scanner.peekChar() == $lbrace) {
|
||||
return new StringExpression(
|
||||
new InterpolationExpression([], span: _scanner.emptySpan));
|
||||
new Interpolation([], span: _scanner.emptySpan));
|
||||
}
|
||||
|
||||
return _expression();
|
||||
@ -762,7 +762,7 @@ class Parser {
|
||||
return new SassColor.rgb(red, green, blue);
|
||||
}
|
||||
|
||||
bool _isHexColor(InterpolationExpression interpolation) {
|
||||
bool _isHexColor(Interpolation interpolation) {
|
||||
var plain = interpolation.asPlain;
|
||||
if (plain == null) return false;
|
||||
if (plain.length != 3 && plain.length != 6) return false;
|
||||
@ -791,7 +791,7 @@ class Parser {
|
||||
///
|
||||
/// This respects string boundaries and supports interpolation. Once this
|
||||
/// interpolation is evaluated, it's expected to be re-parsed.
|
||||
InterpolationExpression _almostAnyValue() {
|
||||
Interpolation _almostAnyValue() {
|
||||
var start = _scanner.state;
|
||||
var buffer = new InterpolationBuffer();
|
||||
|
||||
@ -951,7 +951,7 @@ class Parser {
|
||||
buffer.interpolation(_scanner.spanFrom(start)));
|
||||
}
|
||||
|
||||
InterpolationExpression _interpolatedIdentifier() {
|
||||
Interpolation _interpolatedIdentifier() {
|
||||
var start = _scanner.state;
|
||||
var buffer = new InterpolationBuffer();
|
||||
|
||||
@ -1312,8 +1312,8 @@ class Parser {
|
||||
}
|
||||
|
||||
MediaQuery _mediaQuery() {
|
||||
InterpolationExpression modifier;
|
||||
InterpolationExpression type;
|
||||
Interpolation modifier;
|
||||
Interpolation type;
|
||||
if (_scanner.peekChar() != $lparen) {
|
||||
var identifier1 = _interpolatedIdentifier();
|
||||
_ignoreComments();
|
||||
@ -1345,7 +1345,7 @@ class Parser {
|
||||
// We've consumed either `IDENTIFIER "and"` or
|
||||
// `IDENTIFIER IDENTIFIER "and"`.
|
||||
|
||||
var features = <InterpolationExpression>[];
|
||||
var features = <Interpolation>[];
|
||||
do {
|
||||
_ignoreComments();
|
||||
features.add(_mediaExpression());
|
||||
@ -1358,10 +1358,10 @@ class Parser {
|
||||
}
|
||||
}
|
||||
|
||||
InterpolationExpression _mediaExpression() {
|
||||
Interpolation _mediaExpression() {
|
||||
if (_scanner.peekChar() == $hash) {
|
||||
var interpolation = _singleInterpolation();
|
||||
return new InterpolationExpression([interpolation],
|
||||
return new Interpolation([interpolation],
|
||||
span: interpolation.span);
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
// https://opensource.org/licenses/MIT.
|
||||
|
||||
import '../../ast/sass/expression.dart';
|
||||
import '../../ast/sass/statement.dart';
|
||||
|
||||
abstract class ExpressionVisitor<T> {
|
||||
T visitVariableExpression(VariableExpression node) => null;
|
||||
@ -16,7 +17,7 @@ abstract class ExpressionVisitor<T> {
|
||||
}
|
||||
|
||||
T visitIdentifierExpression(IdentifierExpression node) {
|
||||
visitInterpolationExpression(node.text);
|
||||
_visitInterpolation(node.text);
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -48,14 +49,13 @@ abstract class ExpressionVisitor<T> {
|
||||
}
|
||||
|
||||
T visitStringExpression(StringExpression node) {
|
||||
visitInterpolationExpression(node.text);
|
||||
_visitInterpolation(node.text);
|
||||
return null;
|
||||
}
|
||||
|
||||
T visitInterpolationExpression(InterpolationExpression node) {
|
||||
void _visitInterpolation(Interpolation node) {
|
||||
for (var value in node.contents) {
|
||||
if (value is Expression) value.accept(this);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ class PerformVisitor extends StatementVisitor
|
||||
}
|
||||
|
||||
void visitDeclaration(Declaration node) {
|
||||
var name = _performInterpolation(node.name);
|
||||
var name = _interpolationToValue(node.name);
|
||||
if (_declarationName != null) {
|
||||
name = new CssValue("$_declarationName-${name.value}", span: name.span);
|
||||
}
|
||||
@ -87,7 +87,7 @@ class PerformVisitor extends StatementVisitor
|
||||
}
|
||||
|
||||
void visitExtendRule(ExtendRule node) {
|
||||
var targetText = _performInterpolation(node.selector);
|
||||
var targetText = _interpolationToValue(node.selector);
|
||||
|
||||
// TODO: recontextualize parse errors.
|
||||
// TODO: disallow parent selectors.
|
||||
@ -98,7 +98,7 @@ class PerformVisitor extends StatementVisitor
|
||||
void visitAtRule(AtRule node) {
|
||||
var value = node.value == null
|
||||
? null
|
||||
: _performInterpolation(node.value, trim: true);
|
||||
: _interpolationToValue(node.value, trim: true);
|
||||
|
||||
if (node.children == null) {
|
||||
_parent.addChild(new CssAtRule(node.name, value: value, span: node.span));
|
||||
@ -165,14 +165,14 @@ class PerformVisitor extends StatementVisitor
|
||||
CssMediaQuery _visitMediaQuery(MediaQuery query) {
|
||||
var modifier = query.modifier == null
|
||||
? null
|
||||
: _performInterpolation(query.modifier);
|
||||
: _interpolationToValue(query.modifier);
|
||||
|
||||
var type = query.type == null
|
||||
? null
|
||||
: _performInterpolation(query.type);
|
||||
: _interpolationToValue(query.type);
|
||||
|
||||
var features = query.features
|
||||
.map((feature) => _performInterpolation(feature));
|
||||
.map((feature) => _interpolationToValue(feature));
|
||||
|
||||
if (type == null) return new CssMediaQuery.condition(features);
|
||||
return new CssMediaQuery(type, modifier: modifier, features: features);
|
||||
@ -181,7 +181,7 @@ class PerformVisitor extends StatementVisitor
|
||||
Value visitReturn(Return node) => node.expression.accept(this);
|
||||
|
||||
void visitStyleRule(StyleRule node) {
|
||||
var selectorText = _performInterpolation(node.selector, trim: true);
|
||||
var selectorText = _interpolationToValue(node.selector, trim: true);
|
||||
var parsedSelector = new Parser(selectorText.value).parseSelector();
|
||||
|
||||
// TOOD: catch errors and point them to node.selector
|
||||
@ -227,7 +227,7 @@ class PerformVisitor extends StatementVisitor
|
||||
}
|
||||
|
||||
SassIdentifier visitIdentifierExpression(IdentifierExpression node) =>
|
||||
new SassIdentifier(visitInterpolationExpression(node.text).text);
|
||||
new SassIdentifier(_performInterpolation(node.text));
|
||||
|
||||
SassBoolean visitBooleanExpression(BooleanExpression node) =>
|
||||
new SassBoolean(node.value);
|
||||
@ -237,13 +237,6 @@ class PerformVisitor extends StatementVisitor
|
||||
|
||||
SassColor visitColorExpression(ColorExpression node) => node.value;
|
||||
|
||||
SassString visitInterpolationExpression(InterpolationExpression node) {
|
||||
return new SassString(node.contents.map((value) {
|
||||
if (value is String) return value;
|
||||
return (value as Expression).accept(this);
|
||||
}).join());
|
||||
}
|
||||
|
||||
SassList visitListExpression(ListExpression node) => new SassList(
|
||||
node.contents.map((expression) => expression.accept(this)),
|
||||
node.separator,
|
||||
@ -276,7 +269,7 @@ class PerformVisitor extends StatementVisitor
|
||||
"Plain CSS functions don't support keyword arguments.");
|
||||
}
|
||||
|
||||
var name = node.name.accept(this);
|
||||
var name = _performInterpolation(node.name);
|
||||
var arguments = node.arguments.positional
|
||||
.map((expression) => expression.accept(this)).toList();
|
||||
// TODO: if rest is an arglist that has keywords, error out.
|
||||
@ -381,7 +374,7 @@ class PerformVisitor extends StatementVisitor
|
||||
}
|
||||
|
||||
SassString visitStringExpression(StringExpression node) =>
|
||||
visitInterpolationExpression(node.text);
|
||||
new SassString(_performInterpolation(node.text));
|
||||
|
||||
// ## Utilities
|
||||
|
||||
@ -393,13 +386,20 @@ class PerformVisitor extends StatementVisitor
|
||||
return result;
|
||||
}
|
||||
|
||||
CssValue<String> _performInterpolation(
|
||||
InterpolationExpression interpolation, {bool trim: false}) {
|
||||
var result = visitInterpolationExpression(interpolation).text;
|
||||
CssValue<String> _interpolationToValue(
|
||||
Interpolation interpolation, {bool trim: false}) {
|
||||
var result = _performInterpolation(interpolation);
|
||||
return new CssValue(trim ? result.trim() : result,
|
||||
span: interpolation.span);
|
||||
}
|
||||
|
||||
String _performInterpolation(Interpolation interpolation) {
|
||||
return interpolation.contents.map((value) {
|
||||
if (value is String) return value;
|
||||
return (value as Expression).accept(this);
|
||||
}).join();
|
||||
}
|
||||
|
||||
CssValue<Value> _performExpression(Expression expression) =>
|
||||
new CssValue(expression.accept(this), span: expression.span);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user