diff --git a/packages/jael/jael/bin/jaelfmt.dart b/packages/jael/jael/bin/jaelfmt.dart index e3569c51..c4935c9c 100644 --- a/packages/jael/jael/bin/jaelfmt.dart +++ b/packages/jael/jael/bin/jaelfmt.dart @@ -41,7 +41,7 @@ main(List args) async { if (argResults.rest.isEmpty) { var text = await stdin.transform(utf8.decoder).join(); var result = - await format(argResults['stdin-name'] as String, text, argResults); + await format(argResults['stdin-name'] as String?, text, argResults); if (result != null) print(result); } else { for (var arg in argResults.rest) { @@ -91,14 +91,14 @@ Future formatStat( Future formatFile(File file, ArgResults argResults) async { var content = await file.readAsString(); - var formatted = await format(file.path, content, argResults); + var formatted = format(file.path, content, argResults); if (formatted == null) return; if (argResults['overwrite'] as bool) { if (formatted != content) { if (argResults['dry-run'] as bool) { print('Would have formatted ${file.path}'); } else { - await file.writeAsStringSync(formatted); + file.writeAsStringSync(formatted); print('Formatted ${file.path}'); } } else { @@ -109,7 +109,7 @@ Future formatFile(File file, ArgResults argResults) async { } } -String format(String filename, String content, ArgResults argResults) { +String? format(String? filename, String content, ArgResults argResults) { var errored = false; var doc = parseDocument(content, sourceUrl: filename, onError: (e) { stderr.writeln(e); @@ -118,7 +118,7 @@ String format(String filename, String content, ArgResults argResults) { if (errored) return null; var fmt = JaelFormatter( int.parse(argResults['tab-size'] as String), - argResults['insert-spaces'] as bool, + argResults['insert-spaces'] as bool?, int.parse(argResults['line-length'] as String)); return fmt.apply(doc); } diff --git a/packages/jael/jael/lib/src/ast/array.dart b/packages/jael/jael/lib/src/ast/array.dart index aff752b3..d4f93a1e 100644 --- a/packages/jael/jael/lib/src/ast/array.dart +++ b/packages/jael/jael/lib/src/ast/array.dart @@ -3,39 +3,39 @@ import 'expression.dart'; import 'token.dart'; class Array extends Expression { - final Token lBracket, rBracket; + final Token? lBracket, rBracket; final List items; Array(this.lBracket, this.rBracket, this.items); @override - compute(scope) => items.map((e) => e.compute(scope)).toList(); + List compute(scope) => items.map((e) => e.compute(scope)).toList(); @override FileSpan get span { return items - .fold(lBracket.span, (out, i) => out.expand(i.span)) - .expand(rBracket.span); + .fold(lBracket!.span, (out, i) => out!.expand(i.span!))! + .expand(rBracket!.span!); } } class IndexerExpression extends Expression { - final Expression target, indexer; - final Token lBracket, rBracket; + final Expression? target, indexer; + final Token? lBracket, rBracket; IndexerExpression(this.target, this.lBracket, this.indexer, this.rBracket); @override FileSpan get span { - return target.span - .expand(lBracket.span) - .expand(indexer.span) - .expand(rBracket.span); + return target!.span! + .expand(lBracket!.span!) + .expand(indexer!.span!) + .expand(rBracket!.span!); } @override - compute(scope) { - var a = target.compute(scope), b = indexer.compute(scope); + dynamic compute(scope) { + var a = target!.compute(scope), b = indexer!.compute(scope); return a[b]; } } diff --git a/packages/jael/jael/lib/src/ast/ast_node.dart b/packages/jael/jael/lib/src/ast/ast_node.dart index c48971da..29f2bd67 100644 --- a/packages/jael/jael/lib/src/ast/ast_node.dart +++ b/packages/jael/jael/lib/src/ast/ast_node.dart @@ -1,5 +1,5 @@ import 'package:source_span/source_span.dart'; abstract class AstNode { - FileSpan get span; + FileSpan? get span; } diff --git a/packages/jael/jael/lib/src/ast/attribute.dart b/packages/jael/jael/lib/src/ast/attribute.dart index f06d76e8..1bbbf599 100644 --- a/packages/jael/jael/lib/src/ast/attribute.dart +++ b/packages/jael/jael/lib/src/ast/attribute.dart @@ -6,22 +6,22 @@ import 'string.dart'; import 'token.dart'; class Attribute extends AstNode { - final Identifier id; - final StringLiteral string; - final Token equals, nequ; - final Expression value; + final Identifier? id; + final StringLiteral? string; + final Token? equals, nequ; + final Expression? value; Attribute(this.id, this.string, this.equals, this.nequ, this.value); bool get isRaw => nequ != null; - Expression get nameNode => id ?? string; + Expression? get nameNode => id ?? string; - String get name => string?.value ?? id.name; + String get name => string?.value ?? id!.name; @override - FileSpan get span { - if (equals == null) return nameNode.span; - return nameNode.span.expand(equals?.span ?? nequ.span).expand(value.span); + FileSpan? get span { + if (equals == null) return nameNode!.span; + return nameNode!.span!.expand(equals?.span ?? nequ!.span!).expand(value!.span!); } } diff --git a/packages/jael/jael/lib/src/ast/binary.dart b/packages/jael/jael/lib/src/ast/binary.dart index 75ed2261..908f3f59 100644 --- a/packages/jael/jael/lib/src/ast/binary.dart +++ b/packages/jael/jael/lib/src/ast/binary.dart @@ -3,14 +3,14 @@ import 'expression.dart'; import 'token.dart'; class BinaryExpression extends Expression { - final Expression left, right; - final Token operator; + final Expression? left, right; + final Token? operator; BinaryExpression(this.left, this.operator, this.right); @override compute(scope) { - var l = left.compute(scope), r = right.compute(scope); + var l = left!.compute(scope), r = right!.compute(scope); switch (operator?.type) { case TokenType.asterisk: @@ -43,5 +43,5 @@ class BinaryExpression extends Expression { } @override - FileSpan get span => left.span.expand(operator.span).expand(right.span); + FileSpan get span => left!.span!.expand(operator!.span!).expand(right!.span!); } diff --git a/packages/jael/jael/lib/src/ast/call.dart b/packages/jael/jael/lib/src/ast/call.dart index 0e1272a9..e19551c7 100644 --- a/packages/jael/jael/lib/src/ast/call.dart +++ b/packages/jael/jael/lib/src/ast/call.dart @@ -6,8 +6,8 @@ import 'identifier.dart'; import 'token.dart'; class Call extends Expression { - final Expression target; - final Token lParen, rParen; + final Expression? target; + final Token? lParen, rParen; final List arguments; final List namedArguments; @@ -17,10 +17,10 @@ class Call extends Expression { @override FileSpan get span { return arguments - .fold(target.span, (out, a) => out.expand(a.span)) - .expand(namedArguments.fold( - lParen.span, (out, a) => out.expand(a.span))) - .expand(rParen.span); + .fold(target!.span, (out, a) => out!.expand(a.span!))! + .expand(namedArguments.fold( + lParen!.span, (out, a) => out!.expand(a.span))!) + .expand(rParen!.span!); } List computePositional(SymbolTable scope) => @@ -34,7 +34,7 @@ class Call extends Expression { @override compute(scope) { - var callee = target.compute(scope); + var callee = target!.compute(scope); var args = computePositional(scope); var named = computeNamed(scope); @@ -44,13 +44,13 @@ class Call extends Expression { class NamedArgument extends AstNode { final Identifier name; - final Token colon; + final Token? colon; final Expression value; NamedArgument(this.name, this.colon, this.value); @override FileSpan get span { - return name.span.expand(colon.span).expand(value.span); + return name.span!.expand(colon!.span!).expand(value.span!); } } diff --git a/packages/jael/jael/lib/src/ast/conditional.dart b/packages/jael/jael/lib/src/ast/conditional.dart index c54f6358..d3491193 100644 --- a/packages/jael/jael/lib/src/ast/conditional.dart +++ b/packages/jael/jael/lib/src/ast/conditional.dart @@ -3,29 +3,29 @@ import 'expression.dart'; import 'token.dart'; class Conditional extends Expression { - final Expression condition, ifTrue, ifFalse; - final Token question, colon; + final Expression? condition, ifTrue, ifFalse; + final Token? question, colon; Conditional( this.condition, this.question, this.ifTrue, this.colon, this.ifFalse); @override FileSpan get span { - return condition.span - .expand(question.span) - .expand(ifTrue.span) - .expand(colon.span) - .expand(ifFalse.span); + return condition!.span! + .expand(question!.span!) + .expand(ifTrue!.span!) + .expand(colon!.span!) + .expand(ifFalse!.span!); } @override compute(scope) { - var v = condition.compute(scope) as bool; + var v = condition!.compute(scope) as bool?; if (scope.resolve('!strict!')?.value == false) { v = v == true; } - return v ? ifTrue.compute(scope) : ifFalse.compute(scope); + return v! ? ifTrue!.compute(scope) : ifFalse!.compute(scope); } } diff --git a/packages/jael/jael/lib/src/ast/document.dart b/packages/jael/jael/lib/src/ast/document.dart index b59a371e..04c8198e 100644 --- a/packages/jael/jael/lib/src/ast/document.dart +++ b/packages/jael/jael/lib/src/ast/document.dart @@ -6,40 +6,40 @@ import 'string.dart'; import 'token.dart'; class Document extends AstNode { - final Doctype doctype; + final Doctype? doctype; final Element root; Document(this.doctype, this.root); @override - FileSpan get span { + FileSpan? get span { if (doctype == null) return root.span; - return doctype.span.expand(root.span); + return doctype!.span.expand(root.span!); } } class HtmlComment extends ElementChild { - final Token htmlComment; + final Token? htmlComment; HtmlComment(this.htmlComment); @override - FileSpan get span => htmlComment.span; + FileSpan? get span => htmlComment!.span; } class Text extends ElementChild { - final Token text; + final Token? text; Text(this.text); @override - FileSpan get span => text.span; + FileSpan? get span => text!.span; } class Doctype extends AstNode { - final Token lt, doctype, gt; - final Identifier html, public; - final StringLiteral name, url; + final Token? lt, doctype, gt; + final Identifier? html, public; + final StringLiteral? name, url; Doctype(this.lt, this.doctype, this.html, this.public, this.name, this.url, this.gt); @@ -47,14 +47,14 @@ class Doctype extends AstNode { @override FileSpan get span { if (public == null) { - return lt.span.expand(doctype.span).expand(html.span).expand(gt.span); + return lt!.span!.expand(doctype!.span!).expand(html!.span!).expand(gt!.span!); } - return lt.span - .expand(doctype.span) - .expand(html.span) - .expand(public.span) - .expand(name.span) - .expand(url.span) - .expand(gt.span); + return lt!.span! + .expand(doctype!.span!) + .expand(html!.span!) + .expand(public!.span!) + .expand(name!.span!) + .expand(url!.span!) + .expand(gt!.span!); } } diff --git a/packages/jael/jael/lib/src/ast/element.dart b/packages/jael/jael/lib/src/ast/element.dart index bdfb5653..5a359061 100644 --- a/packages/jael/jael/lib/src/ast/element.dart +++ b/packages/jael/jael/lib/src/ast/element.dart @@ -1,3 +1,4 @@ +import 'package:collection/collection.dart' show IterableExtension; import 'package:source_span/source_span.dart'; import 'ast_node.dart'; import 'attribute.dart'; @@ -12,7 +13,7 @@ class TextNode extends ElementChild { TextNode(this.text); @override - FileSpan get span => text.span; + FileSpan? get span => text.span; } abstract class Element extends ElementChild { @@ -38,12 +39,12 @@ abstract class Element extends ElementChild { Iterable get children; - Attribute getAttribute(String name) => - attributes.firstWhere((a) => a.name == name, orElse: () => null); + Attribute? getAttribute(String name) => + attributes.firstWhereOrNull((a) => a.name == name); } class SelfClosingElement extends Element { - final Token lt, slash, gt; + final Token? lt, slash, gt; final Identifier tagName; @@ -58,15 +59,15 @@ class SelfClosingElement extends Element { @override FileSpan get span { var start = attributes.fold( - lt.span.expand(tagName.span), (out, a) => out.expand(a.span)); + lt!.span!.expand(tagName.span!), (out, a) => out.expand(a.span!)); return slash != null - ? start.expand(slash.span).expand(gt.span) - : start.expand(gt.span); + ? start.expand(slash!.span!).expand(gt!.span!) + : start.expand(gt!.span!); } } class RegularElement extends Element { - final Token lt, gt, lt2, slash, gt2; + final Token? lt, gt, lt2, slash, gt2; final Identifier tagName, tagName2; @@ -81,16 +82,16 @@ class RegularElement extends Element { FileSpan get span { var openingTag = attributes .fold( - lt.span.expand(tagName.span), (out, a) => out.expand(a.span)) - .expand(gt.span); + lt!.span!.expand(tagName.span!), (out, a) => out.expand(a.span!)) + .expand(gt!.span!); if (gt2 == null) return openingTag; return children - .fold(openingTag, (out, c) => out.expand(c.span)) - .expand(lt2.span) - .expand(slash.span) - .expand(tagName2.span) - .expand(gt2.span); + .fold(openingTag, (out, c) => out.expand(c.span!)) + .expand(lt2!.span!) + .expand(slash!.span!) + .expand(tagName2.span!) + .expand(gt2!.span!); } } diff --git a/packages/jael/jael/lib/src/ast/error.dart b/packages/jael/jael/lib/src/ast/error.dart index f931a126..66784d5b 100644 --- a/packages/jael/jael/lib/src/ast/error.dart +++ b/packages/jael/jael/lib/src/ast/error.dart @@ -3,15 +3,15 @@ import 'package:source_span/source_span.dart'; class JaelError extends Error { final JaelErrorSeverity severity; final String message; - final FileSpan span; + final FileSpan? span; JaelError(this.severity, this.message, this.span); @override String toString() { var label = severity == JaelErrorSeverity.warning ? 'warning' : 'error'; - return '$label: ${span.start.toolString}: $message\n' + - span.highlight(color: true); + return '$label: ${span!.start.toolString}: $message\n' + + span!.highlight(color: true); } } diff --git a/packages/jael/jael/lib/src/ast/expression.dart b/packages/jael/jael/lib/src/ast/expression.dart index 0e0f8147..851312b7 100644 --- a/packages/jael/jael/lib/src/ast/expression.dart +++ b/packages/jael/jael/lib/src/ast/expression.dart @@ -4,30 +4,30 @@ import 'ast_node.dart'; import 'token.dart'; abstract class Expression extends AstNode { - compute(SymbolTable scope); + dynamic compute(SymbolTable scope); } abstract class Literal extends Expression {} class Negation extends Expression { - final Token exclamation; - final Expression expression; + final Token? exclamation; + final Expression? expression; Negation(this.exclamation, this.expression); @override FileSpan get span { - return exclamation.span.expand(expression.span); + return exclamation!.span!.expand(expression!.span!); } @override compute(SymbolTable scope) { - var v = expression.compute(scope) as bool; + var v = expression!.compute(scope) as bool?; if (scope.resolve('!strict!')?.value == false) { v = v == true; } - return !v; + return !v!; } } diff --git a/packages/jael/jael/lib/src/ast/identifier.dart b/packages/jael/jael/lib/src/ast/identifier.dart index e2f8c6fd..da95c2d4 100644 --- a/packages/jael/jael/lib/src/ast/identifier.dart +++ b/packages/jael/jael/lib/src/ast/identifier.dart @@ -4,7 +4,7 @@ import 'expression.dart'; import 'token.dart'; class Identifier extends Expression { - final Token id; + final Token? id; Identifier(this.id); @@ -23,25 +23,25 @@ class Identifier extends Expression { if (scope.resolve('!strict!')?.value == false) return null; throw ArgumentError('The name "$name" does not exist in this scope.'); } - return scope.resolve(name).value; + return scope.resolve(name)!.value; } } - String get name => id.span.text; + String get name => id!.span!.text; @override - FileSpan get span => id.span; + FileSpan? get span => id!.span; } class SyntheticIdentifier extends Identifier { @override final String name; - SyntheticIdentifier(this.name, [Token token]) : super(token); + SyntheticIdentifier(this.name, [Token? token]) : super(token); @override - FileSpan get span { - if (id != null) return id.span; + FileSpan? get span { + if (id != null) return id!.span; throw UnsupportedError('Cannot get the span of a SyntheticIdentifier.'); } } diff --git a/packages/jael/jael/lib/src/ast/interpolation.dart b/packages/jael/jael/lib/src/ast/interpolation.dart index 2dacb790..331011ba 100644 --- a/packages/jael/jael/lib/src/ast/interpolation.dart +++ b/packages/jael/jael/lib/src/ast/interpolation.dart @@ -4,15 +4,15 @@ import 'expression.dart'; import 'token.dart'; class Interpolation extends ElementChild { - final Token doubleCurlyL, doubleCurlyR; + final Token? doubleCurlyL, doubleCurlyR; final Expression expression; Interpolation(this.doubleCurlyL, this.expression, this.doubleCurlyR); - bool get isRaw => doubleCurlyL.span.text.endsWith('-'); + bool get isRaw => doubleCurlyL!.span!.text.endsWith('-'); @override FileSpan get span { - return doubleCurlyL.span.expand(expression.span).expand(doubleCurlyR.span); + return doubleCurlyL!.span!.expand(expression.span!).expand(doubleCurlyR!.span!); } } diff --git a/packages/jael/jael/lib/src/ast/map.dart b/packages/jael/jael/lib/src/ast/map.dart index 8f457f3b..23078a1e 100644 --- a/packages/jael/jael/lib/src/ast/map.dart +++ b/packages/jael/jael/lib/src/ast/map.dart @@ -5,7 +5,7 @@ import 'identifier.dart'; import 'token.dart'; class MapLiteral extends Literal { - final Token lCurly, rCurly; + final Token? lCurly, rCurly; final List pairs; MapLiteral(this.lCurly, this.pairs, this.rCurly); @@ -17,14 +17,14 @@ class MapLiteral extends Literal { if (p.colon == null) { if (p.key is! Identifier) { - key = value = p.key.compute(scope); + key = value = p.key!.compute(scope); } else { key = (p.key as Identifier).name; - value = p.key.compute(scope); + value = p.key!.compute(scope); } } else { - key = p.key.compute(scope); - value = p.value.compute(scope); + key = p.key!.compute(scope); + value = p.value!.compute(scope); } return out..[key] = value; @@ -34,20 +34,20 @@ class MapLiteral extends Literal { @override FileSpan get span { return pairs - .fold(lCurly.span, (out, p) => out.expand(p.span)) - .expand(rCurly.span); + .fold(lCurly!.span, (out, p) => out!.expand(p.span!))! + .expand(rCurly!.span!); } } class KeyValuePair extends AstNode { - final Expression key, value; - final Token colon; + final Expression? key, value; + final Token? colon; KeyValuePair(this.key, this.colon, this.value); @override - FileSpan get span { - if (colon == null) return key.span; - return colon.span.expand(colon.span).expand(value.span); + FileSpan? get span { + if (colon == null) return key!.span; + return colon!.span!.expand(colon!.span!).expand(value!.span!); } } diff --git a/packages/jael/jael/lib/src/ast/member.dart b/packages/jael/jael/lib/src/ast/member.dart index 1bac5e50..86751fbe 100644 --- a/packages/jael/jael/lib/src/ast/member.dart +++ b/packages/jael/jael/lib/src/ast/member.dart @@ -6,19 +6,19 @@ import 'identifier.dart'; import 'token.dart'; class MemberExpression extends Expression { - final Expression expression; - final Token op; + final Expression? expression; + final Token? op; final Identifier name; MemberExpression(this.expression, this.op, this.name); @override compute(SymbolTable scope) { - var target = expression.compute(scope); - if (op.span.text == '?.' && target == null) return null; + var target = expression!.compute(scope); + if (op!.span!.text == '?.' && target == null) return null; return reflect(target).getField(Symbol(name.name)).reflectee; } @override - FileSpan get span => expression.span.expand(op.span).expand(name.span); + FileSpan get span => expression!.span!.expand(op!.span!).expand(name.span!); } diff --git a/packages/jael/jael/lib/src/ast/new.dart b/packages/jael/jael/lib/src/ast/new.dart index d13892ce..57ec6be2 100644 --- a/packages/jael/jael/lib/src/ast/new.dart +++ b/packages/jael/jael/lib/src/ast/new.dart @@ -6,17 +6,17 @@ import 'member.dart'; import 'token.dart'; class NewExpression extends Expression { - final Token $new; + final Token? $new; final Call call; NewExpression(this.$new, this.call); @override - FileSpan get span => $new.span.expand(call.span); + FileSpan get span => $new!.span!.expand(call.span); @override compute(scope) { - var targetType = call.target.compute(scope); + var targetType = call.target!.compute(scope); var positional = call.computePositional(scope); var named = call.computeNamed(scope); var name = ''; diff --git a/packages/jael/jael/lib/src/ast/number.dart b/packages/jael/jael/lib/src/ast/number.dart index 3ef3eab5..c91dc48f 100644 --- a/packages/jael/jael/lib/src/ast/number.dart +++ b/packages/jael/jael/lib/src/ast/number.dart @@ -4,13 +4,13 @@ import 'expression.dart'; import 'token.dart'; class NumberLiteral extends Literal { - final Token number; - num _value; + final Token? number; + num? _value; NumberLiteral(this.number); @override - FileSpan get span => number.span; + FileSpan? get span => number!.span; static num parse(String value) { var e = value.indexOf('E'); @@ -25,23 +25,23 @@ class NumberLiteral extends Literal { @override compute(scope) { - return _value ??= parse(number.span.text); + return _value ??= parse(number!.span!.text); } } class HexLiteral extends Literal { - final Token hex; - num _value; + final Token? hex; + num? _value; HexLiteral(this.hex); @override - FileSpan get span => hex.span; + FileSpan? get span => hex!.span; static num parse(String value) => int.parse(value.substring(2), radix: 16); @override compute(scope) { - return _value ??= parse(hex.span.text); + return _value ??= parse(hex!.span!.text); } } diff --git a/packages/jael/jael/lib/src/ast/string.dart b/packages/jael/jael/lib/src/ast/string.dart index cf7163e3..3a87c3ae 100644 --- a/packages/jael/jael/lib/src/ast/string.dart +++ b/packages/jael/jael/lib/src/ast/string.dart @@ -6,13 +6,13 @@ import 'expression.dart'; import 'token.dart'; class StringLiteral extends Literal { - final Token string; + final Token? string; final String value; StringLiteral(this.string, this.value); static String parseValue(Token string) { - var text = string.span.text.substring(1, string.span.text.length - 1); + var text = string.span!.text.substring(1, string.span!.text.length - 1); var codeUnits = text.codeUnits; var buf = StringBuffer(); @@ -71,5 +71,5 @@ class StringLiteral extends Literal { } @override - FileSpan get span => string.span; + FileSpan? get span => string!.span; } diff --git a/packages/jael/jael/lib/src/ast/token.dart b/packages/jael/jael/lib/src/ast/token.dart index 0e4d4a04..54deaf6b 100644 --- a/packages/jael/jael/lib/src/ast/token.dart +++ b/packages/jael/jael/lib/src/ast/token.dart @@ -2,14 +2,14 @@ import 'package:source_span/source_span.dart'; class Token { final TokenType type; - final FileSpan span; - final Match match; + final FileSpan? span; + final Match? match; Token(this.type, this.span, this.match); @override String toString() { - return '${span.start.toolString}: "${span.text}" => $type'; + return '${span!.start.toolString}: "${span!.text}" => $type'; } } diff --git a/packages/jael/jael/lib/src/formatter.dart b/packages/jael/jael/lib/src/formatter.dart index 9b62f9e2..3b46ed7c 100644 --- a/packages/jael/jael/lib/src/formatter.dart +++ b/packages/jael/jael/lib/src/formatter.dart @@ -3,11 +3,11 @@ import 'ast/ast.dart'; /// Jael formatter class JaelFormatter { final num tabSize; - final bool insertSpaces; + final bool? insertSpaces; final int maxLineLength; var _buffer = StringBuffer(); int _level = 0; - String _spaces; + String? _spaces; static String _spaceString(int tabSize) { var b = StringBuffer(); @@ -18,7 +18,7 @@ class JaelFormatter { } JaelFormatter(this.tabSize, this.insertSpaces, this.maxLineLength) { - _spaces = insertSpaces ? _spaceString(tabSize.toInt()) : '\t'; + _spaces = insertSpaces! ? _spaceString(tabSize.toInt()) : '\t'; } void _indent() { @@ -38,20 +38,20 @@ class JaelFormatter { int get _spaceLength { var out = 0; for (int i = 0; i < _level; i++) { - out += _spaces.length; + out += _spaces!.length; } return out; } - String apply(Document document) { + String apply(Document? document) { if (document?.doctype != null) { _buffer.write(''); @@ -62,7 +62,7 @@ class JaelFormatter { return _buffer.toString().trim(); } - int _formatChild(ElementChild child, int lineLength, + int _formatChild(ElementChild? child, int lineLength, {bool isFirst = false, bool isLast = false}) { if (child == null) { return lineLength; @@ -72,11 +72,11 @@ class JaelFormatter { var b = StringBuffer('{{'); if (child.isRaw) b.write('-'); b.write(' '); - b.write(child.expression.span.text.trim()); + b.write(child.expression.span!.text.trim()); b.write(' }}'); s = b.toString(); } else { - s = child.span.text; + s = child.span!.text; } if (isFirst) { s = s.trimLeft(); @@ -145,7 +145,7 @@ class JaelFormatter { _indent(); var lll = _spaceLength; var i = 1; - ElementChild last; + ElementChild? last; for (var c in element.children) { if (lll == _spaceLength && c is! Element) { _applySpacing(); @@ -186,7 +186,7 @@ class JaelFormatter { } else { if (attr.nequ != null) b.write('!='); if (attr.equals != null) b.write('='); - b.write(attr.value.span.text); + b.write(attr.value!.span!.text); } } return b.toString(); diff --git a/packages/jael/jael/lib/src/renderer.dart b/packages/jael/jael/lib/src/renderer.dart index 62b36442..43d4cd5c 100644 --- a/packages/jael/jael/lib/src/renderer.dart +++ b/packages/jael/jael/lib/src/renderer.dart @@ -1,13 +1,14 @@ import 'dart:convert'; import 'package:code_buffer/code_buffer.dart'; +import 'package:collection/collection.dart' show IterableExtension; import 'package:symbol_table/symbol_table.dart'; import 'ast/ast.dart'; import 'text/parser.dart'; import 'text/scanner.dart'; /// Parses a Jael document. -Document parseDocument(String text, - {sourceUrl, bool asDSX = false, void onError(JaelError error)}) { +Document? parseDocument(String text, + {sourceUrl, bool asDSX = false, void onError(JaelError error)?}) { var scanner = scan(text, sourceUrl: sourceUrl, asDSX: asDSX); //scanner.tokens.forEach(print); @@ -55,12 +56,12 @@ class Renderer { ..writeln('
  • ') ..indent() ..writeln( - '$type: ${error.span.start.toolString}: ${error.message}') + '$type: ${error.span!.start.toolString}: ${error.message}') ..writeln('
    ') ..writeln( '' + htmlEscape - .convert(error.span.highlight(color: false)) + .convert(error.span!.highlight(color: false)) .replaceAll('\n', '
    ') + '
    ', ) @@ -83,7 +84,7 @@ class Renderer { {bool strictResolution = true}) { scope.create('!strict!', value: strictResolution != false); - if (document.doctype != null) buffer.writeln(document.doctype.span.text); + if (document.doctype != null) buffer.writeln(document.doctype!.span.text); renderElement( document.root, buffer, scope, document.doctype?.public == null); } @@ -177,15 +178,15 @@ class Renderer { var attribute = element.attributes.singleWhere((a) => a.name == 'for-each'); if (attribute.value == null) return; - var asAttribute = element.attributes - .firstWhere((a) => a.name == 'as', orElse: () => null); - var indexAsAttribute = element.attributes - .firstWhere((a) => a.name == 'index-as', orElse: () => null); + var asAttribute = + element.attributes.firstWhereOrNull((a) => a.name == 'as'); + var indexAsAttribute = + element.attributes.firstWhereOrNull((a) => a.name == 'index-as'); var alias = asAttribute?.value?.compute(scope)?.toString() ?? 'item'; var indexAs = indexAsAttribute?.value?.compute(scope)?.toString() ?? 'i'; var otherAttributes = element.attributes.where( (a) => a.name != 'for-each' && a.name != 'as' && a.name != 'index-as'); - Element strippedElement; + late Element strippedElement; if (element is SelfClosingElement) { strippedElement = SelfClosingElement(element.lt, element.tagName, @@ -204,7 +205,7 @@ class Renderer { } int i = 0; - for (var item in attribute.value.compute(scope)) { + for (var item in attribute.value!.compute(scope)) { var childScope = scope.createChild(values: {alias: item, indexAs: i++}); renderElement(strippedElement, buffer, childScope, html5); } @@ -214,7 +215,7 @@ class Renderer { Element element, CodeBuffer buffer, SymbolTable scope, bool html5) { var attribute = element.attributes.singleWhere((a) => a.name == 'if'); - var vv = attribute.value.compute(scope); + var vv = attribute.value!.compute(scope); if (scope.resolve('!strict!')?.value == false) { vv = vv == true; @@ -225,7 +226,7 @@ class Renderer { if (!v) return; var otherAttributes = element.attributes.where((a) => a.name != 'if'); - Element strippedElement; + late Element strippedElement; if (element is SelfClosingElement) { strippedElement = SelfClosingElement(element.lt, element.tagName, @@ -263,7 +264,7 @@ class Renderer { void renderSwitch( Element element, CodeBuffer buffer, SymbolTable scope, bool html5) { var value = element.attributes - .firstWhere((a) => a.name == 'value', orElse: () => null) + .firstWhereOrNull((a) => a.name == 'value') ?.value ?.compute(scope); @@ -273,7 +274,7 @@ class Renderer { for (var child in cases) { var comparison = child.attributes - .firstWhere((a) => a.name == 'value', orElse: () => null) + .firstWhereOrNull((a) => a.name == 'value') ?.value ?.compute(scope); if (comparison == value) { @@ -287,11 +288,10 @@ class Renderer { } } - var defaultCase = element.children.firstWhere( - (c) => c is Element && c.tagName.name == 'default', - orElse: () => null) as Element; + var defaultCase = element.children.firstWhereOrNull( + (c) => c is Element && c.tagName.name == 'default') as Element?; if (defaultCase != null) { - for (int i = 0; i < defaultCase.children.length; i++) { + for (var i = 0; i < defaultCase.children.length; i++) { var child = defaultCase.children.elementAt(i); renderElementChild(element, child, buffer, scope, html5, i, defaultCase.children.length); @@ -301,13 +301,13 @@ 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 (child is Text && parent.tagName.name != 'textarea') { if (index == 0) { - buffer.write(child.span.text.trimLeft()); + buffer.write(child.span!.text.trimLeft()); } else if (index == total - 1) { - buffer.write(child.span.text.trimRight()); + buffer.write(child.span!.text.trimRight()); } else { - buffer.write(child.span.text); + buffer.write(child.span!.text); } } else if (child is Interpolation) { var value = child.expression.compute(scope); @@ -320,7 +320,7 @@ class Renderer { } } } else if (child is Element) { - if (buffer?.lastLine?.text?.isNotEmpty == true) buffer.writeln(); + if (buffer.lastLine?.text.isNotEmpty == true) buffer.writeln(); renderElement(child, buffer, scope, html5); } } @@ -331,7 +331,7 @@ class Renderer { Element element, CodeBuffer buffer, SymbolTable scope, bool html5) { if (element is! RegularElement) { throw JaelError(JaelErrorSeverity.error, - "Custom elements cannot be self-closing.", element.span); + 'Custom elements cannot be self-closing.', element.span); } var name = element.getAttribute('name')?.value?.compute(scope)?.toString(); @@ -344,20 +344,20 @@ class Renderer { } try { - var p = scope.isRoot ? scope : scope.parent; + var p = scope.isRoot ? scope : scope.parent!; p.create(customElementName(name), value: element, constant: true); } on StateError { throw JaelError( JaelErrorSeverity.error, "Cannot re-define element '$name' in this scope.", - element.getAttribute('name').span); + element.getAttribute('name')!.span); } } void renderCustomElement( Element element, CodeBuffer buffer, SymbolTable scope, bool html5) { - var template = scope.resolve(customElementName(element.tagName.name)).value - as RegularElement; + var template = scope.resolve(customElementName(element.tagName.name))!.value + as RegularElement?; var renderAs = element.getAttribute('as')?.value?.compute(scope); var attrs = element.attributes.where((a) => a.name != 'as'); @@ -369,7 +369,7 @@ class Renderer { } if (renderAs == false) { - for (int i = 0; i < template.children.length; i++) { + for (int i = 0; i < template!.children.length; i++) { var child = template.children.elementAt(i); renderElementChild( element, child, buffer, scope, html5, i, element.children.length); @@ -378,7 +378,7 @@ class Renderer { var tagName = renderAs?.toString() ?? 'div'; var syntheticElement = RegularElement( - template.lt, + template!.lt, SyntheticIdentifier(tagName), element.attributes .where((a) => a.name != 'as' && !a.name.startsWith('@')), diff --git a/packages/jael/jael/lib/src/text/parselet/infix.dart b/packages/jael/jael/lib/src/text/parselet/infix.dart index 9c52e6af..9a5a27aa 100644 --- a/packages/jael/jael/lib/src/text/parselet/infix.dart +++ b/packages/jael/jael/lib/src/text/parselet/infix.dart @@ -28,12 +28,12 @@ class ConditionalParselet implements InfixParselet { const ConditionalParselet(); @override - Expression parse(Parser parser, Expression left, Token token) { + Expression? parse(Parser parser, Expression? left, Token? token) { var ifTrue = parser.parseExpression(0); if (ifTrue == null) { parser.errors.add(JaelError(JaelErrorSeverity.error, - 'Missing expression in conditional expression.', token.span)); + 'Missing expression in conditional expression.', token!.span)); return null; } @@ -48,7 +48,7 @@ class ConditionalParselet implements InfixParselet { if (ifFalse == null) { parser.errors.add(JaelError(JaelErrorSeverity.error, - 'Missing expression in conditional expression.', colon.span)); + 'Missing expression in conditional expression.', colon!.span)); return null; } @@ -62,14 +62,14 @@ class BinaryParselet implements InfixParselet { const BinaryParselet(this.precedence); @override - Expression parse(Parser parser, Expression left, Token token) { + Expression? parse(Parser parser, Expression? left, Token? token) { var right = parser.parseExpression(precedence); if (right == null) { - if (token.type != TokenType.gt) { + if (token!.type != TokenType.gt) { parser.errors.add(JaelError( JaelErrorSeverity.error, - 'Missing expression after operator "${token.span.text}", following expression ${left.span.text}.', + 'Missing expression after operator "${token.span!.text}", following expression ${left!.span!.text}.', token.span)); } return null; @@ -86,10 +86,10 @@ class CallParselet implements InfixParselet { int get precedence => 19; @override - Expression parse(Parser parser, Expression left, Token token) { + Expression? parse(Parser parser, Expression? left, Token? token) { List arguments = []; List namedArguments = []; - Expression argument = parser.parseExpression(0); + Expression? argument = parser.parseExpression(0); while (argument != null) { arguments.add(argument); @@ -98,7 +98,7 @@ class CallParselet implements InfixParselet { argument = parser.parseExpression(0); } - NamedArgument namedArgument = parser.parseNamedArgument(); + NamedArgument? namedArgument = parser.parseNamedArgument(); while (namedArgument != null) { namedArguments.add(namedArgument); @@ -109,7 +109,7 @@ class CallParselet implements InfixParselet { if (!parser.next(TokenType.rParen)) { var lastSpan = arguments.isEmpty ? null : arguments.last.span; - lastSpan ??= token.span; + lastSpan ??= token!.span; parser.errors.add(JaelError(JaelErrorSeverity.error, 'Missing ")" after argument list.', lastSpan)); return null; @@ -126,12 +126,12 @@ class IndexerParselet implements InfixParselet { int get precedence => 19; @override - Expression parse(Parser parser, Expression left, Token token) { + Expression? parse(Parser parser, Expression? left, Token? token) { var indexer = parser.parseExpression(0); if (indexer == null) { parser.errors.add(JaelError( - JaelErrorSeverity.error, 'Missing expression after "[".', left.span)); + JaelErrorSeverity.error, 'Missing expression after "[".', left!.span)); return null; } @@ -152,12 +152,12 @@ class MemberParselet implements InfixParselet { int get precedence => 19; @override - Expression parse(Parser parser, Expression left, Token token) { + Expression? parse(Parser parser, Expression? left, Token? token) { var name = parser.parseIdentifier(); if (name == null) { parser.errors.add(JaelError(JaelErrorSeverity.error, - 'Expected the name of a property following "."', token.span)); + 'Expected the name of a property following "."', token!.span)); return null; } diff --git a/packages/jael/jael/lib/src/text/parselet/parselet.dart b/packages/jael/jael/lib/src/text/parselet/parselet.dart index 2ff22119..72f9e9e9 100644 --- a/packages/jael/jael/lib/src/text/parselet/parselet.dart +++ b/packages/jael/jael/lib/src/text/parselet/parselet.dart @@ -6,10 +6,10 @@ part 'infix.dart'; part 'prefix.dart'; abstract class PrefixParselet { - Expression parse(Parser parser, Token token); + Expression? parse(Parser parser, Token? token); } abstract class InfixParselet { int get precedence; - Expression parse(Parser parser, Expression left, Token token); + Expression? parse(Parser parser, Expression? left, Token? token); } diff --git a/packages/jael/jael/lib/src/text/parselet/prefix.dart b/packages/jael/jael/lib/src/text/parselet/prefix.dart index cea9bb49..ada46bcc 100644 --- a/packages/jael/jael/lib/src/text/parselet/prefix.dart +++ b/packages/jael/jael/lib/src/text/parselet/prefix.dart @@ -16,12 +16,12 @@ class NotParselet implements PrefixParselet { const NotParselet(); @override - Expression parse(Parser parser, Token token) { + Expression parse(Parser parser, Token? token) { var expression = parser.parseExpression(0); if (expression == null) { parser.errors.add(JaelError(JaelErrorSeverity.error, - 'Missing expression after "!" in negation expression.', token.span)); + 'Missing expression after "!" in negation expression.', token!.span)); } return Negation(token, expression); @@ -32,14 +32,14 @@ class NewParselet implements PrefixParselet { const NewParselet(); @override - Expression parse(Parser parser, Token token) { + Expression? parse(Parser parser, Token? token) { var call = parser.parseExpression(0); if (call == null) { parser.errors.add(JaelError( JaelErrorSeverity.error, '"new" must precede a call expression. Nothing was found.', - call.span)); + call!.span)); return null; } else if (call is Call) { return NewExpression(token, call); @@ -57,31 +57,31 @@ class NumberParselet implements PrefixParselet { const NumberParselet(); @override - Expression parse(Parser parser, Token token) => NumberLiteral(token); + Expression parse(Parser parser, Token? token) => NumberLiteral(token); } class HexParselet implements PrefixParselet { const HexParselet(); @override - Expression parse(Parser parser, Token token) => HexLiteral(token); + Expression parse(Parser parser, Token? token) => HexLiteral(token); } class StringParselet implements PrefixParselet { const StringParselet(); @override - Expression parse(Parser parser, Token token) => - StringLiteral(token, StringLiteral.parseValue(token)); + Expression parse(Parser parser, Token? token) => + StringLiteral(token, StringLiteral.parseValue(token!)); } class ArrayParselet implements PrefixParselet { const ArrayParselet(); @override - Expression parse(Parser parser, Token token) { + Expression? parse(Parser parser, Token? token) { List items = []; - Expression item = parser.parseExpression(0); + Expression? item = parser.parseExpression(0); while (item != null) { items.add(item); @@ -92,7 +92,7 @@ class ArrayParselet implements PrefixParselet { if (!parser.next(TokenType.rBracket)) { var lastSpan = items.isEmpty ? null : items.last.span; - lastSpan ??= token.span; + lastSpan ??= token!.span; parser.errors.add(JaelError(JaelErrorSeverity.error, 'Missing "]" to terminate array literal.', lastSpan)); return null; @@ -106,7 +106,7 @@ class MapParselet implements PrefixParselet { const MapParselet(); @override - Expression parse(Parser parser, Token token) { + Expression? parse(Parser parser, Token? token) { var pairs = []; var pair = parser.parseKeyValuePair(); @@ -118,7 +118,7 @@ class MapParselet implements PrefixParselet { } if (!parser.next(TokenType.rCurly)) { - var lastSpan = pairs.isEmpty ? token.span : pairs.last.span; + var lastSpan = pairs.isEmpty ? token!.span : pairs.last.span; parser.errors.add(JaelError( JaelErrorSeverity.error, 'Missing "}" in map literal.', lastSpan)); return null; @@ -132,19 +132,19 @@ class IdentifierParselet implements PrefixParselet { const IdentifierParselet(); @override - Expression parse(Parser parser, Token token) => Identifier(token); + Expression parse(Parser parser, Token? token) => Identifier(token); } class ParenthesisParselet implements PrefixParselet { const ParenthesisParselet(); @override - Expression parse(Parser parser, Token token) { + Expression? parse(Parser parser, Token? token) { var expression = parser.parseExpression(0); if (expression == null) { parser.errors.add(JaelError(JaelErrorSeverity.error, - 'Missing expression after "(".', token.span)); + 'Missing expression after "(".', token!.span)); return null; } diff --git a/packages/jael/jael/lib/src/text/parser.dart b/packages/jael/jael/lib/src/text/parser.dart index 9225726f..c3c26b9e 100644 --- a/packages/jael/jael/lib/src/text/parser.dart +++ b/packages/jael/jael/lib/src/text/parser.dart @@ -7,12 +7,12 @@ class Parser { final Scanner scanner; final bool asDSX; - Token _current; + Token? _current; int _index = -1; Parser(this.scanner, {this.asDSX = false}); - Token get current => _current; + Token? get current => _current; int _nextPrecedence() { var tok = peek(); @@ -33,12 +33,12 @@ class Parser { return true; } - Token peek() { + Token? peek() { if (_index >= scanner.tokens.length - 1) return null; return scanner.tokens[_index + 1]; } - Token maybe(TokenType type) => next(type) ? _current : null; + Token? maybe(TokenType type) => next(type) ? _current : null; void skipExtraneous(TokenType type) { while (next(type)) { @@ -46,7 +46,7 @@ class Parser { } } - Document parseDocument() { + Document? parseDocument() { var doctype = parseDoctype(); if (doctype == null) { @@ -66,10 +66,10 @@ class Parser { return Document(doctype, root); } - StringLiteral implicitString() { + StringLiteral? implicitString() { if (next(TokenType.string)) { - return prefixParselets[TokenType.string].parse(this, _current) - as StringLiteral; + return prefixParselets[TokenType.string]!.parse(this, _current) + as StringLiteral?; } /*else if (next(TokenType.text)) { @@ -78,7 +78,7 @@ class Parser { return null; } - Doctype parseDoctype() { + Doctype? parseDoctype() { if (!next(TokenType.lt)) return null; var lt = _current; @@ -86,12 +86,12 @@ class Parser { _index--; return null; } - var doctype = _current, html = parseIdentifier(); - if (html?.span?.text?.toLowerCase() != 'html') { + var doctype = _current, html = parseIdentifier() as Token?; + if (html?.span?.text.toLowerCase() != 'html') { errors.add(JaelError( JaelErrorSeverity.error, 'Expected "html" in doctype declaration.', - html?.span ?? doctype.span)); + html?.span ?? doctype!.span)); return null; } @@ -99,18 +99,19 @@ class Parser { if (public == null) { if (!next(TokenType.gt)) { errors.add(JaelError(JaelErrorSeverity.error, - 'Expected ">" in doctype declaration.', html.span)); + 'Expected ">" in doctype declaration.', html!.span)); return null; } - return Doctype(lt, doctype, html, null, null, null, _current); + return Doctype( + lt, doctype, html as Identifier?, null, null, null, _current); } - if (public?.span?.text?.toLowerCase() != 'public') { + if (public.span?.text.toLowerCase() != 'public') { errors.add(JaelError( JaelErrorSeverity.error, 'Expected "public" in doctype declaration.', - public?.span ?? html.span)); + public.span ?? html!.span)); return null; } @@ -122,37 +123,38 @@ class Parser { return null; } - var name = stringParser.parse(this, _current) as StringLiteral; + var name = stringParser!.parse(this, _current) as StringLiteral?; if (!next(TokenType.string)) { errors.add(JaelError(JaelErrorSeverity.error, - 'Expected string in doctype declaration.', name.span)); + 'Expected string in doctype declaration.', name!.span)); return null; } - var url = stringParser.parse(this, _current) as StringLiteral; + var url = stringParser.parse(this, _current) as StringLiteral?; if (!next(TokenType.gt)) { errors.add(JaelError(JaelErrorSeverity.error, - 'Expected ">" in doctype declaration.', url.span)); + 'Expected ">" in doctype declaration.', url!.span)); return null; } - return Doctype(lt, doctype, html, public, name, url, _current); + return Doctype( + lt, doctype, html as Identifier?, public, name, url, _current); } - ElementChild parseElementChild() => + ElementChild? parseElementChild() => parseHtmlComment() ?? parseInterpolation() ?? parseText() ?? parseElement(); - HtmlComment parseHtmlComment() => + HtmlComment? parseHtmlComment() => next(TokenType.htmlComment) ? HtmlComment(_current) : null; - Text parseText() => next(TokenType.text) ? Text(_current) : null; + Text? parseText() => next(TokenType.text) ? Text(_current) : null; - Interpolation parseInterpolation() { + Interpolation? parseInterpolation() { if (!next(asDSX ? TokenType.lCurly : TokenType.lDoubleCurly)) return null; var doubleCurlyL = _current; @@ -160,7 +162,7 @@ class Parser { if (expression == null) { errors.add(JaelError(JaelErrorSeverity.error, - 'Missing expression in interpolation.', doubleCurlyL.span)); + 'Missing expression in interpolation.', doubleCurlyL!.span)); return null; } @@ -174,7 +176,7 @@ class Parser { return Interpolation(doubleCurlyL, expression, _current); } - Element parseElement() { + Element? parseElement() { if (!next(TokenType.lt)) return null; var lt = _current; @@ -188,11 +190,11 @@ class Parser { if (tagName == null) { errors.add( - JaelError(JaelErrorSeverity.error, 'Missing tag name.', lt.span)); + JaelError(JaelErrorSeverity.error, 'Missing tag name.', lt!.span)); return null; } - List attributes = []; + var attributes = []; var attribute = parseAttribute(); while (attribute != null) { @@ -206,7 +208,7 @@ class Parser { if (!next(TokenType.gt)) { errors.add(JaelError(JaelErrorSeverity.error, - 'Missing ">" in self-closing "${tagName.name}" tag.', slash.span)); + 'Missing ">" in self-closing "${tagName.name}" tag.', slash!.span)); return null; } @@ -228,7 +230,7 @@ class Parser { return SelfClosingElement(lt, tagName, attributes, null, gt); } - List children = []; + var children = []; var child = parseElementChild(); while (child != null) { @@ -250,25 +252,26 @@ class Parser { if (!next(TokenType.slash)) { errors.add(JaelError(JaelErrorSeverity.error, - 'Missing "/" in "${tagName.name}" closing tag.', lt2.span)); + 'Missing "/" in "${tagName.name}" closing tag.', lt2!.span)); return null; } - var slash = _current, tagName2 = parseIdentifier(); + var slash = _current; + var tagName2 = parseIdentifier(); if (tagName2 == null) { errors.add(JaelError( JaelErrorSeverity.error, 'Missing "${tagName.name}" in "${tagName.name}" closing tag.', - slash.span)); + slash!.span)); return null; } if (tagName2.name != tagName.name) { errors.add(JaelError( JaelErrorSeverity.error, - 'Mismatched closing tags. Expected "${tagName.span.text}"; got "${tagName2.name}" instead.', - lt2.span)); + 'Mismatched closing tags. Expected "${tagName.span!.text}"; got "${tagName2.name}" instead.', + lt2!.span)); return null; } @@ -282,19 +285,19 @@ class Parser { lt, tagName, attributes, gt, children, lt2, slash, tagName2, _current); } - Attribute parseAttribute() { - Identifier id; - StringLiteral string; + Attribute? parseAttribute() { + Identifier? id; + StringLiteral? string; if ((id = parseIdentifier()) != null) { // Nothing } else if (next(TokenType.string)) { - string = StringLiteral(_current, StringLiteral.parseValue(_current)); + string = StringLiteral(_current, StringLiteral.parseValue(_current!)); } else { return null; } - Token equals, nequ; + Token? equals, nequ; if (next(TokenType.equals)) { equals = _current; @@ -309,7 +312,7 @@ class Parser { if (value == null) { errors.add(JaelError(JaelErrorSeverity.error, - 'Missing expression in attribute.', equals?.span ?? nequ.span)); + 'Missing expression in attribute.', equals?.span ?? nequ!.span)); return null; } @@ -329,22 +332,22 @@ class Parser { } errors.add(JaelError(JaelErrorSeverity.error, - 'Missing expression in attribute.', equals?.span ?? nequ.span)); + 'Missing expression in attribute.', equals?.span ?? nequ!.span)); return null; } } - Expression parseExpression(int precedence) { + Expression? parseExpression(int precedence) { // Only consume a token if it could potentially be a prefix parselet for (var type in prefixParselets.keys) { if (next(type)) { - var left = prefixParselets[type].parse(this, _current); + var left = prefixParselets[type]!.parse(this, _current); while (precedence < _nextPrecedence()) { _current = scanner.tokens[++_index]; - if (_current.type == TokenType.slash && + if (_current!.type == TokenType.slash && peek()?.type == TokenType.gt) { // Handle `/>` // @@ -354,11 +357,11 @@ class Parser { return left; } - var infix = infixParselets[_current.type]; + var infix = infixParselets[_current!.type]!; var newLeft = infix.parse(this, left, _current); if (newLeft == null) { - if (_current.type == TokenType.gt) _index--; + if (_current!.type == TokenType.gt) _index--; return left; } left = newLeft; @@ -372,27 +375,27 @@ class Parser { return null; } - Identifier parseIdentifier() => + Identifier? parseIdentifier() => next(TokenType.id) ? Identifier(_current) : null; - KeyValuePair parseKeyValuePair() { + KeyValuePair? parseKeyValuePair() { var key = parseExpression(0); if (key == null) return null; if (!next(TokenType.colon)) return KeyValuePair(key, null, null); - var colon = _current, value = parseExpression(0); + var colon = _current, value = parseExpression(0) as Token?; if (value == null) { errors.add(JaelError(JaelErrorSeverity.error, - 'Missing expression in key-value pair.', colon.span)); + 'Missing expression in key-value pair.', colon!.span)); return null; } - return KeyValuePair(key, colon, value); + return KeyValuePair(key, colon, value as Expression?); } - NamedArgument parseNamedArgument() { + NamedArgument? parseNamedArgument() { var name = parseIdentifier(); if (name == null) return null; @@ -402,14 +405,14 @@ class Parser { return null; } - var colon = _current, value = parseExpression(0); + var colon = _current, value = parseExpression(0) as Token?; if (value == null) { errors.add(JaelError(JaelErrorSeverity.error, - 'Missing expression in named argument.', colon.span)); + 'Missing expression in named argument.', colon!.span)); return null; } - return NamedArgument(name, colon, value); + return NamedArgument(name, colon, value as Expression); } } diff --git a/packages/jael/jael/lib/src/text/scanner.dart b/packages/jael/jael/lib/src/text/scanner.dart index 964368ae..24f26e3d 100644 --- a/packages/jael/jael/lib/src/text/scanner.dart +++ b/packages/jael/jael/lib/src/text/scanner.dart @@ -85,44 +85,44 @@ class _Scanner implements Scanner { final List errors = []; final List tokens = []; _ScannerState state = _ScannerState.html; - final Queue openTags = Queue(); + final Queue openTags = Queue(); - SpanScanner _scanner; + SpanScanner? _scanner; _Scanner(String text, sourceUrl) { _scanner = SpanScanner(text, sourceUrl: sourceUrl); } void scan({bool asDSX = false}) { - while (!_scanner.isDone) { + while (!_scanner!.isDone) { if (state == _ScannerState.html) { scanHtml(asDSX); } else if (state == _ScannerState.freeText) { // Just keep parsing until we hit " b.span.length.compareTo(a.span.length)); + potential.sort((a, b) => b.span!.length.compareTo(a.span!.length)); if (potential.isEmpty) break; var token = potential.first; tokens.add(token); - _scanner.scan(token.span.text); + _scanner!.scan(token.span!.text); if (token.type == TokenType.lt) { brackets.addFirst(token); // Try to see if we are at a tag. - var replay = _scanner.state; - _scanner.scan(_whitespace); + var replay = _scanner!.state; + _scanner!.scan(_whitespace); - if (_scanner.matches(_id)) { - openTags.addFirst(_scanner.lastMatch[0]); + if (_scanner!.matches(_id)) { + openTags.addFirst(_scanner!.lastMatch![0]); } else { - _scanner.state = replay; + _scanner!.state = replay; } } else if (token.type == TokenType.slash) { // Only push if we're at , try to parse text? brackets.removeFirst(); - var replay = _scanner.state; - _scanner.scan(_whitespace); + var replay = _scanner!.state; + _scanner!.scan(_whitespace); - if (!_scanner.matches('<')) { - _scanner.state = replay; + if (!_scanner!.matches('<')) { + _scanner!.state = replay; state = _ScannerState.freeText; break; } @@ -258,7 +259,7 @@ class _Scanner implements Scanner { potential.clear(); } } - } while (brackets.isNotEmpty && !_scanner.isDone); + } while (brackets.isNotEmpty && !_scanner!.isDone); state = _ScannerState.freeText; } diff --git a/packages/jael/jael/pubspec.yaml b/packages/jael/jael/pubspec.yaml index 3fcb164e..3b2f9fda 100644 --- a/packages/jael/jael/pubspec.yaml +++ b/packages/jael/jael/pubspec.yaml @@ -3,15 +3,25 @@ version: 3.0.0 description: A simple server-side HTML templating engine for Dart. Comparable to Blade or Liquid. author: Tobe O homepage: https://docs.angel-dart.dev/packages/front-end/jael +publish_to: none environment: - sdk: '>=2.10.0 <3.0.0' + sdk: '>=2.12.0 <3.0.0' dependencies: args: ^2.0.0 charcode: ^1.0.0 - code_buffer: ^1.0.0 + code_buffer: + git: + url: https://github.com/dukefirehawk/angel.git + ref: sdk-2.12.x_nnbd + path: packages/code_buffer source_span: ^1.0.0 string_scanner: ^1.0.0 - symbol_table: ^2.0.0 + symbol_table: + git: + url: https://github.com/dukefirehawk/angel.git + ref: sdk-2.12.x_nnbd + path: packages/symbol_table + collection: ^1.15.0-nullsafety.4 dev_dependencies: pedantic: ^1.0.0 test: ^1.0.0 diff --git a/packages/jael/jael/test/render/custom_element_test.dart b/packages/jael/jael/test/render/custom_element_test.dart index 303c1627..489d506b 100644 --- a/packages/jael/jael/test/render/custom_element_test.dart +++ b/packages/jael/jael/test/render/custom_element_test.dart @@ -105,8 +105,8 @@ void main() { }); } -String render(String template, [Map values]) { - var doc = jael.parseDocument(template, onError: (e) => throw e); +String render(String template, [Map values = const {}]) { + var doc = jael.parseDocument(template, onError: (e) => throw e)!; var buffer = CodeBuffer(); const jael.Renderer().render(doc, buffer, SymbolTable(values: values)); return buffer.toString(); diff --git a/packages/jael/jael/test/render/dsx_test.dart b/packages/jael/jael/test/render/dsx_test.dart index 8c47ed7f..607e3deb 100644 --- a/packages/jael/jael/test/render/dsx_test.dart +++ b/packages/jael/jael/test/render/dsx_test.dart @@ -6,18 +6,18 @@ void main() { test('attributes', () { var doc = parseDSX(''' - '''); + ''')!; var foo = doc.root as SelfClosingElement; expect(foo.tagName.name, 'foo'); expect(foo.attributes, hasLength(2)); expect(foo.getAttribute('bar'), isNotNull); expect(foo.getAttribute('yes'), isNotNull); - expect(foo.getAttribute('bar').value.compute(null), 'baz'); + expect(foo.getAttribute('bar')?.value?.compute(null), 'baz'); expect( foo - .getAttribute('yes') - .value + .getAttribute('yes')! + .value! .compute(SymbolTable(values: {'no': 'maybe'})), 'maybe'); }); @@ -27,7 +27,7 @@ void main() { {24 * 3} - '''); + ''')!; var bar = doc.root.children.first as RegularElement; expect(bar.tagName.name, 'bar'); @@ -37,7 +37,7 @@ void main() { }); } -Document parseDSX(String text) { +Document? parseDSX(String text) { return parseDocument(text, sourceUrl: 'test.dsx', asDSX: true, onError: (e) => throw e); } diff --git a/packages/jael/jael/test/render/render_test.dart b/packages/jael/jael/test/render/render_test.dart index b9a60e07..504a9c2f 100644 --- a/packages/jael/jael/test/render/render_test.dart +++ b/packages/jael/jael/test/render/render_test.dart @@ -16,8 +16,8 @@ main() { '''; var buf = CodeBuffer(); - jael.Document document; - SymbolTable scope; + jael.Document? document; + late SymbolTable scope; try { document = jael.parseDocument(template, sourceUrl: 'test.jael'); @@ -33,7 +33,7 @@ main() { } expect(document, isNotNull); - const jael.Renderer().render(document, buf, scope); + const jael.Renderer().render(document!, buf, scope); print(buf); expect( @@ -66,7 +66,7 @@ main() { var buf = CodeBuffer(); //jael.scan(template, sourceUrl: 'test.jael').tokens.forEach(print); - var document = jael.parseDocument(template, sourceUrl: 'test.jael'); + var document = jael.parseDocument(template, sourceUrl: 'test.jael')!; var scope = SymbolTable(values: { 'pokemon': const _Pokemon('Darkrai', 'Dark'), }); @@ -106,7 +106,7 @@ main() { '''; var buf = CodeBuffer(); - var document = jael.parseDocument(template, sourceUrl: 'test.jael'); + var document = jael.parseDocument(template, sourceUrl: 'test.jael')!; var scope = SymbolTable(values: { 'starters': starters, }); @@ -151,7 +151,7 @@ main() { '''; var buf = CodeBuffer(); - var document = jael.parseDocument(template, sourceUrl: 'test.jael'); + var document = jael.parseDocument(template, sourceUrl: 'test.jael')!; var scope = SymbolTable(values: { 'starters': starters, }); @@ -197,7 +197,7 @@ main() { '''; var buf = CodeBuffer(); - var document = jael.parseDocument(template, sourceUrl: 'test.jael'); + var document = jael.parseDocument(template, sourceUrl: 'test.jael')!; var scope = SymbolTable(); const jael.Renderer().render(document, buf, scope); @@ -243,7 +243,7 @@ main() { '''; var buf = CodeBuffer(); - var document = jael.parseDocument(template, sourceUrl: 'test.jael'); + var document = jael.parseDocument(template, sourceUrl: 'test.jael')!; var scope = SymbolTable(); const jael.Renderer().render(document, buf, scope); @@ -268,7 +268,7 @@ main() { '''; var buf = CodeBuffer(); - var document = jael.parseDocument(template, sourceUrl: 'test.jael'); + var document = jael.parseDocument(template, sourceUrl: 'test.jael')!; var scope = SymbolTable(); const jael.Renderer().render(document, buf, scope); @@ -299,7 +299,7 @@ main() { '''; var buf = CodeBuffer(); - var document = jael.parseDocument(template, sourceUrl: 'test.jael'); + var document = jael.parseDocument(template, sourceUrl: 'test.jael')!; var scope = SymbolTable(values: { 'account': _Account(isDisabled: true), }); @@ -326,7 +326,7 @@ main() { '''; var buf = CodeBuffer(); - var document = jael.parseDocument(template, sourceUrl: 'test.jael'); + var document = jael.parseDocument(template, sourceUrl: 'test.jael')!; var scope = SymbolTable(values: { 'account': _Account(isDisabled: null), }); @@ -351,7 +351,7 @@ class _Pokemon { } class _Account { - final bool isDisabled; + final bool? isDisabled; _Account({this.isDisabled}); } diff --git a/packages/jael/jael/test/text/common.dart b/packages/jael/jael/test/text/common.dart index 5fb71587..fa17e560 100644 --- a/packages/jael/jael/test/text/common.dart +++ b/packages/jael/jael/test/text/common.dart @@ -1,11 +1,11 @@ import 'package:matcher/matcher.dart'; import 'package:jael/src/ast/token.dart'; -Matcher isToken(TokenType type, [String text]) => _IsToken(type, text); +Matcher isToken(TokenType type, [String? text]) => _IsToken(type, text); class _IsToken extends Matcher { final TokenType type; - final String text; + final String? text; _IsToken(this.type, [this.text]); @@ -19,6 +19,6 @@ class _IsToken extends Matcher { bool matches(item, Map matchState) { return item is Token && item.type == type && - (text == null || item.span.text == text); + (text == null || item.span!.text == text); } } diff --git a/packages/symbol_table/pubspec.yaml b/packages/symbol_table/pubspec.yaml index 0c605c46..db526ea4 100644 --- a/packages/symbol_table/pubspec.yaml +++ b/packages/symbol_table/pubspec.yaml @@ -1,8 +1,9 @@ name: symbol_table -version: 2.0.0 +version: 3.0.0 description: A generic symbol table implementation in Dart, with support for scopes and constants. author: Tobe O homepage: https://github.com/thosakwe/symbol_table +publish_to: none environment: sdk: '>=2.12.0 <3.0.0' dependencies: