Skip to content

Commit

Permalink
migrate to null safe dart
Browse files Browse the repository at this point in the history
  • Loading branch information
jonahwilliams committed Nov 1, 2020
1 parent cec5095 commit 7fcc19c
Show file tree
Hide file tree
Showing 14 changed files with 118 additions and 111 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## 2.0.0

* Support for null safe dart added.

## 1.0.0+1

* Fixed regression where lookups from list did not work. Removed failing tests
Expand Down
6 changes: 5 additions & 1 deletion analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
include: package:pedantic/analysis_options.yaml
linter:
rules:
unawaited_futures: true
curly_braces_in_flow_control_structures: true
avoid_catches_without_on_clauses: true
18 changes: 9 additions & 9 deletions lib/mustache.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ abstract class Template {
{bool lenient,
bool htmlEscapeValues,
String name,
PartialResolver partialResolver,
PartialResolver? partialResolver,
String delimiters}) = t.Template.fromSource;

String get name;
String? get name;
String get source;

/// [values] can be a combination of Map, List, String. Any non-String object
Expand All @@ -28,7 +28,7 @@ abstract class Template {
void render(values, StringSink sink);
}

typedef PartialResolver = Template Function(String);
typedef PartialResolver = Template? Function(String);

typedef LambdaFunction = Object Function(LambdaContext context);

