Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

housekeeping #4

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: test
on:
pull_request:
types: [opened, synchronize]
push:
branches: [ master, main ]
jobs:
test:
name: test
runs-on: ubuntu-latest
container:
image: google/dart:latest
steps:
- name: set up repository
uses: actions/checkout@v2
- name: install deps
run: pub get
- name: analyzer
run: dartanalyzer --fatal-warnings --fatal-infos .
- name: clone spec
run: |
git clone https://github.com/mustache/spec.git test/spec
dart test/all.dart
7 changes: 0 additions & 7 deletions .travis.yml

This file was deleted.

30 changes: 27 additions & 3 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
analyzer:
language:
strict-casts: true
strict-inference: true
strict-raw-types: true
linter:
rules:
unawaited_futures: true
curly_braces_in_flow_control_structures: true
avoid_catches_without_on_clauses: true
- unawaited_futures
- curly_braces_in_flow_control_structures
- avoid_catches_without_on_clauses
- avoid_empty_else
- empty_catches
- avoid_print
- prefer_const_constructors_in_immutables
- prefer_const_constructors
- prefer_const_declarations
- unnecessary_const
- prefer_final_fields
- prefer_final_locals
- prefer_null_aware_operators
- provide_deprecation_message
- unnecessary_new
- unnecessary_null_aware_assignments
- unnecessary_null_in_if_null_operators
- unnecessary_brace_in_string_interps
- unnecessary_overrides
- unnecessary_parenthesis
- unnecessary_statements
- valid_regexps
6 changes: 3 additions & 3 deletions lib/mustache.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ abstract class Template {
/// [values] can be a combination of Map, List, String. Any non-String object
/// will be converted using toString(). Null values will cause a
/// [TemplateException], unless lenient module is enabled.
String renderString(values);
String renderString(dynamic values);

/// [values] can be a combination of Map, List, String. Any non-String object
/// will be converted using toString(). Null values will cause a
/// [TemplateException], unless lenient module is enabled.
void render(values, StringSink sink);
void render(dynamic values, StringSink sink);
}

typedef PartialResolver = Template? Function(String);
Expand All @@ -43,7 +43,7 @@ abstract class LambdaContext {

/// Render and directly output the current section tag. If provided, value
/// will be added to the top of the context's stack.
void render({Object value});
void render({Object? value});

/// Output a string. The output will not be html escaped, and will be written
/// before the output returned from the lambda.
Expand Down
30 changes: 30 additions & 0 deletions lib/src/ability.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@



import 'package:mustache_template/src/lambda_context.dart';

import 'package:mustache_template/mustache.dart' as m;

mixin HasSource {
/// The template source.
String get source;
}

mixin Writable<T>{
T? get self;
void write(Object object);
}

mixin LambdaCtxWritable on m.LambdaContext implements Writable<LambdaContext> {
LambdaContext? get self => this is LambdaContext ? this as LambdaContext : null;
@override
void write(Object object) {
if(self == null){
throw UnimplementedError();
}else {
self as LambdaContext;
self!.checkClosedOrThrow();
self!.renderer.write(object);
}
}
}
63 changes: 35 additions & 28 deletions lib/src/lambda_context.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import 'package:mustache_template/mustache.dart' as m;
import 'package:mustache_template/src/ability.dart';
import 'package:meta/meta.dart';

import 'node.dart';
import 'parser.dart' as parser;
import 'renderer.dart';
import 'template_exception.dart';

/// Passed as an argument to a mustache lambda function.
class LambdaContext implements m.LambdaContext {
class LambdaContext extends m.LambdaContext with HasSource,LambdaCtxWritable {
final Node _node;
final Renderer _renderer;
bool _closed = false;
Expand All @@ -21,6 +23,15 @@ class LambdaContext implements m.LambdaContext {
if (_closed) throw _error('LambdaContext accessed outside of callback.');
}

@internal
bool get isClosed => _closed;

@internal
Renderer get renderer => _renderer;

@internal
Node get node =>_node;

TemplateException _error(String msg) {
return TemplateException(
msg, _renderer.templateName, _renderer.source, _node.start);
Expand All @@ -33,14 +44,14 @@ class LambdaContext implements m.LambdaContext {
_error(
'LambdaContext.renderString() can only be called on section tags.');
}
var sink = StringBuffer();
final sink = StringBuffer();
_renderSubtree(sink, value);
return sink.toString();
}

void _renderSubtree(StringSink sink, Object? value) {
var renderer = Renderer.subtree(_renderer, sink);
var section = _node as SectionNode;
final renderer = Renderer.subtree(_renderer, sink);
final section = _node as SectionNode;
if (value != null) renderer.push(value);
renderer.render(section.children);
}
Expand All @@ -54,45 +65,41 @@ class LambdaContext implements m.LambdaContext {
_renderSubtree(_renderer.sink, value);
}

@override
void write(Object object) {
_checkClosed();
_renderer.write(object);
}
@internal
void checkClosedOrThrow() => _checkClosed();

@override
String get source {
_checkClosed();

if (_node is! SectionNode) return '';

var node = _node as SectionNode;
var nodes = node.children;
if (nodes.isEmpty) return '';

if (nodes.length == 1 && nodes.first is TextNode) {
return (nodes.single as TextNode).text;
}

return _renderer.source.substring(node.contentStart, node.contentEnd);
if(_node is SectionNode) {
final node = _node as SectionNode;
if(node.children.isEmpty){
return '';
} else {
if(node.children.length == 1 && node.children.first is TextNode) {
return (node.children.single as TextNode).text;
} else {
return _renderer.source.substring(node.contentStart, node.contentEnd);
}
}
}else{
return '';
}
}

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

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

var nodes = parser.parse(
final nodes = parser.parse(
source, _renderer.lenient, _renderer.templateName, delimiters);

var renderer =
final renderer =
Renderer.lambda(_renderer, source, _renderer.indent, sink, delimiters);

if (value != null) renderer.push(value);
Expand Down
10 changes: 5 additions & 5 deletions lib/src/node.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
abstract class Node {
Node(this.start, this.end);
const Node(this.start, this.end);

// The offset of the start of the token in the file. Unless this is a section
// or inverse section, then this stores the start of the content of the
Expand All @@ -19,15 +19,15 @@ abstract class Visitor {
}

class TextNode extends Node {
TextNode(this.text, int start, int end) : super(start, end);
const TextNode(this.text, int start, int end) : super(start, end);

final String text;

@override
String toString() => '(TextNode "$_debugText" $start $end)';

String get _debugText {
var t = text.replaceAll('\n', '\\n');
final t = text.replaceAll('\n', '\\n');
return t.length < 50 ? t : t.substring(0, 48) + '...';
}

Expand All @@ -36,7 +36,7 @@ class TextNode extends Node {
}

class VariableNode extends Node {
VariableNode(this.name, int start, int end, {this.escape = true})
const VariableNode(this.name, int start, int end, {this.escape = true})
: super(start, end);

final String name;
Expand Down Expand Up @@ -75,7 +75,7 @@ class SectionNode extends Node {
}

class PartialNode extends Node {
PartialNode(this.name, int start, int end, this.indent) : super(start, end);
const PartialNode(this.name, int start, int end, this.indent) : super(start, end);

final String name;

Expand Down
Loading