[dart2js] Enforce recommended lints in pkg/js_ast

Enforcing these lints helps reduce the diffs with the forked version
in pkg/dev_compiler/lib/src/js_ast.

Enforce extra lints:
- always_declare_return_types
- depend_on_referenced_packages
- directives_ordering
- prefer_single_quotes
- prefer_relative_imports

Add ignores for:
- avoid_function_literals_in_foreach_calls
- avoid_renaming_method_parameters
- constant_identifier_names
- non_constant_identifier_names
- prefer_void_to_null

Change-Id: I6b96eca51fdb698927569df538d1db1bf07498cd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/239325
Reviewed-by: Stephen Adams <sra@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
This commit is contained in:
Nicholas Shahan 2022-04-01 18:26:01 +00:00 committed by Commit Bot
parent 8fb5b2b02f
commit 10656e3dcd
12 changed files with 494 additions and 453 deletions

View file

@ -2,15 +2,24 @@
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
include: package:lints/recommended.yaml
analyzer:
errors:
todo: ignore
avoid_function_literals_in_foreach_calls: ignore
avoid_renaming_method_parameters: ignore
# Allow deprecated calls from within the same package
deprecated_member_use_from_same_package: ignore
constant_identifier_names: ignore
non_constant_identifier_names: ignore
prefer_void_to_null: ignore
linter:
rules:
- annotate_overrides
- prefer_final_fields
- prefer_if_null_operators
- prefer_null_aware_operators
# Not enforced by the lints package at any version.
- always_declare_return_types
- depend_on_referenced_packages
- directives_ordering
- prefer_single_quotes
- prefer_relative_imports

View file

@ -6,8 +6,8 @@
library js_ast;
export 'src/nodes.dart';
export 'src/builder.dart';
export 'src/equivalence_visitor.dart';
export 'src/nodes.dart';
export 'src/printer.dart';
export 'src/template.dart';
export 'src/equivalence_visitor.dart';

View file