Expand All @@ -39,7 +39,7 @@ abstract class LambdaContext {
/// Render the current section tag in the current context and return the
/// result as a string. If provided, value will be added to the top of the
/// context's stack.
String renderString({Object value});
String renderString({Object? value});

/// Render and directly output the current section tag. If provided, value
/// will be added to the top of the context's stack.
Expand All @@ -54,10 +54,10 @@ abstract class LambdaContext {

/// Evaluate the string as a mustache template using the current context. If
/// provided, value will be added to the top of the context's stack.
String renderSource(String source, {Object value});
String renderSource(String source, {Object? value});

/// Lookup the value of a variable in the current context.
Object lookup(String variableName);
Object? lookup(String variableName);
}

/// [TemplateException] is used to obtain the line and column numbers
Expand All @@ -68,7 +68,7 @@ abstract class TemplateException implements Exception {

/// The name used to identify the template, as passed to the Template
/// constructor.
String get templateName;
String? get templateName;

/// The 1-based line number of the token where formatting error was found.
int get line;
Expand All @@ -77,10 +77,10 @@ abstract class TemplateException implements Exception {
int get column;

/// The character offset within the template source.
int get offset;
int? get offset;

/// The template source.
String get source;
String? get source;

/// A short source substring of the source at the point the problem occurred
/// with parsing or rendering.
Expand Down
18 changes: 8 additions & 10 deletions lib/src/lambda_context.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class LambdaContext implements m.LambdaContext {
}

@override
String renderString({Object value}) {
String renderString({Object? value}) {
_checkClosed();
if (_node is! SectionNode) {
_error(
Expand All @@ -38,15 +38,15 @@ class LambdaContext implements m.LambdaContext {
return sink.toString();
}

void _renderSubtree(StringSink sink, Object value) {
void _renderSubtree(StringSink sink, Object? value) {
var renderer = Renderer.subtree(_renderer, sink);
SectionNode section = _node;
var section = _node as SectionNode;
if (value != null) renderer.push(value);
renderer.render(section.children);
}

@override
void render({Object value}) {
void render({Object? value}) {
_checkClosed();
if (_node is! SectionNode) {
_error('LambdaContext.render() can only be called on section tags.');
Expand All @@ -66,10 +66,8 @@ class LambdaContext implements m.LambdaContext {

if (_node is! SectionNode) return '';

SectionNode node = _node;

var node = _node as SectionNode;
var nodes = node.children;

if (nodes.isEmpty) return '';

if (nodes.length == 1 && nodes.first is TextNode) {
Expand All @@ -80,14 +78,14 @@ class LambdaContext implements m.LambdaContext {
}

@override
String renderSource(String source, {Object value}) {
String renderSource(String source, {Object? value}) {
_checkClosed();
var sink = StringBuffer();

// Lambdas used for sections should parse with the current delimiters.
var delimiters = '{{ }}';
if (_node is SectionNode) {
SectionNode node = _node;
var node = _node as SectionNode;
delimiters = node.delimiters;
}

Expand All @@ -104,7 +102,7 @@ class LambdaContext implements m.LambdaContext {
}

@override
Object lookup(String variableName) {
Object? lookup(String variableName) {
_checkClosed();
return _renderer.resolveValue(variableName);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/src/node.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class SectionNode extends Node {
final String delimiters;
final bool inverse;
final int contentStart;
int contentEnd; // Set in parser when close tag is parsed.
int? contentEnd; // Set in parser when close tag is parsed.
final List<Node> children = <Node>[];

@override
Expand Down
40 changes: 20 additions & 20 deletions lib/src/parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import 'template_exception.dart';
import 'token.dart';

List<Node> parse(
String source, bool lenient, String templateName, String delimiters) {
String source, bool lenient, String? templateName, String delimiters) {
var parser = Parser(source, templateName, delimiters, lenient: lenient);
return parser.parse();
}
Expand Down Expand Up @@ -33,7 +33,7 @@ class TagType {
}

class Parser {
Parser(String source, String templateName, String delimiters,
Parser(String source, String? templateName, String delimiters,
{lenient = false})
: _source = source,
_templateName = templateName,
Expand All @@ -43,12 +43,12 @@ class Parser {

final String _source;
final bool _lenient;
final String _templateName;
final String? _templateName;
final String _delimiters;
final Scanner _scanner;
final List<SectionNode> _stack = <SectionNode>[];
List<Token> _tokens;
String _currentDelimiters;
late List<Token> _tokens;
String? _currentDelimiters;
int _offset = 0;

List<Node> parse() {
Expand Down Expand Up @@ -83,7 +83,7 @@ class Parser {
break;

case TokenType.lineEnd:
_appendTextToken(_read());
_appendTextToken(_read()!);
_parseLine();
break;

Expand All @@ -101,11 +101,11 @@ class Parser {
}

// Returns null on EOF.
Token _peek() => _offset < _tokens.length ? _tokens[_offset] : null;
Token? _peek() => _offset < _tokens.length ? _tokens[_offset] : null;

// Returns null on EOF.
Token _read() {
Token t;
Token? _read() {
Token? t;
if (_offset < _tokens.length) {
t = _tokens[_offset];
_offset++;
Expand All @@ -122,7 +122,7 @@ class Parser {
return token;
}

Token _readIf(TokenType type, {eofOk = false}) {
Token? _readIf(TokenType type, {eofOk = false}) {
var token = _peek();
if (!eofOk && token == null) throw _errorEof();
return token != null && token.type == type ? _read() : null;
Expand Down Expand Up @@ -151,14 +151,14 @@ class Parser {

// Add the node to top most section on the stack. If a section node then
// push it onto the stack, if a close section tag, then pop the stack.
void _appendTag(Tag tag, Node node) {
void _appendTag(Tag tag, Node? node) {
switch (tag.type) {

// {{#...}} {{^...}}
case TagType.openSection:
case TagType.openInverseSection:
_stack.last.children.add(node);
_stack.add(node);
_stack.last.children.add(node!);
_stack.add(node as SectionNode);
break;

// {{/...}}
Expand Down Expand Up @@ -229,7 +229,7 @@ class Parser {
];

if (tag != null &&
(_peek() == null || _peek().type == TokenType.lineEnd) &&
(_peek() == null || _peek()!.type == TokenType.lineEnd) &&
standaloneTypes.contains(tag.type)) {
// This is a tag on a "standalone line", so do not create text nodes
// for whitespace, or the following newline.
Expand Down Expand Up @@ -259,7 +259,7 @@ class Parser {

// If open delimiter, or change delimiter token then return a tag.
// If EOF or any another token then return null.
Tag _readTag() {
Tag? _readTag() {
var t = _peek();
if (t == null ||
(t.type != TokenType.changeDelimiter &&
Expand All @@ -284,7 +284,7 @@ class Parser {
// A sigil is the character which identifies which sort of tag it is,
// i.e. '#', '/', or '>'.
// Variable tags and triple mustache tags don't have a sigil.
TagType tagType;
TagType? tagType;

if (open.value == '{{{') {
tagType = TagType.tripleMustache;
Expand Down Expand Up @@ -328,21 +328,21 @@ class Parser {

var close = _expect(TokenType.closeDelimiter);

return Tag(tagType, name, open.start, close.end);
return Tag(tagType!, name, open.start, close.end);
}

Node _createNodeFromTag(Tag tag, {String partialIndent = ''}) {
Node? _createNodeFromTag(Tag? tag, {String partialIndent = ''}) {
// Handle EOF case.
if (tag == null) {
return null;
}

Node node;
Node? node;
switch (tag.type) {
case TagType.openSection:
case TagType.openInverseSection:
var inverse = tag.type == TagType.openInverseSection;
node = SectionNode(tag.name, tag.start, tag.end, _currentDelimiters,
node = SectionNode(tag.name, tag.start, tag.end, _currentDelimiters!,
inverse: inverse);
break;

Expand Down
26 changes: 14 additions & 12 deletions lib/src/renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ class Renderer extends Visitor {
final List _stack;
final bool lenient;
final bool htmlEscapeValues;
final m.PartialResolver partialResolver;
final String templateName;
final m.PartialResolver? partialResolver;
final String? templateName;
final String indent;
final String source;

Expand All @@ -48,7 +48,7 @@ class Renderer extends Visitor {
void write(Object output) => sink.write(output.toString());

void render(List<Node> nodes) {
if (indent == null || indent == '') {
if (indent == '') {
nodes.forEach((n) => n.accept(this));
} else if (nodes.isNotEmpty) {
// Special case to make sure there is not an extra indent after the last
Expand All @@ -69,7 +69,7 @@ class Renderer extends Visitor {
@override
void visitText(TextNode node, {bool lastNode = false}) {
if (node.text == '') return;
if (indent == null || indent == '') {
if (indent == '') {
write(node.text);
} else if (lastNode && node.text.runes.last == _NEWLINE) {
// Don't indent after the last line in a template.
Expand All @@ -87,7 +87,7 @@ class Renderer extends Visitor {

if (value is Function) {
var context = LambdaContext(node, this);
Function valueFunction = value;
var valueFunction = value;
value = valueFunction(context);
context.close();
}
Expand All @@ -101,7 +101,7 @@ class Renderer extends Visitor {
var output = !node.escape || !htmlEscapeValues
? valueString
: _htmlEscape(valueString);
if (output != null) write(output);
write(output);
}
}

Expand Down Expand Up @@ -188,8 +188,8 @@ class Renderer extends Visitor {
@override
void visitPartial(PartialNode node) {
var partialName = node.name;
Template template =
partialResolver == null ? null : partialResolver(partialName);
var template =
partialResolver == null ? null : (partialResolver!(partialName) as Template?);
if (template != null) {
var renderer = Renderer.partial(this, template, node.indent);
var nodes = getTemplateNodes(template);
Expand All @@ -203,7 +203,7 @@ class Renderer extends Visitor {

// Walks up the stack looking for the variable.
// Handles dotted names of the form "a.b.c".
Object resolveValue(String name) {
Object? resolveValue(String name) {
if (name == '.') {
return _stack.last;
}
Expand All @@ -216,7 +216,7 @@ class Renderer extends Visitor {
}
}
for (var i = 1; i < parts.length; i++) {
if (object == null || object == noSuchProperty) {
if (object == noSuchProperty) {
return noSuchProperty;
}
object = _getNamedProperty(object, parts[i]);
Expand All @@ -232,9 +232,11 @@ class Renderer extends Visitor {
if (object is Map && object.containsKey(name)) return object[name];

if (object is List && _integerTag.hasMatch(name)) {
return object[int.parse(name)];
var index = int.parse(name);
if (object.length > index) {
return object[index];
}
}

return noSuchProperty;
}

Expand Down
Loading

0 comments on commit 7fcc19c

Please sign in to comment.