From 0498e8a95c8ab3cae6c97973c8b0aa522a9f2c25 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 26 Aug 2016 22:43:10 -0700 Subject: [PATCH] InterpolationExpression -> Interpolation --- lib/src/ast/sass/at_rule.dart | 3 +- lib/src/ast/sass/declaration.dart | 3 +- lib/src/ast/sass/expression.dart | 1 - lib/src/ast/sass/expression/function.dart | 2 +- lib/src/ast/sass/expression/identifier.dart | 4 +- lib/src/ast/sass/expression/string.dart | 8 ++-- lib/src/ast/sass/extend_rule.dart | 3 +- .../sass/{expression => }/interpolation.dart | 11 ++--- lib/src/ast/sass/media_query.dart | 12 +++--- lib/src/ast/sass/statement.dart | 1 + lib/src/ast/sass/style_rule.dart | 3 +- lib/src/interpolation_buffer.dart | 7 ++-- lib/src/parser.dart | 20 +++++----- lib/src/visitor/interface/expression.dart | 8 ++-- lib/src/visitor/perform.dart | 40 +++++++++---------- 15 files changed, 60 insertions(+), 66 deletions(-) rename lib/src/ast/sass/{expression => }/interpolation.dart (80%) diff --git a/lib/src/ast/sass/at_rule.dart b/lib/src/ast/sass/at_rule.dart index e3e74c95..649beb44 100644 --- a/lib/src/ast/sass/at_rule.dart +++ b/lib/src/ast/sass/at_rule.dart @@ -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 children; diff --git a/lib/src/ast/sass/declaration.dart b/lib/src/ast/sass/declaration.dart index a76e169b..c1ed2b45 100644 --- a/lib/src/ast/sass/declaration.dart +++ b/lib/src/ast/sass/declaration.dart @@ -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; diff --git a/lib/src/ast/sass/expression.dart b/lib/src/ast/sass/expression.dart index 5ff00baf..d1590277 100644 --- a/lib/src/ast/sass/expression.dart +++ b/lib/src/ast/sass/expression.dart @@ -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'; diff --git a/lib/src/ast/sass/expression/function.dart b/lib/src/ast/sass/expression/function.dart index 892b3419..e97920c1 100644 --- a/lib/src/ast/sass/expression/function.dart +++ b/lib/src/ast/sass/expression/function.dart @@ -10,7 +10,7 @@ import '../expression.dart'; import '../statement.dart'; class FunctionExpression implements Expression { - final InterpolationExpression name; + final Interpolation name; final ArgumentInvocation arguments; diff --git a/lib/src/ast/sass/expression/identifier.dart b/lib/src/ast/sass/expression/identifier.dart index c5bfc3ea..f170bf7e 100644 --- a/lib/src/ast/sass/expression/identifier.dart +++ b/lib/src/ast/sass/expression/identifier.dart @@ -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; diff --git a/lib/src/ast/sass/expression/string.dart b/lib/src/ast/sass/expression/string.dart index 583cfe9f..49c06229 100644 --- a/lib/src/ast/sass/expression/string.dart +++ b/lib/src/ast/sass/expression/string.dart @@ -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++) { diff --git a/lib/src/ast/sass/extend_rule.dart b/lib/src/ast/sass/extend_rule.dart index 9fd6e7a9..e9e950f7 100644 --- a/lib/src/ast/sass/extend_rule.dart +++ b/lib/src/ast/sass/extend_rule.dart @@ -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; diff --git a/lib/src/ast/sass/expression/interpolation.dart b/lib/src/ast/sass/interpolation.dart similarity index 80% rename from lib/src/ast/sass/expression/interpolation.dart rename to lib/src/ast/sass/interpolation.dart index 87ce1f89..45d1b1fc 100644 --- a/lib/src/ast/sass/expression/interpolation.dart +++ b/lib/src/ast/sass/interpolation.dart @@ -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/**/(ExpressionVisitor/**/ visitor) => - visitor.visitInterpolationExpression(this); - String toString() => contents.map((value) => value is String ? value : "#{$value}").join(); } \ No newline at end of file diff --git a/lib/src/ast/sass/media_query.dart b/lib/src/ast/sass/media_query.dart index 7a559933..dc4133a7 100644 --- a/lib/src/ast/sass/media_query.dart +++ b/lib/src/ast/sass/media_query.dart @@ -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 features; + final List features; FileSpan get span { var components = []; @@ -25,12 +25,12 @@ class MediaQuery implements SassNode { } MediaQuery(this.type, {this.modifier, - Iterable features}) + Iterable features}) : features = features == null ? const [] : new List.unmodifiable(features); - MediaQuery.condition(Iterable features, + MediaQuery.condition(Iterable features, {this.modifier, this.type}) : features = new List.unmodifiable(features); diff --git a/lib/src/ast/sass/statement.dart b/lib/src/ast/sass/statement.dart index dc9be57e..ed3b18e8 100644 --- a/lib/src/ast/sass/statement.dart +++ b/lib/src/ast/sass/statement.dart @@ -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'; diff --git a/lib/src/ast/sass/style_rule.dart b/lib/src/ast/sass/style_rule.dart index 0c080e0c..14eef86c 100644 --- a/lib/src/ast/sass/style_rule.dart +++ b/lib/src/ast/sass/style_rule.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 children; diff --git a/lib/src/interpolation_buffer.dart b/lib/src/interpolation_buffer.dart index bbe89ef3..43598370 100644 --- a/lib/src/interpolation_buffer.dart +++ b/lib/src/interpolation_buffer.dart @@ -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"; diff --git a/lib/src/parser.dart b/lib/src/parser.dart index 0aad4199..1175462a 100644 --- a/lib/src/parser.dart +++ b/lib/src/parser.dart @@ -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 = []; + var features = []; 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); } diff --git a/lib/src/visitor/interface/expression.dart b/lib/src/visitor/interface/expression.dart index 291c1356..39ccd02f 100644 --- a/lib/src/visitor/interface/expression.dart +++ b/lib/src/visitor/interface/expression.dart @@ -3,6 +3,7 @@ // https://opensource.org/licenses/MIT. import '../../ast/sass/expression.dart'; +import '../../ast/sass/statement.dart'; abstract class ExpressionVisitor { T visitVariableExpression(VariableExpression node) => null; @@ -16,7 +17,7 @@ abstract class ExpressionVisitor { } T visitIdentifierExpression(IdentifierExpression node) { - visitInterpolationExpression(node.text); + _visitInterpolation(node.text); return null; } @@ -48,14 +49,13 @@ abstract class ExpressionVisitor { } 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; } } diff --git a/lib/src/visitor/perform.dart b/lib/src/visitor/perform.dart index ea58c5d2..762b4db2 100644 --- a/lib/src/visitor/perform.dart +++ b/lib/src/visitor/perform.dart @@ -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 _performInterpolation( - InterpolationExpression interpolation, {bool trim: false}) { - var result = visitInterpolationExpression(interpolation).text; + CssValue _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 _performExpression(Expression expression) => new CssValue(expression.accept(this), span: expression.span);