@ -8,7 +8,7 @@
/// parser that parses part of the language.
library js_ast.builder;
import 'characters.dart' as charCodes;
import 'characters.dart' as char_codes;
import 'nodes.dart';
import 'template.dart';
@ -135,7 +135,7 @@ TemplateManager templateManager = TemplateManager();
/// blocks to be appended.
///
/// var b1 = js.statement('{ 1; 2; }');
/// var sEmpty = new Emptystatement();
/// var sEmpty = new EmptyStatement();
/// js.statement('{ #; #; #; #; }', [sEmpty, b1, b1, sEmpty])
/// -->
/// { 1; 2; 1; 2; }
@ -223,7 +223,7 @@ class JsBuilder {
// TODO(sra): Parse with extra validation to forbid `#` interpolation in
// functions, as this leads to unanticipated capture of temporaries that are
// reused after capture.
if (source.startsWith("throw ")) {
if (source.startsWith('throw ')) {
return _findStatementTemplate(source);
} else {
return _findExpressionTemplate(source);
@ -358,7 +358,7 @@ ObjectInitializer objectLiteral(Map<String, Expression> map) {
}
class MiniJsParserError {
MiniJsParserError(this.parser, this.message) {}
MiniJsParserError(this.parser, this.message);
final MiniJsParser parser;
final String message;
@ -381,7 +381,7 @@ class MiniJsParserError {
// Replace non-tabs with spaces, giving a print indent that matches the text
// for tabbing.
String spaces = prefix.replaceAll(RegExp(r'[^\t]'), ' ');
return 'Error in MiniJsParser:\n${src}\n$spaces^\n$spaces$message\n';
return 'Error in MiniJsParser:\n$src\n$spaces^\n$spaces$message\n';
}
}
@ -454,49 +454,49 @@ class MiniJsParser {
static String categoryToString(int cat) {
switch (cat) {
case NONE:
return "NONE";
return 'NONE';
case ALPHA:
return "ALPHA";
return 'ALPHA';
case NUMERIC:
return "NUMERIC";
return 'NUMERIC';
case SYMBOL:
return "SYMBOL";
return 'SYMBOL';
case ASSIGNMENT:
return "ASSIGNMENT";
return 'ASSIGNMENT';
case DOT:
return "DOT";
return 'DOT';
case LPAREN:
return "LPAREN";
return 'LPAREN';
case RPAREN:
return "RPAREN";
return 'RPAREN';
case LBRACE:
return "LBRACE";
return 'LBRACE';
case RBRACE:
return "RBRACE";
return 'RBRACE';
case LSQUARE:
return "LSQUARE";
return 'LSQUARE';
case RSQUARE:
return "RSQUARE";
return 'RSQUARE';
case STRING:
return "STRING";
return 'STRING';
case COMMA:
return "COMMA";
return 'COMMA';
case QUERY:
return "QUERY";
return 'QUERY';
case COLON:
return "COLON";
return 'COLON';
case SEMICOLON:
return "SEMICOLON";
return 'SEMICOLON';
case ARROW:
return "ARROW";
return 'ARROW';
case HASH:
return "HASH";
return 'HASH';
case WHITESPACE:
return "WHITESPACE";
return 'WHITESPACE';
case OTHER:
return "OTHER";
return 'OTHER';
}
return "Unknown: $cat";
return 'Unknown: $cat';
}
static const CATEGORIES = <int>[
@ -595,16 +595,16 @@ class MiniJsParser {
int currentCode;
do {
position++;
if (position >= src.length) error("Unterminated literal");
if (position >= src.length) error('Unterminated literal');
currentCode = src.codeUnitAt(position);
if (currentCode == charCodes.$LF) error("Unterminated literal");
if (currentCode == charCodes.$BACKSLASH) {
if (++position >= src.length) error("Unterminated literal");
if (currentCode == char_codes.$LF) error('Unterminated literal');
if (currentCode == char_codes.$BACKSLASH) {
if (++position >= src.length) error('Unterminated literal');
int escaped = src.codeUnitAt(position);
if (escaped == charCodes.$x ||
escaped == charCodes.$X ||
escaped == charCodes.$u ||
escaped == charCodes.$U ||
if (escaped == char_codes.$x ||
escaped == char_codes.$X ||
escaped == char_codes.$u ||
escaped == char_codes.$U ||
category(escaped) == NUMERIC) {
error('Numeric and hex escapes are not supported in RegExp literals');
}
@ -619,30 +619,30 @@ class MiniJsParser {
position = startPosition + 1;
final value = StringBuffer();
while (true) {
if (position >= src.length) error("Unterminated literal");
if (position >= src.length) error('Unterminated literal');
int code = src.codeUnitAt(position++);
if (code == quote) break;
if (code == charCodes.$LF) error("Unterminated literal");
if (code == charCodes.$BACKSLASH) {
if (position >= src.length) error("Unterminated literal");
if (code == char_codes.$LF) error('Unterminated literal');
if (code == char_codes.$BACKSLASH) {
if (position >= src.length) error('Unterminated literal');
code = src.codeUnitAt(position++);
if (code == charCodes.$f) {
if (code == char_codes.$f) {
value.writeCharCode(12);
} else if (code == charCodes.$n) {
} else if (code == char_codes.$n) {
value.writeCharCode(10);
} else if (code == charCodes.$r) {
} else if (code == char_codes.$r) {
value.writeCharCode(13);
} else if (code == charCodes.$t) {
} else if (code == char_codes.$t) {
value.writeCharCode(8);
} else if (code == charCodes.$BACKSLASH ||
code == charCodes.$SQ ||
code == charCodes.$DQ) {
} else if (code == char_codes.$BACKSLASH ||
code == char_codes.$SQ ||
code == char_codes.$DQ) {
value.writeCharCode(code);
} else if (code == charCodes.$x || code == charCodes.$X) {
} else if (code == char_codes.$x || code == char_codes.$X) {
error('Hex escapes not supported in string literals');
} else if (code == charCodes.$u || code == charCodes.$U) {
} else if (code == char_codes.$u || code == char_codes.$U) {
error('Unicode escapes not supported in string literals');
} else if (charCodes.$0 <= code && code <= charCodes.$9) {
} else if (char_codes.$0 <= code && code <= char_codes.$9) {
error('Numeric escapes not supported in string literals');
} else {
error('Unknown escape U+${code.toRadixString(16).padLeft(4, '0')}');
@ -660,13 +660,13 @@ class MiniJsParser {
if (position >= src.length) break;
int code = src.codeUnitAt(position);
// Skip '//' and '/*' style comments.
if (code == charCodes.$SLASH && position + 1 < src.length) {
if (src.codeUnitAt(position + 1) == charCodes.$SLASH) {
if (code == char_codes.$SLASH && position + 1 < src.length) {
if (src.codeUnitAt(position + 1) == char_codes.$SLASH) {
int nextPosition = src.indexOf('\n', position);
if (nextPosition == -1) nextPosition = src.length;
position = nextPosition;
continue;
} else if (src.codeUnitAt(position + 1) == charCodes.$STAR) {
} else if (src.codeUnitAt(position + 1) == char_codes.$STAR) {
int nextPosition = src.indexOf('*/', position + 2);
if (nextPosition == -1) error('Unterminated comment');
position = nextPosition + 2;
@ -674,7 +674,7 @@ class MiniJsParser {
}
}
if (category(code) != WHITESPACE) break;
if (code == charCodes.$LF) skippedNewline = true;
if (code == char_codes.$LF) skippedNewline = true;
++position;
}
@ -686,13 +686,13 @@ class MiniJsParser {
}
int code = src.codeUnitAt(position);
lastPosition = position;
if (code == charCodes.$SQ || code == charCodes.$DQ) {
if (code == char_codes.$SQ || code == char_codes.$DQ) {
// String literal.
lastCategory = STRING;
lastToken = getString(position, code);
} else if (code == charCodes.$0 &&
} else if (code == char_codes.$0 &&
position + 2 < src.length &&
src.codeUnitAt(position + 1) == charCodes.$x) {
src.codeUnitAt(position + 1) == char_codes.$x) {
// Hex literal.
for (position += 2; position < src.length; position++) {
int cat = category(src.codeUnitAt(position));
@ -701,13 +701,13 @@ class MiniJsParser {
lastCategory = NUMERIC;
lastToken = src.substring(lastPosition, position);
if (int.tryParse(lastToken) == null) {
error("Unparseable number");
error('Unparseable number');
}
} else if (code == charCodes.$SLASH) {
} else if (code == char_codes.$SLASH) {
// Tokens that start with / are special due to regexp literals.
lastCategory = SYMBOL;
position++;
if (position < src.length && src.codeUnitAt(position) == charCodes.$EQ) {
if (position < src.length && src.codeUnitAt(position) == char_codes.$EQ) {
position++;
}
lastToken = src.substring(lastPosition, position);
@ -722,9 +722,9 @@ class MiniJsParser {
// Special code to disallow !, ~ and / in non-first position in token,
// so that !! and ~~ parse as two tokens and != parses as one, while =/
// parses as a an equals token followed by a regexp literal start.
newCat = (code == charCodes.$BANG ||
code == charCodes.$SLASH ||
code == charCodes.$TILDE)
newCat = (code == char_codes.$BANG ||
code == char_codes.$SLASH ||
code == char_codes.$TILDE)
? NONE
: category(code);
} while (!singleCharCategory(cat) &&
@ -735,7 +735,7 @@ class MiniJsParser {
lastToken = src.substring(lastPosition, position);
if (cat == NUMERIC) {
if (double.tryParse(lastToken) == null) {
error("Unparseable number");
error('Unparseable number');
}
} else if (cat == SYMBOL) {
if (lastToken == '=>') {
@ -744,7 +744,7 @@ class MiniJsParser {
int? binaryPrecedence = BINARY_PRECEDENCE[lastToken];
if (binaryPrecedence == null &&
!UNARY_OPERATORS.contains(lastToken)) {
error("Unknown operator");
error('Unknown operator');
}
if (isAssignment(lastToken)) lastCategory = ASSIGNMENT;
}
@ -757,7 +757,7 @@ class MiniJsParser {
}
void expectCategory(int cat) {
if (cat != lastCategory) error("Expected ${categoryToString(cat)}");
if (cat != lastCategory) error('Expected ${categoryToString(cat)}');
getToken();
}
@ -793,12 +793,12 @@ class MiniJsParser {
return false;
}
Never error(message) {
Never error(String message) {
throw MiniJsParserError(this, message);
}
/// Returns either the name for the hole, or its integer position.
parseHash() {
Object parseHash() {
String holeName = lastToken;
if (acceptCategory(ALPHA)) {
// Named hole. Example: 'function #funName() { ... }'
@ -818,15 +818,15 @@ class MiniJsParser {
Expression parsePrimary() {
String last = lastToken;
if (acceptCategory(ALPHA)) {
if (last == "true") {
if (last == 'true') {
return LiteralBool(true);
} else if (last == "false") {
} else if (last == 'false') {
return LiteralBool(false);
} else if (last == "null") {
} else if (last == 'null') {
return LiteralNull();
} else if (last == "function") {
} else if (last == 'function') {
return parseFunctionExpression();
} else if (last == "this") {
} else if (last == 'this') {
return This();
} else {
return VariableUse(last);
@ -852,11 +852,11 @@ class MiniJsParser {
expectCategory(COMMA);
}
return ArrayInitializer(values);
} else if (last.startsWith("/")) {
} else if (last.startsWith('/')) {
String regexp = getRegExp(lastPosition);
getToken();
String flags = lastToken;
if (!acceptCategory(ALPHA)) flags = "";
if (!acceptCategory(ALPHA)) flags = '';
Expression expression = RegExpLiteral(regexp + flags);
return expression;
} else if (acceptCategory(HASH)) {
@ -866,7 +866,7 @@ class MiniJsParser {
interpolatedValues.add(expression);
return expression;
} else {
error("Expected primary expression");
error('Expected primary expression');
}
}
@ -907,7 +907,7 @@ class MiniJsParser {
asyncModifier = AsyncModifier.async;
}
} else if (acceptString('sync')) {
if (!acceptString('*')) error("Only sync* is valid - sync is implied");
if (!acceptString('*')) error('Only sync* is valid - sync is implied');
asyncModifier = AsyncModifier.syncStar;
} else {
asyncModifier = AsyncModifier.sync;
@ -974,7 +974,7 @@ class MiniJsParser {
}
Expression parseCall() {
bool constructor = acceptString("new");
bool constructor = acceptString('new');
Expression receiver = parseMember();
while (true) {
if (acceptCategory(LPAREN)) {
@ -998,7 +998,7 @@ class MiniJsParser {
receiver = getDotRhs(receiver);
} else {
// JS allows new without (), but we don't.
if (constructor) error("Parentheses are required for new");
if (constructor) error('Parentheses are required for new');
break;
}
}
@ -1017,7 +1017,7 @@ class MiniJsParser {
// names, and the IndexedDB API uses that, so we need to allow it here.
if (acceptCategory(SYMBOL)) {
if (!OPERATORS_THAT_LOOK_LIKE_IDENTIFIERS.contains(identifier)) {
error("Expected alphanumeric identifier");
error('Expected alphanumeric identifier');
}
} else {
expectCategory(ALPHA);
@ -1032,7 +1032,7 @@ class MiniJsParser {
// LeftHandSideExpression [no LineTerminator here] ++
if (lastCategory == SYMBOL &&
!skippedNewline &&
(acceptString("++") || acceptString("--"))) {
(acceptString('++') || acceptString('--'))) {
return Postfix(operator, expression);
}
// If we don't accept '++' or '--' due to skippedNewline a newline, no other
@ -1045,8 +1045,8 @@ class MiniJsParser {
String operator = lastToken;
if (lastCategory == SYMBOL &&
UNARY_OPERATORS.contains(operator) &&
(acceptString("++") || acceptString("--") || acceptString('await'))) {
if (operator == "await") return Await(parsePostfix());
(acceptString('++') || acceptString('--') || acceptString('await'))) {
if (operator == 'await') return Await(parsePostfix());
return Prefix(operator, parsePostfix());
}
return parsePostfix();
@ -1056,10 +1056,10 @@ class MiniJsParser {
String operator = lastToken;
if (lastCategory == SYMBOL &&
UNARY_OPERATORS.contains(operator) &&
operator != "++" &&
operator != "--") {
operator != '++' &&
operator != '--') {
expectCategory(SYMBOL);
if (operator == "await") return Await(parsePostfix());
if (operator == 'await') return Await(parsePostfix());
return Prefix(operator, parseUnaryLow());
}
return parseUnaryHigh();
@ -1108,7 +1108,7 @@ class MiniJsParser {
String assignmentOperator = lastToken;
if (acceptCategory(ASSIGNMENT)) {
Expression rhs = parseAssignment();
if (assignmentOperator == "=") {
if (assignmentOperator == '=') {
return Assignment(lhs, rhs);
} else {
// Handle +=, -=, etc.
@ -1147,7 +1147,7 @@ class MiniJsParser {
} else if (e is InterpolatedExpression) {
params.add(InterpolatedParameter(e.nameOrPosition));
} else {
error("Expected arrow function parameter list");
error('Expected arrow function parameter list');
}
}
return parseArrowFunctionBody(params);
@ -1176,8 +1176,8 @@ class MiniJsParser {
var initialization = <VariableInitialization>[];
void declare(Declaration declaration) {
Expression? initializer = null;
if (acceptString("=")) {
Expression? initializer;
if (acceptString('=')) {
initializer = parseAssignment();
}
initialization.add(VariableInitialization(declaration, initializer));
@ -1192,7 +1192,7 @@ class MiniJsParser {
}
Expression parseVarDeclarationOrExpression() {
if (acceptString("var")) {
if (acceptString('var')) {
return parseVariableDeclarationList();
} else {
return parseExpression();
@ -1202,7 +1202,7 @@ class MiniJsParser {
Expression expression() {
Expression expression = parseVarDeclarationOrExpression();
if (lastCategory != NONE || position != src.length) {
error("Unparsed junk: ${categoryToString(lastCategory)}");
error('Unparsed junk: ${categoryToString(lastCategory)}');
}
return expression;
}
@ -1210,7 +1210,7 @@ class MiniJsParser {
Statement statement() {
Statement statement = parseStatement();
if (lastCategory != NONE || position != src.length) {
error("Unparsed junk: ${categoryToString(lastCategory)}");
error('Unparsed junk: ${categoryToString(lastCategory)}');
}
// TODO(sra): interpolated capture here?
return statement;
@ -1264,9 +1264,9 @@ class MiniJsParser {
if (acceptString('switch')) return parseSwitch();
if (lastToken == 'case') error("Case outside switch.");
if (lastToken == 'case') error('Case outside switch.');
if (lastToken == 'default') error("Default outside switch.");
if (lastToken == 'default') error('Default outside switch.');
if (lastToken == 'yield') return parseYield();
@ -1353,12 +1353,12 @@ class MiniJsParser {
// for (var variable in Expression) Statement
//
Statement finishFor(Expression? init) {
Expression? condition = null;
Expression? condition;
if (!acceptCategory(SEMICOLON)) {
condition = parseExpression();
expectCategory(SEMICOLON);
}
Expression? update = null;
Expression? update;
if (!acceptCategory(RPAREN)) {
update = parseExpression();
expectCategory(RPAREN);
@ -1417,9 +1417,9 @@ class MiniJsParser {
Statement parseTry() {
expectCategory(LBRACE);
Block body = parseBlock();
Catch? catchPart = null;
Catch? catchPart;
if (acceptString('catch')) catchPart = parseCatch();
Block? finallyPart = null;
Block? finallyPart;
if (acceptString('finally')) {
expectCategory(LBRACE);
finallyPart = parseBlock();
@ -1430,7 +1430,7 @@ class MiniJsParser {
}
SwitchClause parseSwitchClause() {
Expression? expression = null;
Expression? expression;
if (acceptString('case')) {
expression = parseExpression();
expectCategory(COLON);
@ -1461,7 +1461,7 @@ class MiniJsParser {
Statement parseDo() {
Statement body = parseStatement();
if (lastToken != "while") error("Missing while after do body.");
if (lastToken != 'while') error('Missing while after do body.');
getToken();
expectCategory(LPAREN);
Expression condition = parseExpression();

View file

@ -556,7 +556,7 @@ class BaseVisitor1Void<A> extends BaseVisitor1<void, A> {
void visitComment(Comment node, A arg) {}
}
/// This tag interface has no behaviour but must be implemented by any class
/// This tag interface has no behavior but must be implemented by any class
/// that is to be stored on a [Node] as source information.
abstract class JavaScriptNodeSourceInformation {
const JavaScriptNodeSourceInformation();
@ -627,12 +627,16 @@ class Program extends Node {
@override
void visitChildren<T>(NodeVisitor<T> visitor) {
for (Statement statement in body) statement.accept(visitor);
for (Statement statement in body) {
statement.accept(visitor);
}
}
@override
void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
for (Statement statement in body) statement.accept1(visitor, arg);
for (Statement statement in body) {
statement.accept1(visitor, arg);
}
}
@override
@ -672,7 +676,7 @@ class Block extends Statement {
Block(this.statements);
Block.empty() : this.statements = [];
Block.empty() : statements = [];
@override
T accept<T>(NodeVisitor<T> visitor) => visitor.visitBlock(this);
@ -683,12 +687,16 @@ class Block extends Statement {
@override
void visitChildren<T>(NodeVisitor<T> visitor) {
for (Statement statement in statements) statement.accept(visitor);
for (Statement statement in statements) {
statement.accept(visitor);
}
}
@override
void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
for (Statement statement in statements) statement.accept1(visitor, arg);
for (Statement statement in statements) {
statement.accept1(visitor, arg);
}
}
@override
@ -748,7 +756,7 @@ class If extends Statement {
If(this.condition, this.then, this.otherwise);
If.noElse(this.condition, this.then) : this.otherwise = EmptyStatement();
If.noElse(this.condition, this.then) : otherwise = EmptyStatement();
bool get hasElse => otherwise is! EmptyStatement;
@ -955,7 +963,7 @@ class Return extends Statement {
/// The expression for `return expression;`, or `null` for `return;`.
final Expression? value;
Return([this.value = null]);
Return([this.value]);
@override
T accept<T>(NodeVisitor<T> visitor) => visitor.visitReturn(this);
@ -1083,13 +1091,17 @@ class Switch extends Statement {
@override
void visitChildren<T>(NodeVisitor<T> visitor) {
key.accept(visitor);
for (SwitchClause clause in cases) clause.accept(visitor);
for (SwitchClause clause in cases) {
clause.accept(visitor);
}
}
@override
void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
key.accept1(visitor, arg);
for (SwitchClause clause in cases) clause.accept1(visitor, arg);
for (SwitchClause clause in cases) {
clause.accept1(visitor, arg);
}
}
@override
@ -1545,7 +1557,7 @@ class Call extends Expression {
Call(this.target, this.arguments,
{JavaScriptNodeSourceInformation? sourceInformation}) {
this._sourceInformation = sourceInformation;
_sourceInformation = sourceInformation;
}
@override
@ -1628,43 +1640,43 @@ class Binary extends Expression {
int get precedenceLevel {
// TODO(floitsch): switch to constant map.
switch (op) {
case "*":
case "/":
case "%":
case '*':
case '/':
case '%':
return MULTIPLICATIVE;
case "+":
case "-":
case '+':
case '-':
return ADDITIVE;
case "<<":
case ">>":
case ">>>":
case '<<':
case '>>':
case '>>>':
return SHIFT;
case "<":
case ">":
case "<=":
case ">=":
case "instanceof":
case "in":
case '<':
case '>':
case '<=':
case '>=':
case 'instanceof':
case 'in':
return RELATIONAL;
case "==":
case "===":
case "!=":
case "!==":
case '==':
case '===':
case '!=':
case '!==':
return EQUALITY;
case "&":
case '&':
return BIT_AND;
case "^":
case '^':
return BIT_XOR;
case "|":
case '|':
return BIT_OR;
case "&&":
case '&&':
return LOGICAL_AND;
case "||":
case '||':
return LOGICAL_OR;
case ',':
return EXPRESSION;
default:
throw "Internal Error: Unhandled binary operator: $op";
throw 'Internal Error: Unhandled binary operator: $op';
}
}
}
@ -1799,7 +1811,7 @@ class Parameter extends VariableDeclaration {
}
class This extends Parameter {
This() : super("this");
This() : super('this');
@override
T accept<T>(NodeVisitor<T> visitor) => visitor.visitThis(this);
@ -1869,13 +1881,17 @@ class Fun extends FunctionExpression {
@override
void visitChildren<T>(NodeVisitor<T> visitor) {
for (Parameter param in params) param.accept(visitor);
for (Parameter param in params) {
param.accept(visitor);
}
body.accept(visitor);
}
@override
void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
for (Parameter param in params) param.accept1(visitor, arg);
for (Parameter param in params) {
param.accept1(visitor, arg);
}
body.accept1(visitor, arg);
}
@ -1911,13 +1927,17 @@ class ArrowFunction extends FunctionExpression {
@override
void visitChildren<T>(NodeVisitor<T> visitor) {
for (Parameter param in params) param.accept(visitor);
for (Parameter param in params) {
param.accept(visitor);
}
body.accept(visitor);
}
@override
void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
for (Parameter param in params) param.accept1(visitor, arg);
for (Parameter param in params) {
param.accept1(visitor, arg);
}
body.accept1(visitor, arg);
}
@ -1940,13 +1960,13 @@ class AsyncModifier {
{required this.isAsync, required this.isYielding});
static const AsyncModifier sync =
AsyncModifier(0, "sync", isAsync: false, isYielding: false);
AsyncModifier(0, 'sync', isAsync: false, isYielding: false);
static const AsyncModifier async =
AsyncModifier(1, "async", isAsync: true, isYielding: false);
AsyncModifier(1, 'async', isAsync: true, isYielding: false);
static const AsyncModifier asyncStar =
AsyncModifier(2, "async*", isAsync: true, isYielding: true);
AsyncModifier(2, 'async*', isAsync: true, isYielding: true);
static const AsyncModifier syncStar =
AsyncModifier(3, "sync*", isAsync: false, isYielding: true);
AsyncModifier(3, 'sync*', isAsync: false, isYielding: true);
static const List<AsyncModifier> values = [sync, async, asyncStar, syncStar];
@ -2159,16 +2179,20 @@ class StringConcatenation extends Literal {
@override
void visitChildren<T>(NodeVisitor<T> visitor) {
for (Literal part in parts) part.accept(visitor);
for (Literal part in parts) {
part.accept(visitor);
}
}
@override
void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
for (Literal part in parts) part.accept1(visitor, arg);
for (Literal part in parts) {
part.accept1(visitor, arg);
}
}
@override
StringConcatenation _clone() => StringConcatenation(this.parts);
StringConcatenation _clone() => StringConcatenation(parts);
}
class LiteralNumber extends Literal {
@ -2204,12 +2228,16 @@ class ArrayInitializer extends Expression {
@override
void visitChildren<T>(NodeVisitor<T> visitor) {
for (Expression element in elements) element.accept(visitor);
for (Expression element in elements) {
element.accept(visitor);
}
}
@override
void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
for (Expression element in elements) element.accept1(visitor, arg);
for (Expression element in elements) {
element.accept1(visitor, arg);
}
}
@override
@ -2248,9 +2276,9 @@ class ObjectInitializer extends Expression {
/// Constructs a new object-initializer containing the given [properties].
///
/// [isOneLiner] describes the behaviour when pretty-printing (non-minified).
/// [isOneLiner] describes the behavior when pretty-printing (non-minified).
/// If true print all properties on the same line.
/// If false print each property on a seperate line.
/// If false print each property on a separate line.
ObjectInitializer(this.properties, {this.isOneLiner = true});
@override
@ -2262,12 +2290,16 @@ class ObjectInitializer extends Expression {
@override
void visitChildren<T>(NodeVisitor<T> visitor) {
for (Property init in properties) init.accept(visitor);
for (Property init in properties) {
init.accept(visitor);
}
}
@override
void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
for (Property init in properties) init.accept1(visitor, arg);
for (Property init in properties) {
init.accept1(visitor, arg);
}
}
@override
@ -2343,7 +2375,7 @@ class MethodDefinition extends Node implements Property {
/// Tag class for all interpolated positions.
abstract class InterpolatedNode implements Node {
get nameOrPosition;
dynamic get nameOrPosition;
bool get isNamed => nameOrPosition is String;
@ -2352,7 +2384,7 @@ abstract class InterpolatedNode implements Node {
class InterpolatedExpression extends Expression with InterpolatedNode {
@override
final nameOrPosition;
final dynamic nameOrPosition;
InterpolatedExpression(this.nameOrPosition);
@ -2379,7 +2411,7 @@ class InterpolatedExpression extends Expression with InterpolatedNode {
class InterpolatedLiteral extends Literal with InterpolatedNode {
@override
final nameOrPosition;
final dynamic nameOrPosition;
InterpolatedLiteral(this.nameOrPosition);
@ -2404,13 +2436,13 @@ class InterpolatedParameter extends Expression
with InterpolatedNode
implements Parameter {
@override
final nameOrPosition;
final dynamic nameOrPosition;
InterpolatedParameter(this.nameOrPosition);
@override
String get name {
throw "InterpolatedParameter.name must not be invoked";
throw 'InterpolatedParameter.name must not be invoked';
}
@override
@ -2439,7 +2471,7 @@ class InterpolatedParameter extends Expression
class InterpolatedSelector extends Expression with InterpolatedNode {
@override
final nameOrPosition;
final dynamic nameOrPosition;
InterpolatedSelector(this.nameOrPosition);
@ -2466,7 +2498,7 @@ class InterpolatedSelector extends Expression with InterpolatedNode {
class InterpolatedStatement extends Statement with InterpolatedNode {
@override
final nameOrPosition;
final dynamic nameOrPosition;
InterpolatedStatement(this.nameOrPosition);
@ -2492,7 +2524,7 @@ class InterpolatedDeclaration extends Expression
with InterpolatedNode
implements Declaration {
@override
final nameOrPosition;
final dynamic nameOrPosition;
InterpolatedDeclaration(this.nameOrPosition);
@ -2516,7 +2548,7 @@ class InterpolatedDeclaration extends Expression
}
@override
String get name => throw "No name for the interpolated node";
String get name => throw 'No name for the interpolated node';
@override
int get precedenceLevel => PRIMARY;

File diff suppressed because it is too large Load diff

View file

@ -7,7 +7,7 @@
// Utilities for converting between JavaScript source-code Strings and the
// String value they represent.
import 'characters.dart' as charCodes;
import 'characters.dart' as char_codes;
class StringToSourceKind {
/// [true] if preferable to use double quotes, [false] if preferable to use
@ -33,24 +33,25 @@ class StringToSource {
int unpairedSurrogates = 0;
for (int rune in value.runes) {
if (rune == charCodes.$BACKSLASH) {
if (rune == char_codes.$BACKSLASH) {
++otherEscapes;
} else if (rune == charCodes.$SQ) {
} else if (rune == char_codes.$SQ) {
++singleQuotes;
} else if (rune == charCodes.$DQ) {
} else if (rune == char_codes.$DQ) {
++doubleQuotes;
} else if (rune == charCodes.$LF ||
rune == charCodes.$CR ||
rune == charCodes.$LS ||
rune == charCodes.$PS) {
} else if (rune == char_codes.$LF ||
rune == char_codes.$CR ||
rune == char_codes.$LS ||
rune == char_codes.$PS) {
// Line terminators.
++otherEscapes;
} else if (rune == charCodes.$BS ||
rune == charCodes.$TAB ||
rune == charCodes.$VTAB ||
rune == charCodes.$FF) {
} else if (rune == char_codes.$BS ||
rune == char_codes.$TAB ||
rune == char_codes.$VTAB ||
rune == char_codes.$FF) {
++otherEscapes;
} else if (ascii && (rune < charCodes.$SPACE || rune >= charCodes.$DEL)) {
} else if (ascii &&
(rune < char_codes.$SPACE || rune >= char_codes.$DEL)) {
++otherEscapes;
} else if (_isUnpairedSurrogate(rune)) {
// Need to escape unpaired surrogates in a UTF8-encoded output otherwise
@ -82,10 +83,10 @@ class StringToSource {
sb.write(escape);
continue;
}
if (rune == charCodes.$LS ||
rune == charCodes.$PS ||
if (rune == char_codes.$LS ||
rune == char_codes.$PS ||
_isUnpairedSurrogate(rune) ||
!utf8 && (rune < charCodes.$SPACE || rune >= charCodes.$DEL)) {
!utf8 && (rune < char_codes.$SPACE || rune >= char_codes.$DEL)) {
if (rune < 0x100) {
sb.write(r'\x');
sb.write(rune.toRadixString(16).padLeft(2, '0'));
@ -113,23 +114,23 @@ class StringToSource {
static String? _irregularEscape(int code, bool useDoubleQuotes) {
switch (code) {
case charCodes.$SQ:
case char_codes.$SQ:
return useDoubleQuotes ? r"'" : r"\'";
case charCodes.$DQ:
case char_codes.$DQ:
return useDoubleQuotes ? r'\"' : r'"';
case charCodes.$BACKSLASH:
case char_codes.$BACKSLASH:
return r'\\';
case charCodes.$BS:
case char_codes.$BS:
return r'\b';
case charCodes.$TAB:
case char_codes.$TAB:
return r'\t';
case charCodes.$LF:
case char_codes.$LF:
return r'\n';
case charCodes.$VTAB:
case char_codes.$VTAB:
return r'\v';
case charCodes.$FF:
case char_codes.$FF:
return r'\f';
case charCodes.$CR:
case char_codes.$CR:
return r'\r';
}
return null;

View file

@ -126,13 +126,13 @@ class Template {
// number of holes should be quite limited.
String unusedNames = arguments.keys
.where((name) => !holeNames.contains(name))
.join(", ");
throw "Template arguments has unused mappings: $unusedNames";
.join(', ');
throw 'Template arguments has unused mappings: $unusedNames';
}
if (!holeNames.every((String name) => arguments.containsKey(name))) {
String notFound =
holeNames.where((name) => !arguments.containsKey(name)).join(", ");
throw "Template arguments is missing mappings for: $notFound";
holeNames.where((name) => !arguments.containsKey(name)).join(', ');
throw 'Template arguments is missing mappings for: $notFound';
}
return instantiator(arguments);
}
@ -434,7 +434,7 @@ class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> {
};
}
TODO(String name) {
Never TODO(String name) {
throw UnimplementedError('$this.$name');
}
@ -601,7 +601,7 @@ class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> {
Instantiator visitCall(Call node) =>
handleCallOrNew(node, (target, arguments) => Call(target, arguments));
Instantiator handleCallOrNew(Call node, finish(target, arguments)) {
Instantiator handleCallOrNew(Call node, Function(dynamic, dynamic) finish) {
Instantiator makeTarget = visit(node.target);
Iterable<Instantiator> argumentMakers =
node.arguments.map(visitSplayableExpression).toList();
@ -855,7 +855,7 @@ class InterpolatedNodeAnalysis extends BaseVisitorVoid {
}
@override
visitInterpolatedNode(InterpolatedNode node) {
void visitInterpolatedNode(InterpolatedNode node) {
containsInterpolatedNode.add(node);
if (node.isNamed) holeNames.add(node.nameOrPosition);
++count;

View file

@ -8,4 +8,5 @@ environment:
dev_dependencies:
expect:
path: ../expect
lints: ^2.0.0
test: ^1.3.4

View file

@ -7,7 +7,7 @@
import 'package:expect/expect.dart';
import 'package:js_ast/js_ast.dart';
main() {
void main() {
Map<Expression, DeferredExpression> map = {};
VariableUse variableUse = VariableUse('variable');
DeferredExpression deferred =
@ -75,18 +75,18 @@ void test(Map<Expression, DeferredExpression> map, String template,
DeferredExpression deferred = map[argument];
Expect.isTrue(
directContext.enterPositions.containsKey(argument),
"Argument ${DebugPrint(argument)} not found in direct enter positions: "
"${directContext.enterPositions.keys}");
'Argument ${DebugPrint(argument)} not found in direct enter positions: '
'${directContext.enterPositions.keys}');
Expect.isTrue(
deferredContext.enterPositions.containsKey(argument),
"Argument ${DebugPrint(argument)} not found in "
"deferred enter positions: "
"${deferredContext.enterPositions.keys}");
'Argument ${DebugPrint(argument)} not found in '
'deferred enter positions: '
'${deferredContext.enterPositions.keys}');
Expect.isTrue(
deferredContext.enterPositions.containsKey(deferred),
"Argument ${DebugPrint(deferred)} not found in "
"deferred enter positions: "
"${deferredContext.enterPositions.keys}");
'Argument ${DebugPrint(deferred)} not found in '
'deferred enter positions: '
'${deferredContext.enterPositions.keys}');
Expect.equals(directContext.enterPositions[argument],
deferredContext.enterPositions[argument]);
Expect.equals(directContext.enterPositions[argument],
@ -94,18 +94,18 @@ void test(Map<Expression, DeferredExpression> map, String template,
Expect.isTrue(
directContext.exitPositions.containsKey(argument),
"Argument ${DebugPrint(argument)} not found in direct enter positions: "
"${directContext.exitPositions.keys}");
'Argument ${DebugPrint(argument)} not found in direct enter positions: '
'${directContext.exitPositions.keys}');
Expect.isTrue(
deferredContext.exitPositions.containsKey(argument),
"Argument ${DebugPrint(argument)} not found in "
"deferred enter positions: "
"${deferredContext.exitPositions.keys}");
'Argument ${DebugPrint(argument)} not found in '
'deferred enter positions: '
'${deferredContext.exitPositions.keys}');
Expect.isTrue(
deferredContext.exitPositions.containsKey(deferred),
"Argument ${DebugPrint(deferred)} not found in "
"deferred enter positions: "
"${deferredContext.exitPositions.keys}");
'Argument ${DebugPrint(deferred)} not found in '
'deferred enter positions: '
'${deferredContext.exitPositions.keys}');
Expect.equals(directContext.exitPositions[argument],
deferredContext.exitPositions[argument]);
Expect.equals(directContext.exitPositions[argument],

View file

@ -14,8 +14,8 @@ class _DeferredStatement extends DeferredStatement {
_DeferredStatement(this.statement);
}
main() {
// Defering a statement should not change how it prints.
void main() {
// Deferring a statement should not change how it prints.
var undeferredStatement = js.statement('var x = 3');
var deferredStatement = _DeferredStatement(undeferredStatement);
Expect.equals(DebugPrint(undeferredStatement), DebugPrint(deferredStatement));

View file

@ -32,25 +32,25 @@ class TestCase {
const List<TestCase> DATA = <TestCase>[
TestCase({
TestMode.NONE: """
TestMode.NONE: '''
function(a, b) {
return null;
}""",
TestMode.ENTER: """
}''',
TestMode.ENTER: '''
@0function(@1a, @2b) @3{
@4return @5null;
}""",
TestMode.DELIMITER: """
}''',
TestMode.DELIMITER: '''
function(a, b) {
return null@4;
@0}""",
TestMode.EXIT: """
@0}''',
TestMode.EXIT: '''
function(a@1, b@2) {
return null@5;
@4}@3@0"""
@4}@3@0'''
}),
TestCase({
TestMode.NONE: """
TestMode.NONE: '''
function() {
if (true) {
foo1();
@ -63,8 +63,8 @@ function() {
baz3();
baz4();
}
}""",
TestMode.ENTER: """
}''',
TestMode.ENTER: '''
@0function() @1{
@2if (@3true) @4{
@5@6@7foo1();
@ -77,8 +77,8 @@ function() {
@23@24@25baz3();
@26@27@28baz4();
}
}""",
TestMode.DELIMITER: """
}''',
TestMode.DELIMITER: '''
function() {
if (true) {
foo1();
@ -91,8 +91,8 @@ function() {
baz3();
baz4();
}
@0}""",
TestMode.EXIT: """
@0}''',
TestMode.EXIT: '''
function() {
if (true@3) {
foo1@7()@6;
@ -105,29 +105,29 @@ function() {
baz3@25()@24;
@23 baz4@28()@27;
@26 }@22
@20}@1@0""",
@20}@1@0''',
}),
TestCase({
TestMode.NONE: """
TestMode.NONE: '''
function() {
function foo() {
}
}""",
TestMode.ENTER: """
}''',
TestMode.ENTER: '''
@0function() @1{
@2@3function @4foo() @5{
}
}""",
TestMode.DELIMITER: """
}''',
TestMode.DELIMITER: '''
function() {
function foo() {
@3}
@0}""",
TestMode.EXIT: """
@0}''',
TestMode.EXIT: '''
function() {
function foo@4() {
}@5@3
@2}@1@0"""
@2}@1@0'''
}),
TestCase({
TestMode.INPUT: """
@ -135,33 +135,33 @@ function() {
a['b'];
[1,, 2];
}""",
TestMode.NONE: """
TestMode.NONE: '''
function() {
a.b;
[1,, 2];
}""",
TestMode.ENTER: """
}''',
TestMode.ENTER: '''
@0function() @1{
@2@3@4a.@5b;
@6@7[@81,@9, @102];
}""",
TestMode.DELIMITER: """
}''',
TestMode.DELIMITER: '''
function() {
a.b;
[1,, 2];
@0}""",
TestMode.EXIT: """
@0}''',
TestMode.EXIT: '''
function() {
a@4.b@5@3;
@2 [1@8,,@9 2@10]@7;
@6}@1@0""",
@6}@1@0''',
}),
TestCase({
TestMode.INPUT: "a.#nameTemplate = #nameTemplate",
TestMode.NONE: "a.nameValue = nameValue",
TestMode.ENTER: "@0@1@2a.@3nameValue = @3nameValue",
TestMode.DELIMITER: "a.nameValue = nameValue",
TestMode.EXIT: "a@2.nameValue@3@1 = nameValue@3@0",
TestMode.INPUT: 'a.#nameTemplate = #nameTemplate',
TestMode.NONE: 'a.nameValue = nameValue',
TestMode.ENTER: '@0@1@2a.@3nameValue = @3nameValue',
TestMode.DELIMITER: 'a.nameValue = nameValue',
TestMode.EXIT: 'a@2.nameValue@3@1 = nameValue@3@0',
}, {
'nameTemplate': 'nameValue'
}),
@ -179,10 +179,10 @@ class FixedName extends Name {
void check(TestCase testCase) {
Map<TestMode, String> map = testCase.data;
String code = map[TestMode.INPUT];
if (code == null) {
// Input is the same as output.
code = map[TestMode.NONE];
}
// Input is the same as output.
code ??= map[TestMode.NONE];
JavaScriptPrintingOptions options = JavaScriptPrintingOptions();
Map arguments = {};
testCase.environment.forEach((String name, String value) {
@ -196,7 +196,7 @@ void check(TestCase testCase) {
// TODO(johnniwinther): Remove `replaceAll(...)` when dart2js behaves as the
// VM on newline in multiline strings.
expect(context.getText(), equals(expectedOutput.replaceAll('\r\n', '\n')),
reason: "Unexpected output for $code in $mode");
reason: 'Unexpected output for $code in $mode');
});
}

View file

@ -14,7 +14,7 @@ const int $LCURLY = $OPEN_CURLY_BRACKET;
const int $RCURLY = $CLOSE_CURLY_BRACKET;
void main() {
check(input, expected, {bool utf8 = false}) {
void check(input, expected, {bool utf8 = false}) {
if (input is List) input = String.fromCharCodes(input);
String actual = DebugPrint(js.string(input), utf8: utf8);
if (expected is List) {