diff --git a/lib/src/interpolation_buffer.dart b/lib/src/interpolation_buffer.dart new file mode 100644 index 00000000..0cece471 --- /dev/null +++ b/lib/src/interpolation_buffer.dart @@ -0,0 +1,41 @@ +// 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:source_span/source_span.dart'; + +import 'ast/expression/interpolation.dart'; +import 'ast/expression.dart'; + +class InterpolationBuffer implements StringSink { + final _text = new StringBuffer(); + + final _contents = []; + + bool get isEmpty => _contents.isEmpty && _text.isEmpty; + + void clear() { + _contents.clear(); + _text.clear(); + } + + void write(Object obj) => _text.write(obj); + void writeAll(Iterable objects, [String separator = '']) => + _text.writeAll(objects, separator); + void writeCharCode(int character) => _text.writeCharCode(character); + void writeln([Object obj = '']) => _text.writeln(obj); + + void add(Expression expression) { + if (_text.isNotEmpty) { + _contents.add(_text.toString()); + _text.clear(); + } + _contents.add(expression); + } + + InterpolationExpression interpolation([SourceSpan span]) { + var contents = _contents.toList(); + if (_text.isNotEmpty) contents.add(_text.toString()); + return new InterpolationExpression(contents, span: span); + } +} diff --git a/lib/src/parser.dart b/lib/src/parser.dart index 0d7436b8..0bdf1350 100644 --- a/lib/src/parser.dart +++ b/lib/src/parser.dart @@ -13,6 +13,7 @@ import 'ast/expression/interpolation.dart'; import 'ast/expression/list.dart'; import 'ast/stylesheet.dart'; import 'ast/variable_declaration.dart'; +import 'interpolation_buffer.dart'; class Parser { final SpanScanner _scanner; @@ -213,24 +214,21 @@ class Parser { InterpolationExpression _interpolatedIdentifier() { var start = _scanner.state; - var contents = []; - var text = new StringBuffer(); + var buffer = new InterpolationBuffer(); while (_scanChar($dash)) { - text.writeCharCode($dash); + buffer.writeCharCode($dash); } var first = _scanner.peekChar(); if (first == null) { _scanner.error("Expected identifier."); } else if (_isNameStart(first)) { - text.writeCharCode(_scanner.readChar()); + buffer.writeCharCode(_scanner.readChar()); } else if (first == $backslash) { - text.writeCharCode(_escape()); + buffer.writeCharCode(_escape()); } else if (first == $hash) { - if (!text.isEmpty) contents.add(text.toString()); - text.clear(); - contents.add(_singleInterpolation()); + buffer.add(_singleInterpolation()); } while (true) { @@ -239,21 +237,17 @@ class Parser { break; } else if (next == $underscore || next == $dash || _isAlphabetic(next) || _isDigit(next) || next >= 0x0080) { - text.writeCharCode(_scanner.readChar()); + buffer.writeCharCode(_scanner.readChar()); } else if (next == $backslash) { - text.writeCharCode(_escape()); + buffer.writeCharCode(_escape()); } else if (next == $hash) { - if (!text.isEmpty) contents.add(text.toString()); - text.clear(); - contents.add(_singleInterpolation()); + buffer.add(_singleInterpolation()); } else { break; } } - if (!text.isEmpty) contents.add(text.toString()); - return new InterpolationExpression( - contents, span: _scanner.spanFrom(start)); + return buffer.interpolation(_scanner.spanFrom(start)); } Expression _singleInterpolation() {