Apply pedantic
This commit is contained in:
parent
e7df87d0c2
commit
3d5ac69ab2
26 changed files with 222 additions and 213 deletions
|
@ -33,9 +33,9 @@ void myFunction() {
|
|||
</html>
|
||||
''';
|
||||
|
||||
var buf = new CodeBuffer();
|
||||
var buf = CodeBuffer();
|
||||
var document = jael.parseDocument(template, sourceUrl: 'test.jael', asDSX: false);
|
||||
var scope = new SymbolTable(values: {
|
||||
var scope = SymbolTable(values: {
|
||||
'profile': {
|
||||
'avatar': 'thosakwe.png',
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import 'package:symbol_table/symbol_table.dart';
|
|||
|
||||
main() {
|
||||
while (true) {
|
||||
var buf = new StringBuffer();
|
||||
var buf = StringBuffer();
|
||||
int ch;
|
||||
print('Enter lines of Jael text, terminated by CTRL^D.');
|
||||
print('All environment variables are injected into the template scope.');
|
||||
|
@ -24,11 +24,11 @@ main() {
|
|||
if (document == null) {
|
||||
stderr.writeln('Could not parse the given text.');
|
||||
} else {
|
||||
var output = new CodeBuffer();
|
||||
var output = CodeBuffer();
|
||||
const jael.Renderer().render(
|
||||
document,
|
||||
output,
|
||||
new SymbolTable(values: Platform.environment),
|
||||
SymbolTable(values: Platform.environment),
|
||||
strictResolution: false,
|
||||
);
|
||||
print('GENERATED HTML:\n$output');
|
||||
|
|
|
@ -37,7 +37,7 @@ class BinaryExpression extends Expression {
|
|||
case TokenType.elvis:
|
||||
return l ?? r;
|
||||
default:
|
||||
throw new UnsupportedError(
|
||||
throw UnsupportedError(
|
||||
'Unsupported binary operator: "${operator?.span?.text ?? "<null>"}".');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ class Call extends Expression {
|
|||
|
||||
Map<Symbol, dynamic> computeNamed(SymbolTable scope) {
|
||||
return namedArguments.fold<Map<Symbol, dynamic>>({}, (out, a) {
|
||||
return out..[new Symbol(a.name.name)] = a.value.compute(scope);
|
||||
return out..[Symbol(a.name.name)] = a.value.compute(scope);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -46,8 +46,9 @@ class Doctype extends AstNode {
|
|||
|
||||
@override
|
||||
FileSpan get span {
|
||||
if (public == null)
|
||||
if (public == null) {
|
||||
return lt.span.expand(doctype.span).expand(html.span).expand(gt.span);
|
||||
}
|
||||
return lt.span
|
||||
.expand(doctype.span)
|
||||
.expand(html.span)
|
||||
|
|
|
@ -16,7 +16,7 @@ class TextNode extends ElementChild {
|
|||
}
|
||||
|
||||
abstract class Element extends ElementChild {
|
||||
static const List<String> selfClosing = const [
|
||||
static const List<String> selfClosing = [
|
||||
'include',
|
||||
'base',
|
||||
'basefont',
|
||||
|
|
|
@ -21,8 +21,7 @@ class Identifier extends Expression {
|
|||
var symbol = scope.resolve(name);
|
||||
if (symbol == null) {
|
||||
if (scope.resolve('!strict!')?.value == false) return null;
|
||||
throw new ArgumentError(
|
||||
'The name "$name" does not exist in this scope.');
|
||||
throw ArgumentError('The name "$name" does not exist in this scope.');
|
||||
}
|
||||
return scope.resolve(name).value;
|
||||
}
|
||||
|
@ -43,6 +42,6 @@ class SyntheticIdentifier extends Identifier {
|
|||
@override
|
||||
FileSpan get span {
|
||||
if (id != null) return id.span;
|
||||
throw new UnsupportedError('Cannot get the span of a SyntheticIdentifier.');
|
||||
throw UnsupportedError('Cannot get the span of a SyntheticIdentifier.');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ class MemberExpression extends Expression {
|
|||
compute(SymbolTable scope) {
|
||||
var target = expression.compute(scope);
|
||||
if (op.span.text == '?.' && target == null) return null;
|
||||
return reflect(target).getField(new Symbol(name.name)).reflectee;
|
||||
return reflect(target).getField(Symbol(name.name)).reflectee;
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -21,11 +21,12 @@ class NewExpression extends Expression {
|
|||
var named = call.computeNamed(scope);
|
||||
var name = '';
|
||||
|
||||
if (call.target is MemberExpression)
|
||||
if (call.target is MemberExpression) {
|
||||
name = (call.target as MemberExpression).name.name;
|
||||
}
|
||||
|
||||
return reflectClass(targetType as Type)
|
||||
.newInstance(new Symbol(name), positional, named)
|
||||
.newInstance(Symbol(name), positional, named)
|
||||
.reflectee;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ class StringLiteral extends Literal {
|
|||
static String parseValue(Token string) {
|
||||
var text = string.span.text.substring(1, string.span.text.length - 1);
|
||||
var codeUnits = text.codeUnits;
|
||||
var buf = new StringBuffer();
|
||||
var buf = StringBuffer();
|
||||
|
||||
for (int i = 0; i < codeUnits.length; i++) {
|
||||
var ch = codeUnits[i];
|
||||
|
@ -25,9 +25,9 @@ class StringLiteral extends Literal {
|
|||
c2 = codeUnits[++i],
|
||||
c3 = codeUnits[++i],
|
||||
c4 = codeUnits[++i];
|
||||
var hexString = new String.fromCharCodes([c1, c2, c3, c4]);
|
||||
var hexString = String.fromCharCodes([c1, c2, c3, c4]);
|
||||
var hexNumber = int.parse(hexString, radix: 16);
|
||||
buf.write(new String.fromCharCode(hexNumber));
|
||||
buf.write(String.fromCharCode(hexNumber));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -53,9 +53,10 @@ class StringLiteral extends Literal {
|
|||
default:
|
||||
buf.writeCharCode(next);
|
||||
}
|
||||
} else
|
||||
throw new JaelError(JaelErrorSeverity.error,
|
||||
} else {
|
||||
throw JaelError(JaelErrorSeverity.error,
|
||||
'Unexpected "\\" in string literal.', string.span);
|
||||
}
|
||||
} else {
|
||||
buf.writeCharCode(ch);
|
||||
}
|
||||
|
|
|
@ -5,12 +5,12 @@ class JaelFormatter {
|
|||
final num tabSize;
|
||||
final bool insertSpaces;
|
||||
final int maxLineLength;
|
||||
var _buffer = new StringBuffer();
|
||||
var _buffer = StringBuffer();
|
||||
int _level = 0;
|
||||
String _spaces;
|
||||
|
||||
static String _spaceString(int tabSize) {
|
||||
var b = new StringBuffer();
|
||||
var b = StringBuffer();
|
||||
for (int i = 0; i < tabSize; i++) {
|
||||
b.write(' ');
|
||||
}
|
||||
|
@ -30,7 +30,9 @@ class JaelFormatter {
|
|||
}
|
||||
|
||||
void _applySpacing() {
|
||||
for (int i = 0; i < _level; i++) _buffer.write(_spaces);
|
||||
for (int i = 0; i < _level; i++) {
|
||||
_buffer.write(_spaces);
|
||||
}
|
||||
}
|
||||
|
||||
int get _spaceLength {
|
||||
|
@ -62,9 +64,9 @@ class JaelFormatter {
|
|||
|
||||
int _formatChild(ElementChild child, int lineLength,
|
||||
{bool isFirst = false, bool isLast = false}) {
|
||||
if (child == null)
|
||||
if (child == null) {
|
||||
return lineLength;
|
||||
else if (child is Element) return _formatElement(child, lineLength);
|
||||
} else if (child is Element) return _formatElement(child, lineLength);
|
||||
String s;
|
||||
if (child is Interpolation) {
|
||||
var b = StringBuffer('{{');
|
||||
|
|
|
@ -7,21 +7,21 @@ import 'text/scanner.dart';
|
|||
|
||||
/// Parses a Jael document.
|
||||
Document parseDocument(String text,
|
||||
{sourceUrl, bool asDSX: false, void onError(JaelError error)}) {
|
||||
{sourceUrl, bool asDSX = false, void onError(JaelError error)}) {
|
||||
var scanner = scan(text, sourceUrl: sourceUrl, asDSX: asDSX);
|
||||
|
||||
//scanner.tokens.forEach(print);
|
||||
|
||||
if (scanner.errors.isNotEmpty && onError != null)
|
||||
if (scanner.errors.isNotEmpty && onError != null) {
|
||||
scanner.errors.forEach(onError);
|
||||
else if (scanner.errors.isNotEmpty) throw scanner.errors.first;
|
||||
} else if (scanner.errors.isNotEmpty) throw scanner.errors.first;
|
||||
|
||||
var parser = new Parser(scanner, asDSX: asDSX);
|
||||
var parser = Parser(scanner, asDSX: asDSX);
|
||||
var doc = parser.parseDocument();
|
||||
|
||||
if (parser.errors.isNotEmpty && onError != null)
|
||||
if (parser.errors.isNotEmpty && onError != null) {
|
||||
parser.errors.forEach(onError);
|
||||
else if (parser.errors.isNotEmpty) throw parser.errors.first;
|
||||
} else if (parser.errors.isNotEmpty) throw parser.errors.first;
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ class Renderer {
|
|||
/// If [strictResolution] is `false` (default: `true`), then undefined identifiers will return `null`
|
||||
/// instead of throwing.
|
||||
void render(Document document, CodeBuffer buffer, SymbolTable scope,
|
||||
{bool strictResolution: true}) {
|
||||
{bool strictResolution = true}) {
|
||||
scope.create('!strict!', value: strictResolution != false);
|
||||
|
||||
if (document.doctype != null) buffer.writeln(document.doctype.span.text);
|
||||
|
@ -126,17 +126,18 @@ class Renderer {
|
|||
|
||||
buffer.write(' ${attribute.name}');
|
||||
|
||||
if (value == true)
|
||||
if (value == true) {
|
||||
continue;
|
||||
else
|
||||
} else {
|
||||
buffer.write('="');
|
||||
}
|
||||
|
||||
String msg;
|
||||
|
||||
if (value is Iterable) {
|
||||
msg = value.join(' ');
|
||||
} else if (value is Map) {
|
||||
msg = value.keys.fold<StringBuffer>(new StringBuffer(), (buf, k) {
|
||||
msg = value.keys.fold<StringBuffer>(StringBuffer(), (buf, k) {
|
||||
var v = value[k];
|
||||
if (v == null) return buf;
|
||||
return buf..write('$k: $v;');
|
||||
|
@ -150,10 +151,11 @@ class Renderer {
|
|||
}
|
||||
|
||||
if (element is SelfClosingElement) {
|
||||
if (html5)
|
||||
if (html5) {
|
||||
buffer.writeln('>');
|
||||
else
|
||||
} else {
|
||||
buffer.writeln('/>');
|
||||
}
|
||||
} else {
|
||||
buffer.writeln('>');
|
||||
buffer.indent();
|
||||
|
@ -185,11 +187,11 @@ class Renderer {
|
|||
(a) => a.name != 'for-each' && a.name != 'as' && a.name != 'index-as');
|
||||
Element strippedElement;
|
||||
|
||||
if (element is SelfClosingElement)
|
||||
strippedElement = new SelfClosingElement(element.lt, element.tagName,
|
||||
if (element is SelfClosingElement) {
|
||||
strippedElement = SelfClosingElement(element.lt, element.tagName,
|
||||
otherAttributes, element.slash, element.gt);
|
||||
else if (element is RegularElement)
|
||||
strippedElement = new RegularElement(
|
||||
} else if (element is RegularElement) {
|
||||
strippedElement = RegularElement(
|
||||
element.lt,
|
||||
element.tagName,
|
||||
otherAttributes,
|
||||
|
@ -199,6 +201,7 @@ class Renderer {
|
|||
element.slash,
|
||||
element.tagName2,
|
||||
element.gt2);
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (var item in attribute.value.compute(scope)) {
|
||||
|
@ -224,11 +227,11 @@ class Renderer {
|
|||
var otherAttributes = element.attributes.where((a) => a.name != 'if');
|
||||
Element strippedElement;
|
||||
|
||||
if (element is SelfClosingElement)
|
||||
strippedElement = new SelfClosingElement(element.lt, element.tagName,
|
||||
if (element is SelfClosingElement) {
|
||||
strippedElement = SelfClosingElement(element.lt, element.tagName,
|
||||
otherAttributes, element.slash, element.gt);
|
||||
else if (element is RegularElement)
|
||||
strippedElement = new RegularElement(
|
||||
} else if (element is RegularElement) {
|
||||
strippedElement = RegularElement(
|
||||
element.lt,
|
||||
element.tagName,
|
||||
otherAttributes,
|
||||
|
@ -238,6 +241,7 @@ class Renderer {
|
|||
element.slash,
|
||||
element.tagName2,
|
||||
element.gt2);
|
||||
}
|
||||
|
||||
renderElement(strippedElement, buffer, scope, html5);
|
||||
}
|
||||
|
@ -298,21 +302,23 @@ class Renderer {
|
|||
void renderElementChild(Element parent, ElementChild child, CodeBuffer buffer,
|
||||
SymbolTable scope, bool html5, int index, int total) {
|
||||
if (child is Text && parent?.tagName?.name != 'textarea') {
|
||||
if (index == 0)
|
||||
if (index == 0) {
|
||||
buffer.write(child.span.text.trimLeft());
|
||||
else if (index == total - 1)
|
||||
} else if (index == total - 1) {
|
||||
buffer.write(child.span.text.trimRight());
|
||||
else
|
||||
} else {
|
||||
buffer.write(child.span.text);
|
||||
}
|
||||
} else if (child is Interpolation) {
|
||||
var value = child.expression.compute(scope);
|
||||
|
||||
if (value != null) {
|
||||
if (child.isRaw)
|
||||
if (child.isRaw) {
|
||||
buffer.write(value);
|
||||
else
|
||||
} else {
|
||||
buffer.write(htmlEscape.convert(value.toString()));
|
||||
}
|
||||
}
|
||||
} else if (child is Element) {
|
||||
if (buffer?.lastLine?.text?.isNotEmpty == true) buffer.writeln();
|
||||
renderElement(child, buffer, scope, html5);
|
||||
|
@ -324,14 +330,14 @@ class Renderer {
|
|||
void registerCustomElement(
|
||||
Element element, CodeBuffer buffer, SymbolTable scope, bool html5) {
|
||||
if (element is! RegularElement) {
|
||||
throw new JaelError(JaelErrorSeverity.error,
|
||||
throw JaelError(JaelErrorSeverity.error,
|
||||
"Custom elements cannot be self-closing.", element.span);
|
||||
}
|
||||
|
||||
var name = element.getAttribute('name')?.value?.compute(scope)?.toString();
|
||||
|
||||
if (name == null) {
|
||||
throw new JaelError(
|
||||
throw JaelError(
|
||||
JaelErrorSeverity.error,
|
||||
"Attribute 'name' is required when registering a custom element.",
|
||||
element.tagName.span);
|
||||
|
@ -341,7 +347,7 @@ class Renderer {
|
|||
var p = scope.isRoot ? scope : scope.parent;
|
||||
p.create(customElementName(name), value: element, constant: true);
|
||||
} on StateError {
|
||||
throw new JaelError(
|
||||
throw JaelError(
|
||||
JaelErrorSeverity.error,
|
||||
"Cannot re-define element '$name' in this scope.",
|
||||
element.getAttribute('name').span);
|
||||
|
@ -371,16 +377,16 @@ class Renderer {
|
|||
} else {
|
||||
var tagName = renderAs?.toString() ?? 'div';
|
||||
|
||||
var syntheticElement = new RegularElement(
|
||||
var syntheticElement = RegularElement(
|
||||
template.lt,
|
||||
new SyntheticIdentifier(tagName),
|
||||
SyntheticIdentifier(tagName),
|
||||
element.attributes
|
||||
.where((a) => a.name != 'as' && !a.name.startsWith('@')),
|
||||
template.gt,
|
||||
template.children,
|
||||
template.lt2,
|
||||
template.slash,
|
||||
new SyntheticIdentifier(tagName),
|
||||
SyntheticIdentifier(tagName),
|
||||
template.gt2);
|
||||
|
||||
renderElement(syntheticElement, buffer, scope, html5);
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
part of jael.src.text.parselet;
|
||||
|
||||
const Map<TokenType, InfixParselet> infixParselets = const {
|
||||
TokenType.lParen: const CallParselet(),
|
||||
TokenType.elvis_dot: const MemberParselet(),
|
||||
TokenType.dot: const MemberParselet(),
|
||||
TokenType.lBracket: const IndexerParselet(),
|
||||
TokenType.asterisk: const BinaryParselet(14),
|
||||
TokenType.slash: const BinaryParselet(14),
|
||||
TokenType.percent: const BinaryParselet(14),
|
||||
TokenType.plus: const BinaryParselet(13),
|
||||
TokenType.minus: const BinaryParselet(13),
|
||||
TokenType.lt: const BinaryParselet(11),
|
||||
TokenType.lte: const BinaryParselet(11),
|
||||
TokenType.gt: const BinaryParselet(11),
|
||||
TokenType.gte: const BinaryParselet(11),
|
||||
TokenType.equ: const BinaryParselet(10),
|
||||
TokenType.nequ: const BinaryParselet(10),
|
||||
TokenType.question: const ConditionalParselet(),
|
||||
TokenType.equals: const BinaryParselet(3),
|
||||
TokenType.elvis: const BinaryParselet(3),
|
||||
const Map<TokenType, InfixParselet> infixParselets = {
|
||||
TokenType.lParen: CallParselet(),
|
||||
TokenType.elvis_dot: MemberParselet(),
|
||||
TokenType.dot: MemberParselet(),
|
||||
TokenType.lBracket: IndexerParselet(),
|
||||
TokenType.asterisk: BinaryParselet(14),
|
||||
TokenType.slash: BinaryParselet(14),
|
||||
TokenType.percent: BinaryParselet(14),
|
||||
TokenType.plus: BinaryParselet(13),
|
||||
TokenType.minus: BinaryParselet(13),
|
||||
TokenType.lt: BinaryParselet(11),
|
||||
TokenType.lte: BinaryParselet(11),
|
||||
TokenType.gt: BinaryParselet(11),
|
||||
TokenType.gte: BinaryParselet(11),
|
||||
TokenType.equ: BinaryParselet(10),
|
||||
TokenType.nequ: BinaryParselet(10),
|
||||
TokenType.question: ConditionalParselet(),
|
||||
TokenType.equals: BinaryParselet(3),
|
||||
TokenType.elvis: BinaryParselet(3),
|
||||
};
|
||||
|
||||
class ConditionalParselet implements InfixParselet {
|
||||
|
@ -32,13 +32,13 @@ class ConditionalParselet implements InfixParselet {
|
|||
var ifTrue = parser.parseExpression(0);
|
||||
|
||||
if (ifTrue == null) {
|
||||
parser.errors.add(new JaelError(JaelErrorSeverity.error,
|
||||
parser.errors.add(JaelError(JaelErrorSeverity.error,
|
||||
'Missing expression in conditional expression.', token.span));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!parser.next(TokenType.colon)) {
|
||||
parser.errors.add(new JaelError(JaelErrorSeverity.error,
|
||||
parser.errors.add(JaelError(JaelErrorSeverity.error,
|
||||
'Missing ":" in conditional expression.', ifTrue.span));
|
||||
return null;
|
||||
}
|
||||
|
@ -47,12 +47,12 @@ class ConditionalParselet implements InfixParselet {
|
|||
var ifFalse = parser.parseExpression(0);
|
||||
|
||||
if (ifFalse == null) {
|
||||
parser.errors.add(new JaelError(JaelErrorSeverity.error,
|
||||
parser.errors.add(JaelError(JaelErrorSeverity.error,
|
||||
'Missing expression in conditional expression.', colon.span));
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Conditional(left, token, ifTrue, colon, ifFalse);
|
||||
return Conditional(left, token, ifTrue, colon, ifFalse);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,15 +66,16 @@ class BinaryParselet implements InfixParselet {
|
|||
var right = parser.parseExpression(precedence);
|
||||
|
||||
if (right == null) {
|
||||
if (token.type != TokenType.gt)
|
||||
parser.errors.add(new JaelError(
|
||||
if (token.type != TokenType.gt) {
|
||||
parser.errors.add(JaelError(
|
||||
JaelErrorSeverity.error,
|
||||
'Missing expression after operator "${token.span.text}", following expression ${left.span.text}.',
|
||||
token.span));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return new BinaryExpression(left, token, right);
|
||||
return BinaryExpression(left, token, right);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,12 +110,12 @@ class CallParselet implements InfixParselet {
|
|||
if (!parser.next(TokenType.rParen)) {
|
||||
var lastSpan = arguments.isEmpty ? null : arguments.last.span;
|
||||
lastSpan ??= token.span;
|
||||
parser.errors.add(new JaelError(JaelErrorSeverity.error,
|
||||
parser.errors.add(JaelError(JaelErrorSeverity.error,
|
||||
'Missing ")" after argument list.', lastSpan));
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Call(left, token, parser.current, arguments, namedArguments);
|
||||
return Call(left, token, parser.current, arguments, namedArguments);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,18 +130,18 @@ class IndexerParselet implements InfixParselet {
|
|||
var indexer = parser.parseExpression(0);
|
||||
|
||||
if (indexer == null) {
|
||||
parser.errors.add(new JaelError(
|
||||
parser.errors.add(JaelError(
|
||||
JaelErrorSeverity.error, 'Missing expression after "[".', left.span));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!parser.next(TokenType.rBracket)) {
|
||||
parser.errors.add(
|
||||
new JaelError(JaelErrorSeverity.error, 'Missing "]".', indexer.span));
|
||||
JaelError(JaelErrorSeverity.error, 'Missing "]".', indexer.span));
|
||||
return null;
|
||||
}
|
||||
|
||||
return new IndexerExpression(left, token, indexer, parser.current);
|
||||
return IndexerExpression(left, token, indexer, parser.current);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,11 +156,11 @@ class MemberParselet implements InfixParselet {
|
|||
var name = parser.parseIdentifier();
|
||||
|
||||
if (name == null) {
|
||||
parser.errors.add(new JaelError(JaelErrorSeverity.error,
|
||||
parser.errors.add(JaelError(JaelErrorSeverity.error,
|
||||
'Expected the name of a property following "."', token.span));
|
||||
return null;
|
||||
}
|
||||
|
||||
return new MemberExpression(left, token, name);
|
||||
return MemberExpression(left, token, name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
part of jael.src.text.parselet;
|
||||
|
||||
const Map<TokenType, PrefixParselet> prefixParselets = const {
|
||||
TokenType.exclamation: const NotParselet(),
|
||||
TokenType.$new: const NewParselet(),
|
||||
TokenType.number: const NumberParselet(),
|
||||
TokenType.hex: const HexParselet(),
|
||||
TokenType.string: const StringParselet(),
|
||||
TokenType.lCurly: const MapParselet(),
|
||||
TokenType.lBracket: const ArrayParselet(),
|
||||
TokenType.id: const IdentifierParselet(),
|
||||
TokenType.lParen: const ParenthesisParselet(),
|
||||
const Map<TokenType, PrefixParselet> prefixParselets = {
|
||||
TokenType.exclamation: NotParselet(),
|
||||
TokenType.$new: NewParselet(),
|
||||
TokenType.number: NumberParselet(),
|
||||
TokenType.hex: HexParselet(),
|
||||
TokenType.string: StringParselet(),
|
||||
TokenType.lCurly: MapParselet(),
|
||||
TokenType.lBracket: ArrayParselet(),
|
||||
TokenType.id: IdentifierParselet(),
|
||||
TokenType.lParen: ParenthesisParselet(),
|
||||
};
|
||||
|
||||
class NotParselet implements PrefixParselet {
|
||||
|
@ -20,11 +20,11 @@ class NotParselet implements PrefixParselet {
|
|||
var expression = parser.parseExpression(0);
|
||||
|
||||
if (expression == null) {
|
||||
parser.errors.add(new JaelError(JaelErrorSeverity.error,
|
||||
parser.errors.add(JaelError(JaelErrorSeverity.error,
|
||||
'Missing expression after "!" in negation expression.', token.span));
|
||||
}
|
||||
|
||||
return new Negation(token, expression);
|
||||
return Negation(token, expression);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,15 +36,15 @@ class NewParselet implements PrefixParselet {
|
|||
var call = parser.parseExpression(0);
|
||||
|
||||
if (call == null) {
|
||||
parser.errors.add(new JaelError(
|
||||
parser.errors.add(JaelError(
|
||||
JaelErrorSeverity.error,
|
||||
'"new" must precede a call expression. Nothing was found.',
|
||||
call.span));
|
||||
return null;
|
||||
} else if (call is Call) {
|
||||
return new NewExpression(token, call);
|
||||
return NewExpression(token, call);
|
||||
} else {
|
||||
parser.errors.add(new JaelError(
|
||||
parser.errors.add(JaelError(
|
||||
JaelErrorSeverity.error,
|
||||
'"new" must precede a call expression, not a(n) ${call.runtimeType}.',
|
||||
call.span));
|
||||
|
@ -57,14 +57,14 @@ class NumberParselet implements PrefixParselet {
|
|||
const NumberParselet();
|
||||
|
||||
@override
|
||||
Expression parse(Parser parser, Token token) => new NumberLiteral(token);
|
||||
Expression parse(Parser parser, Token token) => NumberLiteral(token);
|
||||
}
|
||||
|
||||
class HexParselet implements PrefixParselet {
|
||||
const HexParselet();
|
||||
|
||||
@override
|
||||
Expression parse(Parser parser, Token token) => new HexLiteral(token);
|
||||
Expression parse(Parser parser, Token token) => HexLiteral(token);
|
||||
}
|
||||
|
||||
class StringParselet implements PrefixParselet {
|
||||
|
@ -72,7 +72,7 @@ class StringParselet implements PrefixParselet {
|
|||
|
||||
@override
|
||||
Expression parse(Parser parser, Token token) =>
|
||||
new StringLiteral(token, StringLiteral.parseValue(token));
|
||||
StringLiteral(token, StringLiteral.parseValue(token));
|
||||
}
|
||||
|
||||
class ArrayParselet implements PrefixParselet {
|
||||
|
@ -93,12 +93,12 @@ class ArrayParselet implements PrefixParselet {
|
|||
if (!parser.next(TokenType.rBracket)) {
|
||||
var lastSpan = items.isEmpty ? null : items.last.span;
|
||||
lastSpan ??= token.span;
|
||||
parser.errors.add(new JaelError(JaelErrorSeverity.error,
|
||||
parser.errors.add(JaelError(JaelErrorSeverity.error,
|
||||
'Missing "]" to terminate array literal.', lastSpan));
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Array(token, parser.current, items);
|
||||
return Array(token, parser.current, items);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,12 +119,12 @@ class MapParselet implements PrefixParselet {
|
|||
|
||||
if (!parser.next(TokenType.rCurly)) {
|
||||
var lastSpan = pairs.isEmpty ? token.span : pairs.last.span;
|
||||
parser.errors.add(new JaelError(
|
||||
parser.errors.add(JaelError(
|
||||
JaelErrorSeverity.error, 'Missing "}" in map literal.', lastSpan));
|
||||
return null;
|
||||
}
|
||||
|
||||
return new MapLiteral(token, pairs, parser.current);
|
||||
return MapLiteral(token, pairs, parser.current);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ class IdentifierParselet implements PrefixParselet {
|
|||
const IdentifierParselet();
|
||||
|
||||
@override
|
||||
Expression parse(Parser parser, Token token) => new Identifier(token);
|
||||
Expression parse(Parser parser, Token token) => Identifier(token);
|
||||
}
|
||||
|
||||
class ParenthesisParselet implements PrefixParselet {
|
||||
|
@ -143,14 +143,14 @@ class ParenthesisParselet implements PrefixParselet {
|
|||
var expression = parser.parseExpression(0);
|
||||
|
||||
if (expression == null) {
|
||||
parser.errors.add(new JaelError(JaelErrorSeverity.error,
|
||||
parser.errors.add(JaelError(JaelErrorSeverity.error,
|
||||
'Missing expression after "(".', token.span));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!parser.next(TokenType.rParen)) {
|
||||
parser.errors.add(new JaelError(
|
||||
JaelErrorSeverity.error, 'Missing ")".', expression.span));
|
||||
parser.errors.add(
|
||||
JaelError(JaelErrorSeverity.error, 'Missing ")".', expression.span));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ class Parser {
|
|||
Token _current;
|
||||
int _index = -1;
|
||||
|
||||
Parser(this.scanner, {this.asDSX: false});
|
||||
Parser(this.scanner, {this.asDSX = false});
|
||||
|
||||
Token get current => _current;
|
||||
|
||||
|
@ -52,18 +52,18 @@ class Parser {
|
|||
if (doctype == null) {
|
||||
var root = parseElement();
|
||||
if (root == null) return null;
|
||||
return new Document(null, root);
|
||||
return Document(null, root);
|
||||
}
|
||||
|
||||
var root = parseElement();
|
||||
|
||||
if (root == null) {
|
||||
errors.add(new JaelError(JaelErrorSeverity.error,
|
||||
errors.add(JaelError(JaelErrorSeverity.error,
|
||||
'Missing root element after !DOCTYPE declaration.', doctype.span));
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Document(doctype, root);
|
||||
return Document(doctype, root);
|
||||
}
|
||||
|
||||
StringLiteral implicitString() {
|
||||
|
@ -88,7 +88,7 @@ class Parser {
|
|||
}
|
||||
var doctype = _current, html = parseIdentifier();
|
||||
if (html?.span?.text?.toLowerCase() != 'html') {
|
||||
errors.add(new JaelError(
|
||||
errors.add(JaelError(
|
||||
JaelErrorSeverity.error,
|
||||
'Expected "html" in doctype declaration.',
|
||||
html?.span ?? doctype.span));
|
||||
|
@ -98,16 +98,16 @@ class Parser {
|
|||
var public = parseIdentifier();
|
||||
if (public == null) {
|
||||
if (!next(TokenType.gt)) {
|
||||
errors.add(new JaelError(JaelErrorSeverity.error,
|
||||
errors.add(JaelError(JaelErrorSeverity.error,
|
||||
'Expected ">" in doctype declaration.', html.span));
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Doctype(lt, doctype, html, null, null, null, _current);
|
||||
return Doctype(lt, doctype, html, null, null, null, _current);
|
||||
}
|
||||
|
||||
if (public?.span?.text?.toLowerCase() != 'public') {
|
||||
errors.add(new JaelError(
|
||||
errors.add(JaelError(
|
||||
JaelErrorSeverity.error,
|
||||
'Expected "public" in doctype declaration.',
|
||||
public?.span ?? html.span));
|
||||
|
@ -117,7 +117,7 @@ class Parser {
|
|||
var stringParser = prefixParselets[TokenType.string];
|
||||
|
||||
if (!next(TokenType.string)) {
|
||||
errors.add(new JaelError(JaelErrorSeverity.error,
|
||||
errors.add(JaelError(JaelErrorSeverity.error,
|
||||
'Expected string in doctype declaration.', public.span));
|
||||
return null;
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ class Parser {
|
|||
var name = stringParser.parse(this, _current) as StringLiteral;
|
||||
|
||||
if (!next(TokenType.string)) {
|
||||
errors.add(new JaelError(JaelErrorSeverity.error,
|
||||
errors.add(JaelError(JaelErrorSeverity.error,
|
||||
'Expected string in doctype declaration.', name.span));
|
||||
return null;
|
||||
}
|
||||
|
@ -133,12 +133,12 @@ class Parser {
|
|||
var url = stringParser.parse(this, _current) as StringLiteral;
|
||||
|
||||
if (!next(TokenType.gt)) {
|
||||
errors.add(new JaelError(JaelErrorSeverity.error,
|
||||
errors.add(JaelError(JaelErrorSeverity.error,
|
||||
'Expected ">" in doctype declaration.', url.span));
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Doctype(lt, doctype, html, public, name, url, _current);
|
||||
return Doctype(lt, doctype, html, public, name, url, _current);
|
||||
}
|
||||
|
||||
ElementChild parseElementChild() =>
|
||||
|
@ -148,9 +148,9 @@ class Parser {
|
|||
parseElement();
|
||||
|
||||
HtmlComment parseHtmlComment() =>
|
||||
next(TokenType.htmlComment) ? new HtmlComment(_current) : null;
|
||||
next(TokenType.htmlComment) ? HtmlComment(_current) : null;
|
||||
|
||||
Text parseText() => next(TokenType.text) ? new Text(_current) : null;
|
||||
Text parseText() => next(TokenType.text) ? Text(_current) : null;
|
||||
|
||||
Interpolation parseInterpolation() {
|
||||
if (!next(asDSX ? TokenType.lCurly : TokenType.lDoubleCurly)) return null;
|
||||
|
@ -159,19 +159,19 @@ class Parser {
|
|||
var expression = parseExpression(0);
|
||||
|
||||
if (expression == null) {
|
||||
errors.add(new JaelError(JaelErrorSeverity.error,
|
||||
errors.add(JaelError(JaelErrorSeverity.error,
|
||||
'Missing expression in interpolation.', doubleCurlyL.span));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!next(asDSX ? TokenType.rCurly : TokenType.rDoubleCurly)) {
|
||||
var expected = asDSX ? '}' : '}}';
|
||||
errors.add(new JaelError(JaelErrorSeverity.error,
|
||||
errors.add(JaelError(JaelErrorSeverity.error,
|
||||
'Missing closing "$expected" in interpolation.', expression.span));
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Interpolation(doubleCurlyL, expression, _current);
|
||||
return Interpolation(doubleCurlyL, expression, _current);
|
||||
}
|
||||
|
||||
Element parseElement() {
|
||||
|
@ -188,7 +188,7 @@ class Parser {
|
|||
|
||||
if (tagName == null) {
|
||||
errors.add(
|
||||
new JaelError(JaelErrorSeverity.error, 'Missing tag name.', lt.span));
|
||||
JaelError(JaelErrorSeverity.error, 'Missing tag name.', lt.span));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -205,16 +205,16 @@ class Parser {
|
|||
var slash = _current;
|
||||
|
||||
if (!next(TokenType.gt)) {
|
||||
errors.add(new JaelError(JaelErrorSeverity.error,
|
||||
errors.add(JaelError(JaelErrorSeverity.error,
|
||||
'Missing ">" in self-closing "${tagName.name}" tag.', slash.span));
|
||||
return null;
|
||||
}
|
||||
|
||||
return new SelfClosingElement(lt, tagName, attributes, slash, _current);
|
||||
return SelfClosingElement(lt, tagName, attributes, slash, _current);
|
||||
}
|
||||
|
||||
if (!next(TokenType.gt)) {
|
||||
errors.add(new JaelError(
|
||||
errors.add(JaelError(
|
||||
JaelErrorSeverity.error,
|
||||
'Missing ">" in "${tagName.name}" tag.',
|
||||
attributes.isEmpty ? tagName.span : attributes.last.span));
|
||||
|
@ -225,7 +225,7 @@ class Parser {
|
|||
|
||||
// Implicit self-closing
|
||||
if (Element.selfClosing.contains(tagName.name)) {
|
||||
return new SelfClosingElement(lt, tagName, attributes, null, gt);
|
||||
return SelfClosingElement(lt, tagName, attributes, null, gt);
|
||||
}
|
||||
|
||||
List<ElementChild> children = [];
|
||||
|
@ -239,7 +239,7 @@ class Parser {
|
|||
|
||||
// Parse closing tag
|
||||
if (!next(TokenType.lt)) {
|
||||
errors.add(new JaelError(
|
||||
errors.add(JaelError(
|
||||
JaelErrorSeverity.error,
|
||||
'Missing closing tag for "${tagName.name}" tag.',
|
||||
children.isEmpty ? tagName.span : children.last.span));
|
||||
|
@ -249,7 +249,7 @@ class Parser {
|
|||
var lt2 = _current;
|
||||
|
||||
if (!next(TokenType.slash)) {
|
||||
errors.add(new JaelError(JaelErrorSeverity.error,
|
||||
errors.add(JaelError(JaelErrorSeverity.error,
|
||||
'Missing "/" in "${tagName.name}" closing tag.', lt2.span));
|
||||
return null;
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ class Parser {
|
|||
var slash = _current, tagName2 = parseIdentifier();
|
||||
|
||||
if (tagName2 == null) {
|
||||
errors.add(new JaelError(
|
||||
errors.add(JaelError(
|
||||
JaelErrorSeverity.error,
|
||||
'Missing "${tagName.name}" in "${tagName.name}" closing tag.',
|
||||
slash.span));
|
||||
|
@ -265,7 +265,7 @@ class Parser {
|
|||
}
|
||||
|
||||
if (tagName2.name != tagName.name) {
|
||||
errors.add(new JaelError(
|
||||
errors.add(JaelError(
|
||||
JaelErrorSeverity.error,
|
||||
'Mismatched closing tags. Expected "${tagName.span.text}"; got "${tagName2.name}" instead.',
|
||||
lt2.span));
|
||||
|
@ -273,12 +273,12 @@ class Parser {
|
|||
}
|
||||
|
||||
if (!next(TokenType.gt)) {
|
||||
errors.add(new JaelError(JaelErrorSeverity.error,
|
||||
errors.add(JaelError(JaelErrorSeverity.error,
|
||||
'Missing ">" in "${tagName.name}" closing tag.', tagName2.span));
|
||||
return null;
|
||||
}
|
||||
|
||||
return new RegularElement(
|
||||
return RegularElement(
|
||||
lt, tagName, attributes, gt, children, lt2, slash, tagName2, _current);
|
||||
}
|
||||
|
||||
|
@ -289,7 +289,7 @@ class Parser {
|
|||
if ((id = parseIdentifier()) != null) {
|
||||
// Nothing
|
||||
} else if (next(TokenType.string)) {
|
||||
string = new StringLiteral(_current, StringLiteral.parseValue(_current));
|
||||
string = StringLiteral(_current, StringLiteral.parseValue(_current));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
@ -301,35 +301,34 @@ class Parser {
|
|||
} else if (!asDSX && next(TokenType.nequ)) {
|
||||
nequ = _current;
|
||||
} else {
|
||||
return new Attribute(id, string, null, null, null);
|
||||
return Attribute(id, string, null, null, null);
|
||||
}
|
||||
|
||||
if (!asDSX) {
|
||||
var value = parseExpression(0);
|
||||
|
||||
if (value == null) {
|
||||
errors.add(new JaelError(JaelErrorSeverity.error,
|
||||
errors.add(JaelError(JaelErrorSeverity.error,
|
||||
'Missing expression in attribute.', equals?.span ?? nequ.span));
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Attribute(id, string, equals, nequ, value);
|
||||
return Attribute(id, string, equals, nequ, value);
|
||||
} else {
|
||||
// Find either a string, or an interpolation.
|
||||
var value = implicitString();
|
||||
|
||||
if (value != null) {
|
||||
return new Attribute(id, string, equals, nequ, value);
|
||||
return Attribute(id, string, equals, nequ, value);
|
||||
}
|
||||
|
||||
var interpolation = parseInterpolation();
|
||||
|
||||
if (interpolation != null) {
|
||||
return new Attribute(
|
||||
id, string, equals, nequ, interpolation.expression);
|
||||
return Attribute(id, string, equals, nequ, interpolation.expression);
|
||||
}
|
||||
|
||||
errors.add(new JaelError(JaelErrorSeverity.error,
|
||||
errors.add(JaelError(JaelErrorSeverity.error,
|
||||
'Missing expression in attribute.', equals?.span ?? nequ.span));
|
||||
return null;
|
||||
}
|
||||
|
@ -374,23 +373,23 @@ class Parser {
|
|||
}
|
||||
|
||||
Identifier parseIdentifier() =>
|
||||
next(TokenType.id) ? new Identifier(_current) : null;
|
||||
next(TokenType.id) ? Identifier(_current) : null;
|
||||
|
||||
KeyValuePair parseKeyValuePair() {
|
||||
var key = parseExpression(0);
|
||||
if (key == null) return null;
|
||||
|
||||
if (!next(TokenType.colon)) return new KeyValuePair(key, null, null);
|
||||
if (!next(TokenType.colon)) return KeyValuePair(key, null, null);
|
||||
|
||||
var colon = _current, value = parseExpression(0);
|
||||
|
||||
if (value == null) {
|
||||
errors.add(new JaelError(JaelErrorSeverity.error,
|
||||
errors.add(JaelError(JaelErrorSeverity.error,
|
||||
'Missing expression in key-value pair.', colon.span));
|
||||
return null;
|
||||
}
|
||||
|
||||
return new KeyValuePair(key, colon, value);
|
||||
return KeyValuePair(key, colon, value);
|
||||
}
|
||||
|
||||
NamedArgument parseNamedArgument() {
|
||||
|
@ -398,7 +397,7 @@ class Parser {
|
|||
if (name == null) return null;
|
||||
|
||||
if (!next(TokenType.colon)) {
|
||||
errors.add(new JaelError(JaelErrorSeverity.error,
|
||||
errors.add(JaelError(JaelErrorSeverity.error,
|
||||
'Missing ":" in named argument.', name.span));
|
||||
return null;
|
||||
}
|
||||
|
@ -406,11 +405,11 @@ class Parser {
|
|||
var colon = _current, value = parseExpression(0);
|
||||
|
||||
if (value == null) {
|
||||
errors.add(new JaelError(JaelErrorSeverity.error,
|
||||
errors.add(JaelError(JaelErrorSeverity.error,
|
||||
'Missing expression in named argument.', colon.span));
|
||||
return null;
|
||||
}
|
||||
|
||||
return new NamedArgument(name, colon, value);
|
||||
return NamedArgument(name, colon, value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,17 +3,17 @@ import 'package:charcode/ascii.dart';
|
|||
import 'package:string_scanner/string_scanner.dart';
|
||||
import '../ast/ast.dart';
|
||||
|
||||
final RegExp _whitespace = new RegExp(r'[ \n\r\t]+');
|
||||
final RegExp _whitespace = RegExp(r'[ \n\r\t]+');
|
||||
|
||||
final RegExp _id =
|
||||
new RegExp(r'@?(([A-Za-z][A-Za-z0-9_]*-)*([A-Za-z][A-Za-z0-9_]*))');
|
||||
final RegExp _string1 = new RegExp(
|
||||
RegExp(r'@?(([A-Za-z][A-Za-z0-9_]*-)*([A-Za-z][A-Za-z0-9_]*))');
|
||||
final RegExp _string1 = RegExp(
|
||||
r"'((\\(['\\/bfnrt]|(u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])))|([^'\\]))*'");
|
||||
final RegExp _string2 = new RegExp(
|
||||
final RegExp _string2 = RegExp(
|
||||
r'"((\\(["\\/bfnrt]|(u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])))|([^"\\]))*"');
|
||||
|
||||
Scanner scan(String text, {sourceUrl, bool asDSX: false}) =>
|
||||
new _Scanner(text, sourceUrl)..scan(asDSX: asDSX);
|
||||
Scanner scan(String text, {sourceUrl, bool asDSX = false}) =>
|
||||
_Scanner(text, sourceUrl)..scan(asDSX: asDSX);
|
||||
|
||||
abstract class Scanner {
|
||||
List<JaelError> get errors;
|
||||
|
@ -21,7 +21,7 @@ abstract class Scanner {
|
|||
List<Token> get tokens;
|
||||
}
|
||||
|
||||
final RegExp _htmlComment = new RegExp(r'<!--[^$]*-->');
|
||||
final RegExp _htmlComment = RegExp(r'<!--[^$]*-->');
|
||||
|
||||
final Map<Pattern, TokenType> _expressionPatterns = {
|
||||
//final Map<Pattern, TokenType> _htmlPatterns = {
|
||||
|
@ -74,8 +74,8 @@ final Map<Pattern, TokenType> _expressionPatterns = {
|
|||
'==': TokenType.equ,
|
||||
'!=': TokenType.nequ,
|
||||
'=': TokenType.equals,
|
||||
new RegExp(r'-?[0-9]+(\.[0-9]+)?([Ee][0-9]+)?'): TokenType.number,
|
||||
new RegExp(r'0x[A-Fa-f0-9]+'): TokenType.hex,
|
||||
RegExp(r'-?[0-9]+(\.[0-9]+)?([Ee][0-9]+)?'): TokenType.number,
|
||||
RegExp(r'0x[A-Fa-f0-9]+'): TokenType.hex,
|
||||
_string1: TokenType.string,
|
||||
_string2: TokenType.string,
|
||||
_id: TokenType.id,
|
||||
|
@ -85,15 +85,15 @@ class _Scanner implements Scanner {
|
|||
final List<JaelError> errors = [];
|
||||
final List<Token> tokens = [];
|
||||
_ScannerState state = _ScannerState.html;
|
||||
final Queue<String> openTags = new Queue();
|
||||
final Queue<String> openTags = Queue();
|
||||
|
||||
SpanScanner _scanner;
|
||||
|
||||
_Scanner(String text, sourceUrl) {
|
||||
_scanner = new SpanScanner(text, sourceUrl: sourceUrl);
|
||||
_scanner = SpanScanner(text, sourceUrl: sourceUrl);
|
||||
}
|
||||
|
||||
void scan({bool asDSX: false}) {
|
||||
void scan({bool asDSX = false}) {
|
||||
while (!_scanner.isDone) {
|
||||
if (state == _ScannerState.html) {
|
||||
scanHtml(asDSX);
|
||||
|
@ -164,14 +164,15 @@ class _Scanner implements Scanner {
|
|||
|
||||
var span = _scanner.spanFrom(start, end);
|
||||
|
||||
if (span.text.isNotEmpty)
|
||||
tokens.add(new Token(TokenType.text, span, null));
|
||||
if (span.text.isNotEmpty) {
|
||||
tokens.add(Token(TokenType.text, span, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void scanHtml(bool asDSX) {
|
||||
var brackets = new Queue<Token>();
|
||||
var brackets = Queue<Token>();
|
||||
|
||||
do {
|
||||
// Only continue if we find a left bracket
|
||||
|
@ -184,9 +185,9 @@ class _Scanner implements Scanner {
|
|||
_scanner.scan(_whitespace);
|
||||
|
||||
_expressionPatterns.forEach((pattern, type) {
|
||||
if (_scanner.matches(pattern))
|
||||
potential
|
||||
.add(new Token(type, _scanner.lastSpan, _scanner.lastMatch));
|
||||
if (_scanner.matches(pattern)) {
|
||||
potential.add(Token(type, _scanner.lastSpan, _scanner.lastMatch));
|
||||
}
|
||||
});
|
||||
|
||||
potential.sort((a, b) => b.span.length.compareTo(a.span.length));
|
||||
|
|
|
@ -107,7 +107,7 @@ void main() {
|
|||
|
||||
String render(String template, [Map<String, dynamic> values]) {
|
||||
var doc = jael.parseDocument(template, onError: (e) => throw e);
|
||||
var buffer = new CodeBuffer();
|
||||
const jael.Renderer().render(doc, buffer, new SymbolTable(values: values));
|
||||
var buffer = CodeBuffer();
|
||||
const jael.Renderer().render(doc, buffer, SymbolTable(values: values));
|
||||
return buffer.toString();
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ void main() {
|
|||
foo
|
||||
.getAttribute('yes')
|
||||
.value
|
||||
.compute(new SymbolTable(values: {'no': 'maybe'})),
|
||||
.compute(SymbolTable(values: {'no': 'maybe'})),
|
||||
'maybe');
|
||||
});
|
||||
|
||||
|
|
|
@ -15,13 +15,13 @@ main() {
|
|||
</html>
|
||||
''';
|
||||
|
||||
var buf = new CodeBuffer();
|
||||
var buf = CodeBuffer();
|
||||
jael.Document document;
|
||||
SymbolTable scope;
|
||||
|
||||
try {
|
||||
document = jael.parseDocument(template, sourceUrl: 'test.jael');
|
||||
scope = new SymbolTable<dynamic>(values: {
|
||||
scope = SymbolTable<dynamic>(values: {
|
||||
'csrf_token': 'foo',
|
||||
'profile': {
|
||||
'avatar': 'thosakwe.png',
|
||||
|
@ -64,10 +64,10 @@ main() {
|
|||
</html>
|
||||
''';
|
||||
|
||||
var buf = new CodeBuffer();
|
||||
var buf = CodeBuffer();
|
||||
//jael.scan(template, sourceUrl: 'test.jael').tokens.forEach(print);
|
||||
var document = jael.parseDocument(template, sourceUrl: 'test.jael');
|
||||
var scope = new SymbolTable<dynamic>(values: {
|
||||
var scope = SymbolTable<dynamic>(values: {
|
||||
'pokemon': const _Pokemon('Darkrai', 'Dark'),
|
||||
});
|
||||
|
||||
|
@ -105,9 +105,9 @@ main() {
|
|||
</html>
|
||||
''';
|
||||
|
||||
var buf = new CodeBuffer();
|
||||
var buf = CodeBuffer();
|
||||
var document = jael.parseDocument(template, sourceUrl: 'test.jael');
|
||||
var scope = new SymbolTable<dynamic>(values: {
|
||||
var scope = SymbolTable<dynamic>(values: {
|
||||
'starters': starters,
|
||||
});
|
||||
|
||||
|
@ -150,9 +150,9 @@ main() {
|
|||
</html>
|
||||
''';
|
||||
|
||||
var buf = new CodeBuffer();
|
||||
var buf = CodeBuffer();
|
||||
var document = jael.parseDocument(template, sourceUrl: 'test.jael');
|
||||
var scope = new SymbolTable<dynamic>(values: {
|
||||
var scope = SymbolTable<dynamic>(values: {
|
||||
'starters': starters,
|
||||
});
|
||||
|
||||
|
@ -196,9 +196,9 @@ main() {
|
|||
</div>
|
||||
''';
|
||||
|
||||
var buf = new CodeBuffer();
|
||||
var buf = CodeBuffer();
|
||||
var document = jael.parseDocument(template, sourceUrl: 'test.jael');
|
||||
var scope = new SymbolTable();
|
||||
var scope = SymbolTable();
|
||||
|
||||
const jael.Renderer().render(document, buf, scope);
|
||||
print(buf);
|
||||
|
@ -242,9 +242,9 @@ main() {
|
|||
</div>
|
||||
''';
|
||||
|
||||
var buf = new CodeBuffer();
|
||||
var buf = CodeBuffer();
|
||||
var document = jael.parseDocument(template, sourceUrl: 'test.jael');
|
||||
var scope = new SymbolTable();
|
||||
var scope = SymbolTable();
|
||||
|
||||
const jael.Renderer().render(document, buf, scope);
|
||||
print(buf);
|
||||
|
@ -267,9 +267,9 @@ main() {
|
|||
<button '(click)'="myEventHandler(\$event)"></button>
|
||||
''';
|
||||
|
||||
var buf = new CodeBuffer();
|
||||
var buf = CodeBuffer();
|
||||
var document = jael.parseDocument(template, sourceUrl: 'test.jael');
|
||||
var scope = new SymbolTable();
|
||||
var scope = SymbolTable();
|
||||
|
||||
const jael.Renderer().render(document, buf, scope);
|
||||
print(buf);
|
||||
|
@ -298,10 +298,10 @@ main() {
|
|||
</switch>
|
||||
''';
|
||||
|
||||
var buf = new CodeBuffer();
|
||||
var buf = CodeBuffer();
|
||||
var document = jael.parseDocument(template, sourceUrl: 'test.jael');
|
||||
var scope = new SymbolTable<dynamic>(values: {
|
||||
'account': new _Account(isDisabled: true),
|
||||
var scope = SymbolTable<dynamic>(values: {
|
||||
'account': _Account(isDisabled: true),
|
||||
});
|
||||
|
||||
const jael.Renderer().render(document, buf, scope);
|
||||
|
@ -325,10 +325,10 @@ main() {
|
|||
</switch>
|
||||
''';
|
||||
|
||||
var buf = new CodeBuffer();
|
||||
var buf = CodeBuffer();
|
||||
var document = jael.parseDocument(template, sourceUrl: 'test.jael');
|
||||
var scope = new SymbolTable<dynamic>(values: {
|
||||
'account': new _Account(isDisabled: null),
|
||||
var scope = SymbolTable<dynamic>(values: {
|
||||
'account': _Account(isDisabled: null),
|
||||
});
|
||||
|
||||
const jael.Renderer().render(document, buf, scope);
|
||||
|
@ -338,10 +338,10 @@ main() {
|
|||
});
|
||||
}
|
||||
|
||||
const List<_Pokemon> starters = const [
|
||||
const _Pokemon('Bulbasaur', 'Grass'),
|
||||
const _Pokemon('Charmander', 'Fire'),
|
||||
const _Pokemon('Squirtle', 'Water'),
|
||||
const List<_Pokemon> starters = [
|
||||
_Pokemon('Bulbasaur', 'Grass'),
|
||||
_Pokemon('Charmander', 'Fire'),
|
||||
_Pokemon('Squirtle', 'Water'),
|
||||
];
|
||||
|
||||
class _Pokemon {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:matcher/matcher.dart';
|
||||
import 'package:jael/src/ast/token.dart';
|
||||
|
||||
Matcher isToken(TokenType type, [String text]) => new _IsToken(type, text);
|
||||
Matcher isToken(TokenType type, [String text]) => _IsToken(type, text);
|
||||
|
||||
class _IsToken extends Matcher {
|
||||
final TokenType type;
|
||||
|
|
|
@ -1,3 +1 @@
|
|||
abstract class DomNode {
|
||||
|
||||
}
|
||||
abstract class DomNode {}
|
||||
|
|
Loading…
Reference in a new issue