From b3f66b03a1627935feb1b95c83b1e6738416498a Mon Sep 17 00:00:00 2001 From: Brian Wilkerson Date: Wed, 19 Oct 2016 14:31:21 -0700 Subject: [PATCH] Provide an extensible form of ToSourceVisitor (issue 27169) R=matan@lurey.org Review URL: https://codereview.chromium.org/2429243003 . --- pkg/analyzer/lib/src/dart/ast/utilities.dart | 1161 +++++++++ .../test/src/dart/ast/utilities_test.dart | 2244 ++++++++++++++++- 2 files changed, 3399 insertions(+), 6 deletions(-) diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart index 8cf5463b3f9..a1e5448e20f 100644 --- a/pkg/analyzer/lib/src/dart/ast/utilities.dart +++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart @@ -17,6 +17,7 @@ import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine; import 'package:analyzer/src/generated/java_core.dart'; import 'package:analyzer/src/generated/utilities_collection.dart' show TokenMap; import 'package:analyzer/src/generated/utilities_dart.dart'; +import 'package:meta/meta.dart'; /** * A function used to handle exceptions that are thrown by delegates while using @@ -7913,3 +7914,1163 @@ class ToSourceVisitor implements AstVisitor { } } } + +/** + * A visitor used to write a source representation of a visited AST node (and + * all of it's children) to a sink. + */ +class ToSourceVisitor2 implements AstVisitor { + /** + * The sink to which the source is to be written. + */ + @protected + final StringSink sink; + + /** + * Initialize a newly created visitor to write source code representing the + * visited nodes to the given [sink]. + */ + ToSourceVisitor2(this.sink); + + /** + * Visit the given function [body], printing the [prefix] before if the body + * is not empty. + */ + @protected + void safelyVisitFunctionWithPrefix(String prefix, FunctionBody body) { + if (body is! EmptyFunctionBody) { + sink.write(prefix); + } + safelyVisitNode(body); + } + + /** + * Safely visit the given [node]. + */ + @protected + void safelyVisitNode(AstNode node) { + if (node != null) { + node.accept(this); + } + } + + /** + * Print a list of [nodes] without any separation. + */ + @protected + void safelyVisitNodeList(NodeList nodes) { + safelyVisitNodeListWithSeparator(nodes, ""); + } + + /** + * Print a list of [nodes], separated by the given [separator]. + */ + @protected + void safelyVisitNodeListWithSeparator( + NodeList nodes, String separator) { + if (nodes != null) { + int size = nodes.length; + for (int i = 0; i < size; i++) { + if (i > 0) { + sink.write(separator); + } + nodes[i].accept(this); + } + } + } + + /** + * Print a list of [nodes], prefixed by the given [prefix] if the list is not + * empty, and separated by the given [separator]. + */ + @protected + void safelyVisitNodeListWithSeparatorAndPrefix( + String prefix, NodeList nodes, String separator) { + if (nodes != null) { + int size = nodes.length; + if (size > 0) { + sink.write(prefix); + for (int i = 0; i < size; i++) { + if (i > 0) { + sink.write(separator); + } + nodes[i].accept(this); + } + } + } + } + + /** + * Print a list of [nodes], separated by the given [separator], followed by + * the given [suffix] if the list is not empty. + */ + @protected + void safelyVisitNodeListWithSeparatorAndSuffix( + NodeList nodes, String separator, String suffix) { + if (nodes != null) { + int size = nodes.length; + if (size > 0) { + for (int i = 0; i < size; i++) { + if (i > 0) { + sink.write(separator); + } + nodes[i].accept(this); + } + sink.write(suffix); + } + } + } + + /** + * Safely visit the given [node], printing the [prefix] before the node if it + * is non-`null`. + */ + @protected + void safelyVisitNodeWithPrefix(String prefix, AstNode node) { + if (node != null) { + sink.write(prefix); + node.accept(this); + } + } + + /** + * Safely visit the given [node], printing the [suffix] after the node if it + * is non-`null`. + */ + @protected + void safelyVisitNodeWithSuffix(AstNode node, String suffix) { + if (node != null) { + node.accept(this); + sink.write(suffix); + } + } + + /** + * Safely visit the given [token], printing the [suffix] after the token if it + * is non-`null`. + */ + @protected + void safelyVisitTokenWithSuffix(Token token, String suffix) { + if (token != null) { + sink.write(token.lexeme); + sink.write(suffix); + } + } + + @override + Object visitAdjacentStrings(AdjacentStrings node) { + safelyVisitNodeListWithSeparator(node.strings, " "); + return null; + } + + @override + Object visitAnnotation(Annotation node) { + sink.write('@'); + safelyVisitNode(node.name); + safelyVisitNodeWithPrefix(".", node.constructorName); + safelyVisitNode(node.arguments); + return null; + } + + @override + Object visitArgumentList(ArgumentList node) { + sink.write('('); + safelyVisitNodeListWithSeparator(node.arguments, ", "); + sink.write(')'); + return null; + } + + @override + Object visitAsExpression(AsExpression node) { + safelyVisitNode(node.expression); + sink.write(" as "); + safelyVisitNode(node.type); + return null; + } + + @override + Object visitAssertStatement(AssertStatement node) { + sink.write("assert ("); + safelyVisitNode(node.condition); + if (node.message != null) { + sink.write(', '); + safelyVisitNode(node.message); + } + sink.write(");"); + return null; + } + + @override + Object visitAssignmentExpression(AssignmentExpression node) { + safelyVisitNode(node.leftHandSide); + sink.write(' '); + sink.write(node.operator.lexeme); + sink.write(' '); + safelyVisitNode(node.rightHandSide); + return null; + } + + @override + Object visitAwaitExpression(AwaitExpression node) { + sink.write("await "); + safelyVisitNode(node.expression); + return null; + } + + @override + Object visitBinaryExpression(BinaryExpression node) { + safelyVisitNode(node.leftOperand); + sink.write(' '); + sink.write(node.operator.lexeme); + sink.write(' '); + safelyVisitNode(node.rightOperand); + return null; + } + + @override + Object visitBlock(Block node) { + sink.write('{'); + safelyVisitNodeListWithSeparator(node.statements, " "); + sink.write('}'); + return null; + } + + @override + Object visitBlockFunctionBody(BlockFunctionBody node) { + Token keyword = node.keyword; + if (keyword != null) { + sink.write(keyword.lexeme); + if (node.star != null) { + sink.write('*'); + } + sink.write(' '); + } + safelyVisitNode(node.block); + return null; + } + + @override + Object visitBooleanLiteral(BooleanLiteral node) { + sink.write(node.literal.lexeme); + return null; + } + + @override + Object visitBreakStatement(BreakStatement node) { + sink.write("break"); + safelyVisitNodeWithPrefix(" ", node.label); + sink.write(";"); + return null; + } + + @override + Object visitCascadeExpression(CascadeExpression node) { + safelyVisitNode(node.target); + safelyVisitNodeList(node.cascadeSections); + return null; + } + + @override + Object visitCatchClause(CatchClause node) { + safelyVisitNodeWithPrefix("on ", node.exceptionType); + if (node.catchKeyword != null) { + if (node.exceptionType != null) { + sink.write(' '); + } + sink.write("catch ("); + safelyVisitNode(node.exceptionParameter); + safelyVisitNodeWithPrefix(", ", node.stackTraceParameter); + sink.write(") "); + } else { + sink.write(" "); + } + safelyVisitNode(node.body); + return null; + } + + @override + Object visitClassDeclaration(ClassDeclaration node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " "); + safelyVisitTokenWithSuffix(node.abstractKeyword, " "); + sink.write("class "); + safelyVisitNode(node.name); + safelyVisitNode(node.typeParameters); + safelyVisitNodeWithPrefix(" ", node.extendsClause); + safelyVisitNodeWithPrefix(" ", node.withClause); + safelyVisitNodeWithPrefix(" ", node.implementsClause); + sink.write(" {"); + safelyVisitNodeListWithSeparator(node.members, " "); + sink.write("}"); + return null; + } + + @override + Object visitClassTypeAlias(ClassTypeAlias node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " "); + if (node.abstractKeyword != null) { + sink.write("abstract "); + } + sink.write("class "); + safelyVisitNode(node.name); + safelyVisitNode(node.typeParameters); + sink.write(" = "); + safelyVisitNode(node.superclass); + safelyVisitNodeWithPrefix(" ", node.withClause); + safelyVisitNodeWithPrefix(" ", node.implementsClause); + sink.write(";"); + return null; + } + + @override + Object visitComment(Comment node) => null; + + @override + Object visitCommentReference(CommentReference node) => null; + + @override + Object visitCompilationUnit(CompilationUnit node) { + ScriptTag scriptTag = node.scriptTag; + NodeList directives = node.directives; + safelyVisitNode(scriptTag); + String prefix = scriptTag == null ? "" : " "; + safelyVisitNodeListWithSeparatorAndPrefix(prefix, directives, " "); + prefix = scriptTag == null && directives.isEmpty ? "" : " "; + safelyVisitNodeListWithSeparatorAndPrefix(prefix, node.declarations, " "); + return null; + } + + @override + Object visitConditionalExpression(ConditionalExpression node) { + safelyVisitNode(node.condition); + sink.write(" ? "); + safelyVisitNode(node.thenExpression); + sink.write(" : "); + safelyVisitNode(node.elseExpression); + return null; + } + + @override + Object visitConfiguration(Configuration node) { + sink.write('if ('); + safelyVisitNode(node.name); + safelyVisitNodeWithPrefix(" == ", node.value); + sink.write(') '); + safelyVisitNode(node.uri); + return null; + } + + @override + Object visitConstructorDeclaration(ConstructorDeclaration node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " "); + safelyVisitTokenWithSuffix(node.externalKeyword, " "); + safelyVisitTokenWithSuffix(node.constKeyword, " "); + safelyVisitTokenWithSuffix(node.factoryKeyword, " "); + safelyVisitNode(node.returnType); + safelyVisitNodeWithPrefix(".", node.name); + safelyVisitNode(node.parameters); + safelyVisitNodeListWithSeparatorAndPrefix(" : ", node.initializers, ", "); + safelyVisitNodeWithPrefix(" = ", node.redirectedConstructor); + safelyVisitFunctionWithPrefix(" ", node.body); + return null; + } + + @override + Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { + safelyVisitTokenWithSuffix(node.thisKeyword, "."); + safelyVisitNode(node.fieldName); + sink.write(" = "); + safelyVisitNode(node.expression); + return null; + } + + @override + Object visitConstructorName(ConstructorName node) { + safelyVisitNode(node.type); + safelyVisitNodeWithPrefix(".", node.name); + return null; + } + + @override + Object visitContinueStatement(ContinueStatement node) { + sink.write("continue"); + safelyVisitNodeWithPrefix(" ", node.label); + sink.write(";"); + return null; + } + + @override + Object visitDeclaredIdentifier(DeclaredIdentifier node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " "); + safelyVisitTokenWithSuffix(node.keyword, " "); + safelyVisitNodeWithSuffix(node.type, " "); + safelyVisitNode(node.identifier); + return null; + } + + @override + Object visitDefaultFormalParameter(DefaultFormalParameter node) { + safelyVisitNode(node.parameter); + if (node.separator != null) { + sink.write(" "); + sink.write(node.separator.lexeme); + safelyVisitNodeWithPrefix(" ", node.defaultValue); + } + return null; + } + + @override + Object visitDoStatement(DoStatement node) { + sink.write("do "); + safelyVisitNode(node.body); + sink.write(" while ("); + safelyVisitNode(node.condition); + sink.write(");"); + return null; + } + + @override + Object visitDottedName(DottedName node) { + safelyVisitNodeListWithSeparator(node.components, "."); + return null; + } + + @override + Object visitDoubleLiteral(DoubleLiteral node) { + sink.write(node.literal.lexeme); + return null; + } + + @override + Object visitEmptyFunctionBody(EmptyFunctionBody node) { + sink.write(';'); + return null; + } + + @override + Object visitEmptyStatement(EmptyStatement node) { + sink.write(';'); + return null; + } + + @override + Object visitEnumConstantDeclaration(EnumConstantDeclaration node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " "); + safelyVisitNode(node.name); + return null; + } + + @override + Object visitEnumDeclaration(EnumDeclaration node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " "); + sink.write("enum "); + safelyVisitNode(node.name); + sink.write(" {"); + safelyVisitNodeListWithSeparator(node.constants, ", "); + sink.write("}"); + return null; + } + + @override + Object visitExportDirective(ExportDirective node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " "); + sink.write("export "); + safelyVisitNode(node.uri); + safelyVisitNodeListWithSeparatorAndPrefix(" ", node.combinators, " "); + sink.write(';'); + return null; + } + + @override + Object visitExpressionFunctionBody(ExpressionFunctionBody node) { + Token keyword = node.keyword; + if (keyword != null) { + sink.write(keyword.lexeme); + sink.write(' '); + } + sink.write("=> "); + safelyVisitNode(node.expression); + if (node.semicolon != null) { + sink.write(';'); + } + return null; + } + + @override + Object visitExpressionStatement(ExpressionStatement node) { + safelyVisitNode(node.expression); + sink.write(';'); + return null; + } + + @override + Object visitExtendsClause(ExtendsClause node) { + sink.write("extends "); + safelyVisitNode(node.superclass); + return null; + } + + @override + Object visitFieldDeclaration(FieldDeclaration node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " "); + safelyVisitTokenWithSuffix(node.staticKeyword, " "); + safelyVisitNode(node.fields); + sink.write(";"); + return null; + } + + @override + Object visitFieldFormalParameter(FieldFormalParameter node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, ' ', ' '); + safelyVisitTokenWithSuffix(node.keyword, " "); + safelyVisitNodeWithSuffix(node.type, " "); + sink.write("this."); + safelyVisitNode(node.identifier); + safelyVisitNode(node.typeParameters); + safelyVisitNode(node.parameters); + return null; + } + + @override + Object visitForEachStatement(ForEachStatement node) { + DeclaredIdentifier loopVariable = node.loopVariable; + if (node.awaitKeyword != null) { + sink.write("await "); + } + sink.write("for ("); + if (loopVariable == null) { + safelyVisitNode(node.identifier); + } else { + safelyVisitNode(loopVariable); + } + sink.write(" in "); + safelyVisitNode(node.iterable); + sink.write(") "); + safelyVisitNode(node.body); + return null; + } + + @override + Object visitFormalParameterList(FormalParameterList node) { + String groupEnd = null; + sink.write('('); + NodeList parameters = node.parameters; + int size = parameters.length; + for (int i = 0; i < size; i++) { + FormalParameter parameter = parameters[i]; + if (i > 0) { + sink.write(", "); + } + if (groupEnd == null && parameter is DefaultFormalParameter) { + if (parameter.kind == ParameterKind.NAMED) { + groupEnd = "}"; + sink.write('{'); + } else { + groupEnd = "]"; + sink.write('['); + } + } + parameter.accept(this); + } + if (groupEnd != null) { + sink.write(groupEnd); + } + sink.write(')'); + return null; + } + + @override + Object visitForStatement(ForStatement node) { + Expression initialization = node.initialization; + sink.write("for ("); + if (initialization != null) { + safelyVisitNode(initialization); + } else { + safelyVisitNode(node.variables); + } + sink.write(";"); + safelyVisitNodeWithPrefix(" ", node.condition); + sink.write(";"); + safelyVisitNodeListWithSeparatorAndPrefix(" ", node.updaters, ", "); + sink.write(") "); + safelyVisitNode(node.body); + return null; + } + + @override + Object visitFunctionDeclaration(FunctionDeclaration node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " "); + safelyVisitTokenWithSuffix(node.externalKeyword, " "); + safelyVisitNodeWithSuffix(node.returnType, " "); + safelyVisitTokenWithSuffix(node.propertyKeyword, " "); + safelyVisitNode(node.name); + safelyVisitNode(node.functionExpression); + return null; + } + + @override + Object visitFunctionDeclarationStatement(FunctionDeclarationStatement node) { + safelyVisitNode(node.functionDeclaration); + return null; + } + + @override + Object visitFunctionExpression(FunctionExpression node) { + safelyVisitNode(node.typeParameters); + safelyVisitNode(node.parameters); + if (node.body is! EmptyFunctionBody) { + sink.write(' '); + } + safelyVisitNode(node.body); + return null; + } + + @override + Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { + safelyVisitNode(node.function); + safelyVisitNode(node.typeArguments); + safelyVisitNode(node.argumentList); + return null; + } + + @override + Object visitFunctionTypeAlias(FunctionTypeAlias node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " "); + sink.write("typedef "); + safelyVisitNodeWithSuffix(node.returnType, " "); + safelyVisitNode(node.name); + safelyVisitNode(node.typeParameters); + safelyVisitNode(node.parameters); + sink.write(";"); + return null; + } + + @override + Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, ' ', ' '); + safelyVisitNodeWithSuffix(node.returnType, " "); + safelyVisitNode(node.identifier); + safelyVisitNode(node.typeParameters); + safelyVisitNode(node.parameters); + if (node.question != null) { + sink.write('?'); + } + return null; + } + + @override + Object visitHideCombinator(HideCombinator node) { + sink.write("hide "); + safelyVisitNodeListWithSeparator(node.hiddenNames, ", "); + return null; + } + + @override + Object visitIfStatement(IfStatement node) { + sink.write("if ("); + safelyVisitNode(node.condition); + sink.write(") "); + safelyVisitNode(node.thenStatement); + safelyVisitNodeWithPrefix(" else ", node.elseStatement); + return null; + } + + @override + Object visitImplementsClause(ImplementsClause node) { + sink.write("implements "); + safelyVisitNodeListWithSeparator(node.interfaces, ", "); + return null; + } + + @override + Object visitImportDirective(ImportDirective node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " "); + sink.write("import "); + safelyVisitNode(node.uri); + if (node.deferredKeyword != null) { + sink.write(" deferred"); + } + safelyVisitNodeWithPrefix(" as ", node.prefix); + safelyVisitNodeListWithSeparatorAndPrefix(" ", node.combinators, " "); + sink.write(';'); + return null; + } + + @override + Object visitIndexExpression(IndexExpression node) { + if (node.isCascaded) { + sink.write(".."); + } else { + safelyVisitNode(node.target); + } + sink.write('['); + safelyVisitNode(node.index); + sink.write(']'); + return null; + } + + @override + Object visitInstanceCreationExpression(InstanceCreationExpression node) { + safelyVisitTokenWithSuffix(node.keyword, " "); + safelyVisitNode(node.constructorName); + safelyVisitNode(node.argumentList); + return null; + } + + @override + Object visitIntegerLiteral(IntegerLiteral node) { + sink.write(node.literal.lexeme); + return null; + } + + @override + Object visitInterpolationExpression(InterpolationExpression node) { + if (node.rightBracket != null) { + sink.write("\${"); + safelyVisitNode(node.expression); + sink.write("}"); + } else { + sink.write("\$"); + safelyVisitNode(node.expression); + } + return null; + } + + @override + Object visitInterpolationString(InterpolationString node) { + sink.write(node.contents.lexeme); + return null; + } + + @override + Object visitIsExpression(IsExpression node) { + safelyVisitNode(node.expression); + if (node.notOperator == null) { + sink.write(" is "); + } else { + sink.write(" is! "); + } + safelyVisitNode(node.type); + return null; + } + + @override + Object visitLabel(Label node) { + safelyVisitNode(node.label); + sink.write(":"); + return null; + } + + @override + Object visitLabeledStatement(LabeledStatement node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.labels, " ", " "); + safelyVisitNode(node.statement); + return null; + } + + @override + Object visitLibraryDirective(LibraryDirective node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " "); + sink.write("library "); + safelyVisitNode(node.name); + sink.write(';'); + return null; + } + + @override + Object visitLibraryIdentifier(LibraryIdentifier node) { + sink.write(node.name); + return null; + } + + @override + Object visitListLiteral(ListLiteral node) { + if (node.constKeyword != null) { + sink.write(node.constKeyword.lexeme); + sink.write(' '); + } + safelyVisitNodeWithSuffix(node.typeArguments, " "); + sink.write("["); + safelyVisitNodeListWithSeparator(node.elements, ", "); + sink.write("]"); + return null; + } + + @override + Object visitMapLiteral(MapLiteral node) { + if (node.constKeyword != null) { + sink.write(node.constKeyword.lexeme); + sink.write(' '); + } + safelyVisitNodeWithSuffix(node.typeArguments, " "); + sink.write("{"); + safelyVisitNodeListWithSeparator(node.entries, ", "); + sink.write("}"); + return null; + } + + @override + Object visitMapLiteralEntry(MapLiteralEntry node) { + safelyVisitNode(node.key); + sink.write(" : "); + safelyVisitNode(node.value); + return null; + } + + @override + Object visitMethodDeclaration(MethodDeclaration node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " "); + safelyVisitTokenWithSuffix(node.externalKeyword, " "); + safelyVisitTokenWithSuffix(node.modifierKeyword, " "); + safelyVisitNodeWithSuffix(node.returnType, " "); + safelyVisitTokenWithSuffix(node.propertyKeyword, " "); + safelyVisitTokenWithSuffix(node.operatorKeyword, " "); + safelyVisitNode(node.name); + if (!node.isGetter) { + safelyVisitNode(node.typeParameters); + safelyVisitNode(node.parameters); + } + safelyVisitFunctionWithPrefix(" ", node.body); + return null; + } + + @override + Object visitMethodInvocation(MethodInvocation node) { + if (node.isCascaded) { + sink.write(".."); + } else { + if (node.target != null) { + node.target.accept(this); + sink.write(node.operator.lexeme); + } + } + safelyVisitNode(node.methodName); + safelyVisitNode(node.typeArguments); + safelyVisitNode(node.argumentList); + return null; + } + + @override + Object visitNamedExpression(NamedExpression node) { + safelyVisitNode(node.name); + safelyVisitNodeWithPrefix(" ", node.expression); + return null; + } + + @override + Object visitNativeClause(NativeClause node) { + sink.write("native "); + safelyVisitNode(node.name); + return null; + } + + @override + Object visitNativeFunctionBody(NativeFunctionBody node) { + sink.write("native "); + safelyVisitNode(node.stringLiteral); + sink.write(';'); + return null; + } + + @override + Object visitNullLiteral(NullLiteral node) { + sink.write("null"); + return null; + } + + @override + Object visitParenthesizedExpression(ParenthesizedExpression node) { + sink.write('('); + safelyVisitNode(node.expression); + sink.write(')'); + return null; + } + + @override + Object visitPartDirective(PartDirective node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " "); + sink.write("part "); + safelyVisitNode(node.uri); + sink.write(';'); + return null; + } + + @override + Object visitPartOfDirective(PartOfDirective node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " "); + sink.write("part of "); + safelyVisitNode(node.libraryName); + sink.write(';'); + return null; + } + + @override + Object visitPostfixExpression(PostfixExpression node) { + safelyVisitNode(node.operand); + sink.write(node.operator.lexeme); + return null; + } + + @override + Object visitPrefixedIdentifier(PrefixedIdentifier node) { + safelyVisitNode(node.prefix); + sink.write('.'); + safelyVisitNode(node.identifier); + return null; + } + + @override + Object visitPrefixExpression(PrefixExpression node) { + sink.write(node.operator.lexeme); + safelyVisitNode(node.operand); + return null; + } + + @override + Object visitPropertyAccess(PropertyAccess node) { + if (node.isCascaded) { + sink.write(".."); + } else { + safelyVisitNode(node.target); + sink.write(node.operator.lexeme); + } + safelyVisitNode(node.propertyName); + return null; + } + + @override + Object visitRedirectingConstructorInvocation( + RedirectingConstructorInvocation node) { + sink.write("this"); + safelyVisitNodeWithPrefix(".", node.constructorName); + safelyVisitNode(node.argumentList); + return null; + } + + @override + Object visitRethrowExpression(RethrowExpression node) { + sink.write("rethrow"); + return null; + } + + @override + Object visitReturnStatement(ReturnStatement node) { + Expression expression = node.expression; + if (expression == null) { + sink.write("return;"); + } else { + sink.write("return "); + expression.accept(this); + sink.write(";"); + } + return null; + } + + @override + Object visitScriptTag(ScriptTag node) { + sink.write(node.scriptTag.lexeme); + return null; + } + + @override + Object visitShowCombinator(ShowCombinator node) { + sink.write("show "); + safelyVisitNodeListWithSeparator(node.shownNames, ", "); + return null; + } + + @override + Object visitSimpleFormalParameter(SimpleFormalParameter node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, ' ', ' '); + safelyVisitTokenWithSuffix(node.keyword, " "); + safelyVisitNodeWithSuffix(node.type, " "); + safelyVisitNode(node.identifier); + return null; + } + + @override + Object visitSimpleIdentifier(SimpleIdentifier node) { + sink.write(node.token.lexeme); + return null; + } + + @override + Object visitSimpleStringLiteral(SimpleStringLiteral node) { + sink.write(node.literal.lexeme); + return null; + } + + @override + Object visitStringInterpolation(StringInterpolation node) { + safelyVisitNodeList(node.elements); + return null; + } + + @override + Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { + sink.write("super"); + safelyVisitNodeWithPrefix(".", node.constructorName); + safelyVisitNode(node.argumentList); + return null; + } + + @override + Object visitSuperExpression(SuperExpression node) { + sink.write("super"); + return null; + } + + @override + Object visitSwitchCase(SwitchCase node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.labels, " ", " "); + sink.write("case "); + safelyVisitNode(node.expression); + sink.write(": "); + safelyVisitNodeListWithSeparator(node.statements, " "); + return null; + } + + @override + Object visitSwitchDefault(SwitchDefault node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.labels, " ", " "); + sink.write("default: "); + safelyVisitNodeListWithSeparator(node.statements, " "); + return null; + } + + @override + Object visitSwitchStatement(SwitchStatement node) { + sink.write("switch ("); + safelyVisitNode(node.expression); + sink.write(") {"); + safelyVisitNodeListWithSeparator(node.members, " "); + sink.write("}"); + return null; + } + + @override + Object visitSymbolLiteral(SymbolLiteral node) { + sink.write("#"); + List components = node.components; + for (int i = 0; i < components.length; i++) { + if (i > 0) { + sink.write("."); + } + sink.write(components[i].lexeme); + } + return null; + } + + @override + Object visitThisExpression(ThisExpression node) { + sink.write("this"); + return null; + } + + @override + Object visitThrowExpression(ThrowExpression node) { + sink.write("throw "); + safelyVisitNode(node.expression); + return null; + } + + @override + Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { + safelyVisitNodeWithSuffix(node.variables, ";"); + return null; + } + + @override + Object visitTryStatement(TryStatement node) { + sink.write("try "); + safelyVisitNode(node.body); + safelyVisitNodeListWithSeparatorAndPrefix(" ", node.catchClauses, " "); + safelyVisitNodeWithPrefix(" finally ", node.finallyBlock); + return null; + } + + @override + Object visitTypeArgumentList(TypeArgumentList node) { + sink.write('<'); + safelyVisitNodeListWithSeparator(node.arguments, ", "); + sink.write('>'); + return null; + } + + @override + Object visitTypeName(TypeName node) { + safelyVisitNode(node.name); + safelyVisitNode(node.typeArguments); + if (node.question != null) { + sink.write('?'); + } + return null; + } + + @override + Object visitTypeParameter(TypeParameter node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " "); + safelyVisitNode(node.name); + safelyVisitNodeWithPrefix(" extends ", node.bound); + return null; + } + + @override + Object visitTypeParameterList(TypeParameterList node) { + sink.write('<'); + safelyVisitNodeListWithSeparator(node.typeParameters, ", "); + sink.write('>'); + return null; + } + + @override + Object visitVariableDeclaration(VariableDeclaration node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " "); + safelyVisitNode(node.name); + safelyVisitNodeWithPrefix(" = ", node.initializer); + return null; + } + + @override + Object visitVariableDeclarationList(VariableDeclarationList node) { + safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " "); + safelyVisitTokenWithSuffix(node.keyword, " "); + safelyVisitNodeWithSuffix(node.type, " "); + safelyVisitNodeListWithSeparator(node.variables, ", "); + return null; + } + + @override + Object visitVariableDeclarationStatement(VariableDeclarationStatement node) { + safelyVisitNode(node.variables); + sink.write(";"); + return null; + } + + @override + Object visitWhileStatement(WhileStatement node) { + sink.write("while ("); + safelyVisitNode(node.condition); + sink.write(") "); + safelyVisitNode(node.body); + return null; + } + + @override + Object visitWithClause(WithClause node) { + sink.write("with "); + safelyVisitNodeListWithSeparator(node.mixinTypes, ", "); + return null; + } + + @override + Object visitYieldStatement(YieldStatement node) { + if (node.star != null) { + sink.write("yield* "); + } else { + sink.write("yield "); + } + safelyVisitNode(node.expression); + sink.write(";"); + return null; + } +} diff --git a/pkg/analyzer/test/src/dart/ast/utilities_test.dart b/pkg/analyzer/test/src/dart/ast/utilities_test.dart index 7e83cf7bfe0..7b4d93a7d95 100644 --- a/pkg/analyzer/test/src/dart/ast/utilities_test.dart +++ b/pkg/analyzer/test/src/dart/ast/utilities_test.dart @@ -29,6 +29,7 @@ main() { defineReflectiveTests(NodeLocator2Test); defineReflectiveTests(ResolutionCopierTest); defineReflectiveTests(ToSourceVisitorTest); + defineReflectiveTests(ToSourceVisitor2Test); }); } @@ -1108,6 +1109,2241 @@ class ResolutionCopierTest extends EngineTestCase { } } +@reflectiveTest +class ToSourceVisitor2Test extends EngineTestCase { + void test_visitAdjacentStrings() { + _assertSource( + "'a' 'b'", + AstFactory.adjacentStrings( + [AstFactory.string2("a"), AstFactory.string2("b")])); + } + + void test_visitAnnotation_constant() { + _assertSource("@A", AstFactory.annotation(AstFactory.identifier3("A"))); + } + + void test_visitAnnotation_constructor() { + _assertSource( + "@A.c()", + AstFactory.annotation2(AstFactory.identifier3("A"), + AstFactory.identifier3("c"), AstFactory.argumentList())); + } + + void test_visitArgumentList() { + _assertSource( + "(a, b)", + AstFactory.argumentList( + [AstFactory.identifier3("a"), AstFactory.identifier3("b")])); + } + + void test_visitAsExpression() { + _assertSource( + "e as T", + AstFactory.asExpression( + AstFactory.identifier3("e"), AstFactory.typeName4("T"))); + } + + void test_visitAssertStatement() { + _assertSource( + "assert (a);", AstFactory.assertStatement(AstFactory.identifier3("a"))); + } + + void test_visitAssertStatement_withMessage() { + _assertSource( + "assert (a, b);", + AstFactory.assertStatement( + AstFactory.identifier3("a"), AstFactory.identifier3('b'))); + } + + void test_visitAssignmentExpression() { + _assertSource( + "a = b", + AstFactory.assignmentExpression(AstFactory.identifier3("a"), + TokenType.EQ, AstFactory.identifier3("b"))); + } + + void test_visitAwaitExpression() { + _assertSource( + "await e", AstFactory.awaitExpression(AstFactory.identifier3("e"))); + } + + void test_visitBinaryExpression() { + _assertSource( + "a + b", + AstFactory.binaryExpression(AstFactory.identifier3("a"), TokenType.PLUS, + AstFactory.identifier3("b"))); + } + + void test_visitBlock_empty() { + _assertSource("{}", AstFactory.block()); + } + + void test_visitBlock_nonEmpty() { + _assertSource( + "{break; break;}", + AstFactory + .block([AstFactory.breakStatement(), AstFactory.breakStatement()])); + } + + void test_visitBlockFunctionBody_async() { + _assertSource("async {}", AstFactory.asyncBlockFunctionBody()); + } + + void test_visitBlockFunctionBody_async_star() { + _assertSource("async* {}", AstFactory.asyncGeneratorBlockFunctionBody()); + } + + void test_visitBlockFunctionBody_simple() { + _assertSource("{}", AstFactory.blockFunctionBody2()); + } + + void test_visitBlockFunctionBody_sync() { + _assertSource("sync {}", AstFactory.syncBlockFunctionBody()); + } + + void test_visitBlockFunctionBody_sync_star() { + _assertSource("sync* {}", AstFactory.syncGeneratorBlockFunctionBody()); + } + + void test_visitBooleanLiteral_false() { + _assertSource("false", AstFactory.booleanLiteral(false)); + } + + void test_visitBooleanLiteral_true() { + _assertSource("true", AstFactory.booleanLiteral(true)); + } + + void test_visitBreakStatement_label() { + _assertSource("break l;", AstFactory.breakStatement2("l")); + } + + void test_visitBreakStatement_noLabel() { + _assertSource("break;", AstFactory.breakStatement()); + } + + void test_visitCascadeExpression_field() { + _assertSource( + "a..b..c", + AstFactory.cascadeExpression(AstFactory.identifier3("a"), [ + AstFactory.cascadedPropertyAccess("b"), + AstFactory.cascadedPropertyAccess("c") + ])); + } + + void test_visitCascadeExpression_index() { + _assertSource( + "a..[0]..[1]", + AstFactory.cascadeExpression(AstFactory.identifier3("a"), [ + AstFactory.cascadedIndexExpression(AstFactory.integer(0)), + AstFactory.cascadedIndexExpression(AstFactory.integer(1)) + ])); + } + + void test_visitCascadeExpression_method() { + _assertSource( + "a..b()..c()", + AstFactory.cascadeExpression(AstFactory.identifier3("a"), [ + AstFactory.cascadedMethodInvocation("b"), + AstFactory.cascadedMethodInvocation("c") + ])); + } + + void test_visitCatchClause_catch_noStack() { + _assertSource("catch (e) {}", AstFactory.catchClause("e")); + } + + void test_visitCatchClause_catch_stack() { + _assertSource("catch (e, s) {}", AstFactory.catchClause2("e", "s")); + } + + void test_visitCatchClause_on() { + _assertSource( + "on E {}", AstFactory.catchClause3(AstFactory.typeName4("E"))); + } + + void test_visitCatchClause_on_catch() { + _assertSource("on E catch (e) {}", + AstFactory.catchClause4(AstFactory.typeName4("E"), "e")); + } + + void test_visitClassDeclaration_abstract() { + _assertSource( + "abstract class C {}", + AstFactory.classDeclaration( + Keyword.ABSTRACT, "C", null, null, null, null)); + } + + void test_visitClassDeclaration_empty() { + _assertSource("class C {}", + AstFactory.classDeclaration(null, "C", null, null, null, null)); + } + + void test_visitClassDeclaration_extends() { + _assertSource( + "class C extends A {}", + AstFactory.classDeclaration(null, "C", null, + AstFactory.extendsClause(AstFactory.typeName4("A")), null, null)); + } + + void test_visitClassDeclaration_extends_implements() { + _assertSource( + "class C extends A implements B {}", + AstFactory.classDeclaration( + null, + "C", + null, + AstFactory.extendsClause(AstFactory.typeName4("A")), + null, + AstFactory.implementsClause([AstFactory.typeName4("B")]))); + } + + void test_visitClassDeclaration_extends_with() { + _assertSource( + "class C extends A with M {}", + AstFactory.classDeclaration( + null, + "C", + null, + AstFactory.extendsClause(AstFactory.typeName4("A")), + AstFactory.withClause([AstFactory.typeName4("M")]), + null)); + } + + void test_visitClassDeclaration_extends_with_implements() { + _assertSource( + "class C extends A with M implements B {}", + AstFactory.classDeclaration( + null, + "C", + null, + AstFactory.extendsClause(AstFactory.typeName4("A")), + AstFactory.withClause([AstFactory.typeName4("M")]), + AstFactory.implementsClause([AstFactory.typeName4("B")]))); + } + + void test_visitClassDeclaration_implements() { + _assertSource( + "class C implements B {}", + AstFactory.classDeclaration(null, "C", null, null, null, + AstFactory.implementsClause([AstFactory.typeName4("B")]))); + } + + void test_visitClassDeclaration_multipleMember() { + _assertSource( + "class C {var a; var b;}", + AstFactory.classDeclaration(null, "C", null, null, null, null, [ + AstFactory.fieldDeclaration2( + false, Keyword.VAR, [AstFactory.variableDeclaration("a")]), + AstFactory.fieldDeclaration2( + false, Keyword.VAR, [AstFactory.variableDeclaration("b")]) + ])); + } + + void test_visitClassDeclaration_parameters() { + _assertSource( + "class C {}", + AstFactory.classDeclaration( + null, "C", AstFactory.typeParameterList(["E"]), null, null, null)); + } + + void test_visitClassDeclaration_parameters_extends() { + _assertSource( + "class C extends A {}", + AstFactory.classDeclaration( + null, + "C", + AstFactory.typeParameterList(["E"]), + AstFactory.extendsClause(AstFactory.typeName4("A")), + null, + null)); + } + + void test_visitClassDeclaration_parameters_extends_implements() { + _assertSource( + "class C extends A implements B {}", + AstFactory.classDeclaration( + null, + "C", + AstFactory.typeParameterList(["E"]), + AstFactory.extendsClause(AstFactory.typeName4("A")), + null, + AstFactory.implementsClause([AstFactory.typeName4("B")]))); + } + + void test_visitClassDeclaration_parameters_extends_with() { + _assertSource( + "class C extends A with M {}", + AstFactory.classDeclaration( + null, + "C", + AstFactory.typeParameterList(["E"]), + AstFactory.extendsClause(AstFactory.typeName4("A")), + AstFactory.withClause([AstFactory.typeName4("M")]), + null)); + } + + void test_visitClassDeclaration_parameters_extends_with_implements() { + _assertSource( + "class C extends A with M implements B {}", + AstFactory.classDeclaration( + null, + "C", + AstFactory.typeParameterList(["E"]), + AstFactory.extendsClause(AstFactory.typeName4("A")), + AstFactory.withClause([AstFactory.typeName4("M")]), + AstFactory.implementsClause([AstFactory.typeName4("B")]))); + } + + void test_visitClassDeclaration_parameters_implements() { + _assertSource( + "class C implements B {}", + AstFactory.classDeclaration( + null, + "C", + AstFactory.typeParameterList(["E"]), + null, + null, + AstFactory.implementsClause([AstFactory.typeName4("B")]))); + } + + void test_visitClassDeclaration_singleMember() { + _assertSource( + "class C {var a;}", + AstFactory.classDeclaration(null, "C", null, null, null, null, [ + AstFactory.fieldDeclaration2( + false, Keyword.VAR, [AstFactory.variableDeclaration("a")]) + ])); + } + + void test_visitClassDeclaration_withMetadata() { + ClassDeclaration declaration = + AstFactory.classDeclaration(null, "C", null, null, null, null); + declaration.metadata + .add(AstFactory.annotation(AstFactory.identifier3("deprecated"))); + _assertSource("@deprecated class C {}", declaration); + } + + void test_visitClassTypeAlias_abstract() { + _assertSource( + "abstract class C = S with M1;", + AstFactory.classTypeAlias( + "C", + null, + Keyword.ABSTRACT, + AstFactory.typeName4("S"), + AstFactory.withClause([AstFactory.typeName4("M1")]), + null)); + } + + void test_visitClassTypeAlias_abstract_implements() { + _assertSource( + "abstract class C = S with M1 implements I;", + AstFactory.classTypeAlias( + "C", + null, + Keyword.ABSTRACT, + AstFactory.typeName4("S"), + AstFactory.withClause([AstFactory.typeName4("M1")]), + AstFactory.implementsClause([AstFactory.typeName4("I")]))); + } + + void test_visitClassTypeAlias_generic() { + _assertSource( + "class C = S with M1;", + AstFactory.classTypeAlias( + "C", + AstFactory.typeParameterList(["E"]), + null, + AstFactory.typeName4("S", [AstFactory.typeName4("E")]), + AstFactory.withClause([ + AstFactory.typeName4("M1", [AstFactory.typeName4("E")]) + ]), + null)); + } + + void test_visitClassTypeAlias_implements() { + _assertSource( + "class C = S with M1 implements I;", + AstFactory.classTypeAlias( + "C", + null, + null, + AstFactory.typeName4("S"), + AstFactory.withClause([AstFactory.typeName4("M1")]), + AstFactory.implementsClause([AstFactory.typeName4("I")]))); + } + + void test_visitClassTypeAlias_minimal() { + _assertSource( + "class C = S with M1;", + AstFactory.classTypeAlias("C", null, null, AstFactory.typeName4("S"), + AstFactory.withClause([AstFactory.typeName4("M1")]), null)); + } + + void test_visitClassTypeAlias_parameters_abstract() { + _assertSource( + "abstract class C = S with M1;", + AstFactory.classTypeAlias( + "C", + AstFactory.typeParameterList(["E"]), + Keyword.ABSTRACT, + AstFactory.typeName4("S"), + AstFactory.withClause([AstFactory.typeName4("M1")]), + null)); + } + + void test_visitClassTypeAlias_parameters_abstract_implements() { + _assertSource( + "abstract class C = S with M1 implements I;", + AstFactory.classTypeAlias( + "C", + AstFactory.typeParameterList(["E"]), + Keyword.ABSTRACT, + AstFactory.typeName4("S"), + AstFactory.withClause([AstFactory.typeName4("M1")]), + AstFactory.implementsClause([AstFactory.typeName4("I")]))); + } + + void test_visitClassTypeAlias_parameters_implements() { + _assertSource( + "class C = S with M1 implements I;", + AstFactory.classTypeAlias( + "C", + AstFactory.typeParameterList(["E"]), + null, + AstFactory.typeName4("S"), + AstFactory.withClause([AstFactory.typeName4("M1")]), + AstFactory.implementsClause([AstFactory.typeName4("I")]))); + } + + void test_visitClassTypeAlias_withMetadata() { + ClassTypeAlias declaration = AstFactory.classTypeAlias( + "C", + null, + null, + AstFactory.typeName4("S"), + AstFactory.withClause([AstFactory.typeName4("M1")]), + null); + declaration.metadata + .add(AstFactory.annotation(AstFactory.identifier3("deprecated"))); + _assertSource("@deprecated class C = S with M1;", declaration); + } + + void test_visitComment() { + _assertSource( + "", + Comment.createBlockComment( + [TokenFactory.tokenFromString("/* comment */")])); + } + + void test_visitCommentReference() { + _assertSource("", new CommentReference(null, AstFactory.identifier3("a"))); + } + + void test_visitCompilationUnit_declaration() { + _assertSource( + "var a;", + AstFactory.compilationUnit2([ + AstFactory.topLevelVariableDeclaration2( + Keyword.VAR, [AstFactory.variableDeclaration("a")]) + ])); + } + + void test_visitCompilationUnit_directive() { + _assertSource("library l;", + AstFactory.compilationUnit3([AstFactory.libraryDirective2("l")])); + } + + void test_visitCompilationUnit_directive_declaration() { + _assertSource( + "library l; var a;", + AstFactory.compilationUnit4([ + AstFactory.libraryDirective2("l") + ], [ + AstFactory.topLevelVariableDeclaration2( + Keyword.VAR, [AstFactory.variableDeclaration("a")]) + ])); + } + + void test_visitCompilationUnit_empty() { + _assertSource("", AstFactory.compilationUnit()); + } + + void test_visitCompilationUnit_script() { + _assertSource( + "!#/bin/dartvm", AstFactory.compilationUnit5("!#/bin/dartvm")); + } + + void test_visitCompilationUnit_script_declaration() { + _assertSource( + "!#/bin/dartvm var a;", + AstFactory.compilationUnit6("!#/bin/dartvm", [ + AstFactory.topLevelVariableDeclaration2( + Keyword.VAR, [AstFactory.variableDeclaration("a")]) + ])); + } + + void test_visitCompilationUnit_script_directive() { + _assertSource( + "!#/bin/dartvm library l;", + AstFactory.compilationUnit7( + "!#/bin/dartvm", [AstFactory.libraryDirective2("l")])); + } + + void test_visitCompilationUnit_script_directives_declarations() { + _assertSource( + "!#/bin/dartvm library l; var a;", + AstFactory.compilationUnit8("!#/bin/dartvm", [ + AstFactory.libraryDirective2("l") + ], [ + AstFactory.topLevelVariableDeclaration2( + Keyword.VAR, [AstFactory.variableDeclaration("a")]) + ])); + } + + void test_visitConditionalExpression() { + _assertSource( + "a ? b : c", + AstFactory.conditionalExpression(AstFactory.identifier3("a"), + AstFactory.identifier3("b"), AstFactory.identifier3("c"))); + } + + void test_visitConstructorDeclaration_const() { + _assertSource( + "const C() {}", + AstFactory.constructorDeclaration2( + Keyword.CONST, + null, + AstFactory.identifier3("C"), + null, + AstFactory.formalParameterList(), + null, + AstFactory.blockFunctionBody2())); + } + + void test_visitConstructorDeclaration_external() { + _assertSource( + "external C();", + AstFactory.constructorDeclaration(AstFactory.identifier3("C"), null, + AstFactory.formalParameterList(), null)); + } + + void test_visitConstructorDeclaration_minimal() { + _assertSource( + "C() {}", + AstFactory.constructorDeclaration2( + null, + null, + AstFactory.identifier3("C"), + null, + AstFactory.formalParameterList(), + null, + AstFactory.blockFunctionBody2())); + } + + void test_visitConstructorDeclaration_multipleInitializers() { + _assertSource( + "C() : a = b, c = d {}", + AstFactory.constructorDeclaration2( + null, + null, + AstFactory.identifier3("C"), + null, + AstFactory.formalParameterList(), + [ + AstFactory.constructorFieldInitializer( + false, "a", AstFactory.identifier3("b")), + AstFactory.constructorFieldInitializer( + false, "c", AstFactory.identifier3("d")) + ], + AstFactory.blockFunctionBody2())); + } + + void test_visitConstructorDeclaration_multipleParameters() { + _assertSource( + "C(var a, var b) {}", + AstFactory.constructorDeclaration2( + null, + null, + AstFactory.identifier3("C"), + null, + AstFactory.formalParameterList([ + AstFactory.simpleFormalParameter(Keyword.VAR, "a"), + AstFactory.simpleFormalParameter(Keyword.VAR, "b") + ]), + null, + AstFactory.blockFunctionBody2())); + } + + void test_visitConstructorDeclaration_named() { + _assertSource( + "C.m() {}", + AstFactory.constructorDeclaration2( + null, + null, + AstFactory.identifier3("C"), + "m", + AstFactory.formalParameterList(), + null, + AstFactory.blockFunctionBody2())); + } + + void test_visitConstructorDeclaration_singleInitializer() { + _assertSource( + "C() : a = b {}", + AstFactory.constructorDeclaration2( + null, + null, + AstFactory.identifier3("C"), + null, + AstFactory.formalParameterList(), + [ + AstFactory.constructorFieldInitializer( + false, "a", AstFactory.identifier3("b")) + ], + AstFactory.blockFunctionBody2())); + } + + void test_visitConstructorDeclaration_withMetadata() { + ConstructorDeclaration declaration = AstFactory.constructorDeclaration2( + null, + null, + AstFactory.identifier3("C"), + null, + AstFactory.formalParameterList(), + null, + AstFactory.blockFunctionBody2()); + declaration.metadata + .add(AstFactory.annotation(AstFactory.identifier3("deprecated"))); + _assertSource("@deprecated C() {}", declaration); + } + + void test_visitConstructorFieldInitializer_withoutThis() { + _assertSource( + "a = b", + AstFactory.constructorFieldInitializer( + false, "a", AstFactory.identifier3("b"))); + } + + void test_visitConstructorFieldInitializer_withThis() { + _assertSource( + "this.a = b", + AstFactory.constructorFieldInitializer( + true, "a", AstFactory.identifier3("b"))); + } + + void test_visitConstructorName_named_prefix() { + _assertSource("p.C.n", + AstFactory.constructorName(AstFactory.typeName4("p.C.n"), null)); + } + + void test_visitConstructorName_unnamed_noPrefix() { + _assertSource( + "C", AstFactory.constructorName(AstFactory.typeName4("C"), null)); + } + + void test_visitConstructorName_unnamed_prefix() { + _assertSource( + "p.C", + AstFactory.constructorName( + AstFactory.typeName3(AstFactory.identifier5("p", "C")), null)); + } + + void test_visitContinueStatement_label() { + _assertSource("continue l;", AstFactory.continueStatement("l")); + } + + void test_visitContinueStatement_noLabel() { + _assertSource("continue;", AstFactory.continueStatement()); + } + + void test_visitDefaultFormalParameter_annotation() { + DefaultFormalParameter parameter = AstFactory.positionalFormalParameter( + AstFactory.simpleFormalParameter3("p"), AstFactory.integer(0)); + parameter.metadata.add(AstFactory.annotation(AstFactory.identifier3("A"))); + _assertSource('@A p = 0', parameter); + } + + void test_visitDefaultFormalParameter_named_noValue() { + _assertSource( + "p", + AstFactory.namedFormalParameter( + AstFactory.simpleFormalParameter3("p"), null)); + } + + void test_visitDefaultFormalParameter_named_value() { + _assertSource( + "p : 0", + AstFactory.namedFormalParameter( + AstFactory.simpleFormalParameter3("p"), AstFactory.integer(0))); + } + + void test_visitDefaultFormalParameter_positional_noValue() { + _assertSource( + "p", + AstFactory.positionalFormalParameter( + AstFactory.simpleFormalParameter3("p"), null)); + } + + void test_visitDefaultFormalParameter_positional_value() { + _assertSource( + "p = 0", + AstFactory.positionalFormalParameter( + AstFactory.simpleFormalParameter3("p"), AstFactory.integer(0))); + } + + void test_visitDoStatement() { + _assertSource( + "do {} while (c);", + AstFactory.doStatement( + AstFactory.block(), AstFactory.identifier3("c"))); + } + + void test_visitDoubleLiteral() { + _assertSource("4.2", AstFactory.doubleLiteral(4.2)); + } + + void test_visitEmptyFunctionBody() { + _assertSource(";", AstFactory.emptyFunctionBody()); + } + + void test_visitEmptyStatement() { + _assertSource(";", AstFactory.emptyStatement()); + } + + void test_visitEnumDeclaration_multiple() { + _assertSource( + "enum E {ONE, TWO}", AstFactory.enumDeclaration2("E", ["ONE", "TWO"])); + } + + void test_visitEnumDeclaration_single() { + _assertSource("enum E {ONE}", AstFactory.enumDeclaration2("E", ["ONE"])); + } + + void test_visitExportDirective_combinator() { + _assertSource( + "export 'a.dart' show A;", + AstFactory.exportDirective2("a.dart", [ + AstFactory.showCombinator([AstFactory.identifier3("A")]) + ])); + } + + void test_visitExportDirective_combinators() { + _assertSource( + "export 'a.dart' show A hide B;", + AstFactory.exportDirective2("a.dart", [ + AstFactory.showCombinator([AstFactory.identifier3("A")]), + AstFactory.hideCombinator([AstFactory.identifier3("B")]) + ])); + } + + void test_visitExportDirective_minimal() { + _assertSource("export 'a.dart';", AstFactory.exportDirective2("a.dart")); + } + + void test_visitExportDirective_withMetadata() { + ExportDirective directive = AstFactory.exportDirective2("a.dart"); + directive.metadata + .add(AstFactory.annotation(AstFactory.identifier3("deprecated"))); + _assertSource("@deprecated export 'a.dart';", directive); + } + + void test_visitExpressionFunctionBody_async() { + _assertSource("async => a;", + AstFactory.asyncExpressionFunctionBody(AstFactory.identifier3("a"))); + } + + void test_visitExpressionFunctionBody_simple() { + _assertSource("=> a;", + AstFactory.expressionFunctionBody(AstFactory.identifier3("a"))); + } + + void test_visitExpressionStatement() { + _assertSource( + "a;", AstFactory.expressionStatement(AstFactory.identifier3("a"))); + } + + void test_visitExtendsClause() { + _assertSource( + "extends C", AstFactory.extendsClause(AstFactory.typeName4("C"))); + } + + void test_visitFieldDeclaration_instance() { + _assertSource( + "var a;", + AstFactory.fieldDeclaration2( + false, Keyword.VAR, [AstFactory.variableDeclaration("a")])); + } + + void test_visitFieldDeclaration_static() { + _assertSource( + "static var a;", + AstFactory.fieldDeclaration2( + true, Keyword.VAR, [AstFactory.variableDeclaration("a")])); + } + + void test_visitFieldDeclaration_withMetadata() { + FieldDeclaration declaration = AstFactory.fieldDeclaration2( + false, Keyword.VAR, [AstFactory.variableDeclaration("a")]); + declaration.metadata + .add(AstFactory.annotation(AstFactory.identifier3("deprecated"))); + _assertSource("@deprecated var a;", declaration); + } + + void test_visitFieldFormalParameter_annotation() { + FieldFormalParameter parameter = AstFactory.fieldFormalParameter2('f'); + parameter.metadata.add(AstFactory.annotation(AstFactory.identifier3("A"))); + _assertSource('@A this.f', parameter); + } + + void test_visitFieldFormalParameter_functionTyped() { + _assertSource( + "A this.a(b)", + AstFactory.fieldFormalParameter( + null, + AstFactory.typeName4("A"), + "a", + AstFactory.formalParameterList( + [AstFactory.simpleFormalParameter3("b")]))); + } + + void test_visitFieldFormalParameter_functionTyped_typeParameters() { + _assertSource( + "A this.a(b)", + new FieldFormalParameter( + null, + null, + null, + AstFactory.typeName4('A'), + TokenFactory.tokenFromKeyword(Keyword.THIS), + TokenFactory.tokenFromType(TokenType.PERIOD), + AstFactory.identifier3('a'), + AstFactory.typeParameterList(['E', 'F']), + AstFactory.formalParameterList( + [AstFactory.simpleFormalParameter3("b")]))); + } + + void test_visitFieldFormalParameter_keyword() { + _assertSource( + "var this.a", AstFactory.fieldFormalParameter(Keyword.VAR, null, "a")); + } + + void test_visitFieldFormalParameter_keywordAndType() { + _assertSource( + "final A this.a", + AstFactory.fieldFormalParameter( + Keyword.FINAL, AstFactory.typeName4("A"), "a")); + } + + void test_visitFieldFormalParameter_type() { + _assertSource("A this.a", + AstFactory.fieldFormalParameter(null, AstFactory.typeName4("A"), "a")); + } + + void test_visitForEachStatement_declared() { + _assertSource( + "for (var a in b) {}", + AstFactory.forEachStatement(AstFactory.declaredIdentifier3("a"), + AstFactory.identifier3("b"), AstFactory.block())); + } + + void test_visitForEachStatement_variable() { + _assertSource( + "for (a in b) {}", + new ForEachStatement.withReference( + null, + TokenFactory.tokenFromKeyword(Keyword.FOR), + TokenFactory.tokenFromType(TokenType.OPEN_PAREN), + AstFactory.identifier3("a"), + TokenFactory.tokenFromKeyword(Keyword.IN), + AstFactory.identifier3("b"), + TokenFactory.tokenFromType(TokenType.CLOSE_PAREN), + AstFactory.block())); + } + + void test_visitForEachStatement_variable_await() { + _assertSource( + "await for (a in b) {}", + new ForEachStatement.withReference( + TokenFactory.tokenFromString("await"), + TokenFactory.tokenFromKeyword(Keyword.FOR), + TokenFactory.tokenFromType(TokenType.OPEN_PAREN), + AstFactory.identifier3("a"), + TokenFactory.tokenFromKeyword(Keyword.IN), + AstFactory.identifier3("b"), + TokenFactory.tokenFromType(TokenType.CLOSE_PAREN), + AstFactory.block())); + } + + void test_visitFormalParameterList_empty() { + _assertSource("()", AstFactory.formalParameterList()); + } + + void test_visitFormalParameterList_n() { + _assertSource( + "({a : 0})", + AstFactory.formalParameterList([ + AstFactory.namedFormalParameter( + AstFactory.simpleFormalParameter3("a"), AstFactory.integer(0)) + ])); + } + + void test_visitFormalParameterList_nn() { + _assertSource( + "({a : 0, b : 1})", + AstFactory.formalParameterList([ + AstFactory.namedFormalParameter( + AstFactory.simpleFormalParameter3("a"), AstFactory.integer(0)), + AstFactory.namedFormalParameter( + AstFactory.simpleFormalParameter3("b"), AstFactory.integer(1)) + ])); + } + + void test_visitFormalParameterList_p() { + _assertSource( + "([a = 0])", + AstFactory.formalParameterList([ + AstFactory.positionalFormalParameter( + AstFactory.simpleFormalParameter3("a"), AstFactory.integer(0)) + ])); + } + + void test_visitFormalParameterList_pp() { + _assertSource( + "([a = 0, b = 1])", + AstFactory.formalParameterList([ + AstFactory.positionalFormalParameter( + AstFactory.simpleFormalParameter3("a"), AstFactory.integer(0)), + AstFactory.positionalFormalParameter( + AstFactory.simpleFormalParameter3("b"), AstFactory.integer(1)) + ])); + } + + void test_visitFormalParameterList_r() { + _assertSource( + "(a)", + AstFactory + .formalParameterList([AstFactory.simpleFormalParameter3("a")])); + } + + void test_visitFormalParameterList_rn() { + _assertSource( + "(a, {b : 1})", + AstFactory.formalParameterList([ + AstFactory.simpleFormalParameter3("a"), + AstFactory.namedFormalParameter( + AstFactory.simpleFormalParameter3("b"), AstFactory.integer(1)) + ])); + } + + void test_visitFormalParameterList_rnn() { + _assertSource( + "(a, {b : 1, c : 2})", + AstFactory.formalParameterList([ + AstFactory.simpleFormalParameter3("a"), + AstFactory.namedFormalParameter( + AstFactory.simpleFormalParameter3("b"), AstFactory.integer(1)), + AstFactory.namedFormalParameter( + AstFactory.simpleFormalParameter3("c"), AstFactory.integer(2)) + ])); + } + + void test_visitFormalParameterList_rp() { + _assertSource( + "(a, [b = 1])", + AstFactory.formalParameterList([ + AstFactory.simpleFormalParameter3("a"), + AstFactory.positionalFormalParameter( + AstFactory.simpleFormalParameter3("b"), AstFactory.integer(1)) + ])); + } + + void test_visitFormalParameterList_rpp() { + _assertSource( + "(a, [b = 1, c = 2])", + AstFactory.formalParameterList([ + AstFactory.simpleFormalParameter3("a"), + AstFactory.positionalFormalParameter( + AstFactory.simpleFormalParameter3("b"), AstFactory.integer(1)), + AstFactory.positionalFormalParameter( + AstFactory.simpleFormalParameter3("c"), AstFactory.integer(2)) + ])); + } + + void test_visitFormalParameterList_rr() { + _assertSource( + "(a, b)", + AstFactory.formalParameterList([ + AstFactory.simpleFormalParameter3("a"), + AstFactory.simpleFormalParameter3("b") + ])); + } + + void test_visitFormalParameterList_rrn() { + _assertSource( + "(a, b, {c : 3})", + AstFactory.formalParameterList([ + AstFactory.simpleFormalParameter3("a"), + AstFactory.simpleFormalParameter3("b"), + AstFactory.namedFormalParameter( + AstFactory.simpleFormalParameter3("c"), AstFactory.integer(3)) + ])); + } + + void test_visitFormalParameterList_rrnn() { + _assertSource( + "(a, b, {c : 3, d : 4})", + AstFactory.formalParameterList([ + AstFactory.simpleFormalParameter3("a"), + AstFactory.simpleFormalParameter3("b"), + AstFactory.namedFormalParameter( + AstFactory.simpleFormalParameter3("c"), AstFactory.integer(3)), + AstFactory.namedFormalParameter( + AstFactory.simpleFormalParameter3("d"), AstFactory.integer(4)) + ])); + } + + void test_visitFormalParameterList_rrp() { + _assertSource( + "(a, b, [c = 3])", + AstFactory.formalParameterList([ + AstFactory.simpleFormalParameter3("a"), + AstFactory.simpleFormalParameter3("b"), + AstFactory.positionalFormalParameter( + AstFactory.simpleFormalParameter3("c"), AstFactory.integer(3)) + ])); + } + + void test_visitFormalParameterList_rrpp() { + _assertSource( + "(a, b, [c = 3, d = 4])", + AstFactory.formalParameterList([ + AstFactory.simpleFormalParameter3("a"), + AstFactory.simpleFormalParameter3("b"), + AstFactory.positionalFormalParameter( + AstFactory.simpleFormalParameter3("c"), AstFactory.integer(3)), + AstFactory.positionalFormalParameter( + AstFactory.simpleFormalParameter3("d"), AstFactory.integer(4)) + ])); + } + + void test_visitForStatement_c() { + _assertSource( + "for (; c;) {}", + AstFactory.forStatement( + null, AstFactory.identifier3("c"), null, AstFactory.block())); + } + + void test_visitForStatement_cu() { + _assertSource( + "for (; c; u) {}", + AstFactory.forStatement(null, AstFactory.identifier3("c"), + [AstFactory.identifier3("u")], AstFactory.block())); + } + + void test_visitForStatement_e() { + _assertSource( + "for (e;;) {}", + AstFactory.forStatement( + AstFactory.identifier3("e"), null, null, AstFactory.block())); + } + + void test_visitForStatement_ec() { + _assertSource( + "for (e; c;) {}", + AstFactory.forStatement(AstFactory.identifier3("e"), + AstFactory.identifier3("c"), null, AstFactory.block())); + } + + void test_visitForStatement_ecu() { + _assertSource( + "for (e; c; u) {}", + AstFactory.forStatement( + AstFactory.identifier3("e"), + AstFactory.identifier3("c"), + [AstFactory.identifier3("u")], + AstFactory.block())); + } + + void test_visitForStatement_eu() { + _assertSource( + "for (e;; u) {}", + AstFactory.forStatement(AstFactory.identifier3("e"), null, + [AstFactory.identifier3("u")], AstFactory.block())); + } + + void test_visitForStatement_i() { + _assertSource( + "for (var i;;) {}", + AstFactory.forStatement2( + AstFactory.variableDeclarationList2( + Keyword.VAR, [AstFactory.variableDeclaration("i")]), + null, + null, + AstFactory.block())); + } + + void test_visitForStatement_ic() { + _assertSource( + "for (var i; c;) {}", + AstFactory.forStatement2( + AstFactory.variableDeclarationList2( + Keyword.VAR, [AstFactory.variableDeclaration("i")]), + AstFactory.identifier3("c"), + null, + AstFactory.block())); + } + + void test_visitForStatement_icu() { + _assertSource( + "for (var i; c; u) {}", + AstFactory.forStatement2( + AstFactory.variableDeclarationList2( + Keyword.VAR, [AstFactory.variableDeclaration("i")]), + AstFactory.identifier3("c"), + [AstFactory.identifier3("u")], + AstFactory.block())); + } + + void test_visitForStatement_iu() { + _assertSource( + "for (var i;; u) {}", + AstFactory.forStatement2( + AstFactory.variableDeclarationList2( + Keyword.VAR, [AstFactory.variableDeclaration("i")]), + null, + [AstFactory.identifier3("u")], + AstFactory.block())); + } + + void test_visitForStatement_u() { + _assertSource( + "for (;; u) {}", + AstFactory.forStatement( + null, null, [AstFactory.identifier3("u")], AstFactory.block())); + } + + void test_visitFunctionDeclaration_external() { + FunctionDeclaration functionDeclaration = AstFactory.functionDeclaration( + null, + null, + "f", + AstFactory.functionExpression2( + AstFactory.formalParameterList(), AstFactory.emptyFunctionBody())); + functionDeclaration.externalKeyword = + TokenFactory.tokenFromKeyword(Keyword.EXTERNAL); + _assertSource("external f();", functionDeclaration); + } + + void test_visitFunctionDeclaration_getter() { + _assertSource( + "get f() {}", + AstFactory.functionDeclaration( + null, Keyword.GET, "f", AstFactory.functionExpression())); + } + + void test_visitFunctionDeclaration_local_blockBody() { + FunctionDeclaration f = AstFactory.functionDeclaration( + null, null, "f", AstFactory.functionExpression()); + FunctionDeclarationStatement fStatement = + new FunctionDeclarationStatement(f); + _assertSource( + "main() {f() {} 42;}", + AstFactory.functionDeclaration( + null, + null, + "main", + AstFactory.functionExpression2( + AstFactory.formalParameterList(), + AstFactory.blockFunctionBody2([ + fStatement, + AstFactory.expressionStatement(AstFactory.integer(42)) + ])))); + } + + void test_visitFunctionDeclaration_local_expressionBody() { + FunctionDeclaration f = AstFactory.functionDeclaration( + null, + null, + "f", + AstFactory.functionExpression2(AstFactory.formalParameterList(), + AstFactory.expressionFunctionBody(AstFactory.integer(1)))); + FunctionDeclarationStatement fStatement = + new FunctionDeclarationStatement(f); + _assertSource( + "main() {f() => 1; 2;}", + AstFactory.functionDeclaration( + null, + null, + "main", + AstFactory.functionExpression2( + AstFactory.formalParameterList(), + AstFactory.blockFunctionBody2([ + fStatement, + AstFactory.expressionStatement(AstFactory.integer(2)) + ])))); + } + + void test_visitFunctionDeclaration_normal() { + _assertSource( + "f() {}", + AstFactory.functionDeclaration( + null, null, "f", AstFactory.functionExpression())); + } + + void test_visitFunctionDeclaration_setter() { + _assertSource( + "set f() {}", + AstFactory.functionDeclaration( + null, Keyword.SET, "f", AstFactory.functionExpression())); + } + + void test_visitFunctionDeclaration_typeParameters() { + _assertSource( + "f() {}", + AstFactory.functionDeclaration( + null, + null, + "f", + AstFactory.functionExpression3( + AstFactory.typeParameterList(['E']), + AstFactory.formalParameterList(), + AstFactory.blockFunctionBody2()))); + } + + void test_visitFunctionDeclaration_withMetadata() { + FunctionDeclaration declaration = AstFactory.functionDeclaration( + null, null, "f", AstFactory.functionExpression()); + declaration.metadata + .add(AstFactory.annotation(AstFactory.identifier3("deprecated"))); + _assertSource("@deprecated f() {}", declaration); + } + + void test_visitFunctionDeclarationStatement() { + _assertSource( + "f() {}", + AstFactory.functionDeclarationStatement( + null, null, "f", AstFactory.functionExpression())); + } + + void test_visitFunctionExpression() { + _assertSource("() {}", AstFactory.functionExpression()); + } + + void test_visitFunctionExpression_typeParameters() { + _assertSource( + "() {}", + AstFactory.functionExpression3(AstFactory.typeParameterList(['E']), + AstFactory.formalParameterList(), AstFactory.blockFunctionBody2())); + } + + void test_visitFunctionExpressionInvocation_minimal() { + _assertSource("f()", + AstFactory.functionExpressionInvocation(AstFactory.identifier3("f"))); + } + + void test_visitFunctionExpressionInvocation_typeArguments() { + _assertSource( + "f()", + AstFactory.functionExpressionInvocation2(AstFactory.identifier3("f"), + AstFactory.typeArgumentList([AstFactory.typeName4('A')]))); + } + + void test_visitFunctionTypeAlias_generic() { + _assertSource( + "typedef A F();", + AstFactory.typeAlias( + AstFactory.typeName4("A"), + "F", + AstFactory.typeParameterList(["B"]), + AstFactory.formalParameterList())); + } + + void test_visitFunctionTypeAlias_nonGeneric() { + _assertSource( + "typedef A F();", + AstFactory.typeAlias(AstFactory.typeName4("A"), "F", null, + AstFactory.formalParameterList())); + } + + void test_visitFunctionTypeAlias_withMetadata() { + FunctionTypeAlias declaration = AstFactory.typeAlias( + AstFactory.typeName4("A"), "F", null, AstFactory.formalParameterList()); + declaration.metadata + .add(AstFactory.annotation(AstFactory.identifier3("deprecated"))); + _assertSource("@deprecated typedef A F();", declaration); + } + + void test_visitFunctionTypedFormalParameter_annotation() { + FunctionTypedFormalParameter parameter = + AstFactory.functionTypedFormalParameter(null, "f"); + parameter.metadata.add(AstFactory.annotation(AstFactory.identifier3("A"))); + _assertSource('@A f()', parameter); + } + + void test_visitFunctionTypedFormalParameter_noType() { + _assertSource("f()", AstFactory.functionTypedFormalParameter(null, "f")); + } + + void test_visitFunctionTypedFormalParameter_type() { + _assertSource( + "T f()", + AstFactory.functionTypedFormalParameter( + AstFactory.typeName4("T"), "f")); + } + + void test_visitFunctionTypedFormalParameter_typeParameters() { + _assertSource( + "T f()", + new FunctionTypedFormalParameter( + null, + null, + AstFactory.typeName4("T"), + AstFactory.identifier3('f'), + AstFactory.typeParameterList(['E']), + AstFactory.formalParameterList([]))); + } + + void test_visitIfStatement_withElse() { + _assertSource( + "if (c) {} else {}", + AstFactory.ifStatement2(AstFactory.identifier3("c"), AstFactory.block(), + AstFactory.block())); + } + + void test_visitIfStatement_withoutElse() { + _assertSource( + "if (c) {}", + AstFactory.ifStatement( + AstFactory.identifier3("c"), AstFactory.block())); + } + + void test_visitImplementsClause_multiple() { + _assertSource( + "implements A, B", + AstFactory.implementsClause( + [AstFactory.typeName4("A"), AstFactory.typeName4("B")])); + } + + void test_visitImplementsClause_single() { + _assertSource("implements A", + AstFactory.implementsClause([AstFactory.typeName4("A")])); + } + + void test_visitImportDirective_combinator() { + _assertSource( + "import 'a.dart' show A;", + AstFactory.importDirective3("a.dart", null, [ + AstFactory.showCombinator([AstFactory.identifier3("A")]) + ])); + } + + void test_visitImportDirective_combinators() { + _assertSource( + "import 'a.dart' show A hide B;", + AstFactory.importDirective3("a.dart", null, [ + AstFactory.showCombinator([AstFactory.identifier3("A")]), + AstFactory.hideCombinator([AstFactory.identifier3("B")]) + ])); + } + + void test_visitImportDirective_deferred() { + _assertSource("import 'a.dart' deferred as p;", + AstFactory.importDirective2("a.dart", true, "p")); + } + + void test_visitImportDirective_minimal() { + _assertSource( + "import 'a.dart';", AstFactory.importDirective3("a.dart", null)); + } + + void test_visitImportDirective_prefix() { + _assertSource( + "import 'a.dart' as p;", AstFactory.importDirective3("a.dart", "p")); + } + + void test_visitImportDirective_prefix_combinator() { + _assertSource( + "import 'a.dart' as p show A;", + AstFactory.importDirective3("a.dart", "p", [ + AstFactory.showCombinator([AstFactory.identifier3("A")]) + ])); + } + + void test_visitImportDirective_prefix_combinators() { + _assertSource( + "import 'a.dart' as p show A hide B;", + AstFactory.importDirective3("a.dart", "p", [ + AstFactory.showCombinator([AstFactory.identifier3("A")]), + AstFactory.hideCombinator([AstFactory.identifier3("B")]) + ])); + } + + void test_visitImportDirective_withMetadata() { + ImportDirective directive = AstFactory.importDirective3("a.dart", null); + directive.metadata + .add(AstFactory.annotation(AstFactory.identifier3("deprecated"))); + _assertSource("@deprecated import 'a.dart';", directive); + } + + void test_visitImportHideCombinator_multiple() { + _assertSource( + "hide a, b", + AstFactory.hideCombinator( + [AstFactory.identifier3("a"), AstFactory.identifier3("b")])); + } + + void test_visitImportHideCombinator_single() { + _assertSource( + "hide a", AstFactory.hideCombinator([AstFactory.identifier3("a")])); + } + + void test_visitImportShowCombinator_multiple() { + _assertSource( + "show a, b", + AstFactory.showCombinator( + [AstFactory.identifier3("a"), AstFactory.identifier3("b")])); + } + + void test_visitImportShowCombinator_single() { + _assertSource( + "show a", AstFactory.showCombinator([AstFactory.identifier3("a")])); + } + + void test_visitIndexExpression() { + _assertSource( + "a[i]", + AstFactory.indexExpression( + AstFactory.identifier3("a"), AstFactory.identifier3("i"))); + } + + void test_visitInstanceCreationExpression_const() { + _assertSource( + "const C()", + AstFactory.instanceCreationExpression2( + Keyword.CONST, AstFactory.typeName4("C"))); + } + + void test_visitInstanceCreationExpression_named() { + _assertSource( + "new C.c()", + AstFactory.instanceCreationExpression3( + Keyword.NEW, AstFactory.typeName4("C"), "c")); + } + + void test_visitInstanceCreationExpression_unnamed() { + _assertSource( + "new C()", + AstFactory.instanceCreationExpression2( + Keyword.NEW, AstFactory.typeName4("C"))); + } + + void test_visitIntegerLiteral() { + _assertSource("42", AstFactory.integer(42)); + } + + void test_visitInterpolationExpression_expression() { + _assertSource("\${a}", + AstFactory.interpolationExpression(AstFactory.identifier3("a"))); + } + + void test_visitInterpolationExpression_identifier() { + _assertSource("\$a", AstFactory.interpolationExpression2("a")); + } + + void test_visitInterpolationString() { + _assertSource("'x", AstFactory.interpolationString("'x", "x")); + } + + void test_visitIsExpression_negated() { + _assertSource( + "a is! C", + AstFactory.isExpression( + AstFactory.identifier3("a"), true, AstFactory.typeName4("C"))); + } + + void test_visitIsExpression_normal() { + _assertSource( + "a is C", + AstFactory.isExpression( + AstFactory.identifier3("a"), false, AstFactory.typeName4("C"))); + } + + void test_visitLabel() { + _assertSource("a:", AstFactory.label2("a")); + } + + void test_visitLabeledStatement_multiple() { + _assertSource( + "a: b: return;", + AstFactory.labeledStatement( + [AstFactory.label2("a"), AstFactory.label2("b")], + AstFactory.returnStatement())); + } + + void test_visitLabeledStatement_single() { + _assertSource( + "a: return;", + AstFactory.labeledStatement( + [AstFactory.label2("a")], AstFactory.returnStatement())); + } + + void test_visitLibraryDirective() { + _assertSource("library l;", AstFactory.libraryDirective2("l")); + } + + void test_visitLibraryDirective_withMetadata() { + LibraryDirective directive = AstFactory.libraryDirective2("l"); + directive.metadata + .add(AstFactory.annotation(AstFactory.identifier3("deprecated"))); + _assertSource("@deprecated library l;", directive); + } + + void test_visitLibraryIdentifier_multiple() { + _assertSource( + "a.b.c", + AstFactory.libraryIdentifier([ + AstFactory.identifier3("a"), + AstFactory.identifier3("b"), + AstFactory.identifier3("c") + ])); + } + + void test_visitLibraryIdentifier_single() { + _assertSource( + "a", AstFactory.libraryIdentifier([AstFactory.identifier3("a")])); + } + + void test_visitListLiteral_const() { + _assertSource("const []", AstFactory.listLiteral2(Keyword.CONST, null)); + } + + void test_visitListLiteral_empty() { + _assertSource("[]", AstFactory.listLiteral()); + } + + void test_visitListLiteral_nonEmpty() { + _assertSource( + "[a, b, c]", + AstFactory.listLiteral([ + AstFactory.identifier3("a"), + AstFactory.identifier3("b"), + AstFactory.identifier3("c") + ])); + } + + void test_visitMapLiteral_const() { + _assertSource("const {}", AstFactory.mapLiteral(Keyword.CONST, null)); + } + + void test_visitMapLiteral_empty() { + _assertSource("{}", AstFactory.mapLiteral2()); + } + + void test_visitMapLiteral_nonEmpty() { + _assertSource( + "{'a' : a, 'b' : b, 'c' : c}", + AstFactory.mapLiteral2([ + AstFactory.mapLiteralEntry("a", AstFactory.identifier3("a")), + AstFactory.mapLiteralEntry("b", AstFactory.identifier3("b")), + AstFactory.mapLiteralEntry("c", AstFactory.identifier3("c")) + ])); + } + + void test_visitMapLiteralEntry() { + _assertSource("'a' : b", + AstFactory.mapLiteralEntry("a", AstFactory.identifier3("b"))); + } + + void test_visitMethodDeclaration_external() { + _assertSource( + "external m();", + AstFactory.methodDeclaration(null, null, null, null, + AstFactory.identifier3("m"), AstFactory.formalParameterList())); + } + + void test_visitMethodDeclaration_external_returnType() { + _assertSource( + "external T m();", + AstFactory.methodDeclaration( + null, + AstFactory.typeName4("T"), + null, + null, + AstFactory.identifier3("m"), + AstFactory.formalParameterList())); + } + + void test_visitMethodDeclaration_getter() { + _assertSource( + "get m {}", + AstFactory.methodDeclaration2( + null, + null, + Keyword.GET, + null, + AstFactory.identifier3("m"), + null, + AstFactory.blockFunctionBody2())); + } + + void test_visitMethodDeclaration_getter_returnType() { + _assertSource( + "T get m {}", + AstFactory.methodDeclaration2( + null, + AstFactory.typeName4("T"), + Keyword.GET, + null, + AstFactory.identifier3("m"), + null, + AstFactory.blockFunctionBody2())); + } + + void test_visitMethodDeclaration_getter_seturnType() { + _assertSource( + "T set m(var v) {}", + AstFactory.methodDeclaration2( + null, + AstFactory.typeName4("T"), + Keyword.SET, + null, + AstFactory.identifier3("m"), + AstFactory.formalParameterList( + [AstFactory.simpleFormalParameter(Keyword.VAR, "v")]), + AstFactory.blockFunctionBody2())); + } + + void test_visitMethodDeclaration_minimal() { + _assertSource( + "m() {}", + AstFactory.methodDeclaration2( + null, + null, + null, + null, + AstFactory.identifier3("m"), + AstFactory.formalParameterList(), + AstFactory.blockFunctionBody2())); + } + + void test_visitMethodDeclaration_multipleParameters() { + _assertSource( + "m(var a, var b) {}", + AstFactory.methodDeclaration2( + null, + null, + null, + null, + AstFactory.identifier3("m"), + AstFactory.formalParameterList([ + AstFactory.simpleFormalParameter(Keyword.VAR, "a"), + AstFactory.simpleFormalParameter(Keyword.VAR, "b") + ]), + AstFactory.blockFunctionBody2())); + } + + void test_visitMethodDeclaration_operator() { + _assertSource( + "operator +() {}", + AstFactory.methodDeclaration2( + null, + null, + null, + Keyword.OPERATOR, + AstFactory.identifier3("+"), + AstFactory.formalParameterList(), + AstFactory.blockFunctionBody2())); + } + + void test_visitMethodDeclaration_operator_returnType() { + _assertSource( + "T operator +() {}", + AstFactory.methodDeclaration2( + null, + AstFactory.typeName4("T"), + null, + Keyword.OPERATOR, + AstFactory.identifier3("+"), + AstFactory.formalParameterList(), + AstFactory.blockFunctionBody2())); + } + + void test_visitMethodDeclaration_returnType() { + _assertSource( + "T m() {}", + AstFactory.methodDeclaration2( + null, + AstFactory.typeName4("T"), + null, + null, + AstFactory.identifier3("m"), + AstFactory.formalParameterList(), + AstFactory.blockFunctionBody2())); + } + + void test_visitMethodDeclaration_setter() { + _assertSource( + "set m(var v) {}", + AstFactory.methodDeclaration2( + null, + null, + Keyword.SET, + null, + AstFactory.identifier3("m"), + AstFactory.formalParameterList( + [AstFactory.simpleFormalParameter(Keyword.VAR, "v")]), + AstFactory.blockFunctionBody2())); + } + + void test_visitMethodDeclaration_static() { + _assertSource( + "static m() {}", + AstFactory.methodDeclaration2( + Keyword.STATIC, + null, + null, + null, + AstFactory.identifier3("m"), + AstFactory.formalParameterList(), + AstFactory.blockFunctionBody2())); + } + + void test_visitMethodDeclaration_static_returnType() { + _assertSource( + "static T m() {}", + AstFactory.methodDeclaration2( + Keyword.STATIC, + AstFactory.typeName4("T"), + null, + null, + AstFactory.identifier3("m"), + AstFactory.formalParameterList(), + AstFactory.blockFunctionBody2())); + } + + void test_visitMethodDeclaration_typeParameters() { + _assertSource( + "m() {}", + AstFactory.methodDeclaration3( + null, + null, + null, + null, + AstFactory.identifier3("m"), + AstFactory.typeParameterList(['E']), + AstFactory.formalParameterList(), + AstFactory.blockFunctionBody2())); + } + + void test_visitMethodDeclaration_withMetadata() { + MethodDeclaration declaration = AstFactory.methodDeclaration2( + null, + null, + null, + null, + AstFactory.identifier3("m"), + AstFactory.formalParameterList(), + AstFactory.blockFunctionBody2()); + declaration.metadata + .add(AstFactory.annotation(AstFactory.identifier3("deprecated"))); + _assertSource("@deprecated m() {}", declaration); + } + + void test_visitMethodInvocation_conditional() { + _assertSource( + "t?.m()", + AstFactory.methodInvocation( + AstFactory.identifier3("t"), "m", null, TokenType.QUESTION_PERIOD)); + } + + void test_visitMethodInvocation_noTarget() { + _assertSource("m()", AstFactory.methodInvocation2("m")); + } + + void test_visitMethodInvocation_target() { + _assertSource( + "t.m()", AstFactory.methodInvocation(AstFactory.identifier3("t"), "m")); + } + + void test_visitMethodInvocation_typeArguments() { + _assertSource( + "m()", + AstFactory.methodInvocation3(null, "m", + AstFactory.typeArgumentList([AstFactory.typeName4('A')]))); + } + + void test_visitNamedExpression() { + _assertSource( + "a: b", AstFactory.namedExpression2("a", AstFactory.identifier3("b"))); + } + + void test_visitNamedFormalParameter() { + _assertSource( + "var a : 0", + AstFactory.namedFormalParameter( + AstFactory.simpleFormalParameter(Keyword.VAR, "a"), + AstFactory.integer(0))); + } + + void test_visitNativeClause() { + _assertSource("native 'code'", AstFactory.nativeClause("code")); + } + + void test_visitNativeFunctionBody() { + _assertSource("native 'str';", AstFactory.nativeFunctionBody("str")); + } + + void test_visitNullLiteral() { + _assertSource("null", AstFactory.nullLiteral()); + } + + void test_visitParenthesizedExpression() { + _assertSource( + "(a)", AstFactory.parenthesizedExpression(AstFactory.identifier3("a"))); + } + + void test_visitPartDirective() { + _assertSource("part 'a.dart';", AstFactory.partDirective2("a.dart")); + } + + void test_visitPartDirective_withMetadata() { + PartDirective directive = AstFactory.partDirective2("a.dart"); + directive.metadata + .add(AstFactory.annotation(AstFactory.identifier3("deprecated"))); + _assertSource("@deprecated part 'a.dart';", directive); + } + + void test_visitPartOfDirective() { + _assertSource("part of l;", + AstFactory.partOfDirective(AstFactory.libraryIdentifier2(["l"]))); + } + + void test_visitPartOfDirective_withMetadata() { + PartOfDirective directive = + AstFactory.partOfDirective(AstFactory.libraryIdentifier2(["l"])); + directive.metadata + .add(AstFactory.annotation(AstFactory.identifier3("deprecated"))); + _assertSource("@deprecated part of l;", directive); + } + + void test_visitPositionalFormalParameter() { + _assertSource( + "var a = 0", + AstFactory.positionalFormalParameter( + AstFactory.simpleFormalParameter(Keyword.VAR, "a"), + AstFactory.integer(0))); + } + + void test_visitPostfixExpression() { + _assertSource( + "a++", + AstFactory.postfixExpression( + AstFactory.identifier3("a"), TokenType.PLUS_PLUS)); + } + + void test_visitPrefixedIdentifier() { + _assertSource("a.b", AstFactory.identifier5("a", "b")); + } + + void test_visitPrefixExpression() { + _assertSource( + "-a", + AstFactory.prefixExpression( + TokenType.MINUS, AstFactory.identifier3("a"))); + } + + void test_visitPropertyAccess() { + _assertSource( + "a.b", AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b")); + } + + void test_visitPropertyAccess_conditional() { + _assertSource( + "a?.b", + AstFactory.propertyAccess2( + AstFactory.identifier3("a"), "b", TokenType.QUESTION_PERIOD)); + } + + void test_visitRedirectingConstructorInvocation_named() { + _assertSource( + "this.c()", AstFactory.redirectingConstructorInvocation2("c")); + } + + void test_visitRedirectingConstructorInvocation_unnamed() { + _assertSource("this()", AstFactory.redirectingConstructorInvocation()); + } + + void test_visitRethrowExpression() { + _assertSource("rethrow", AstFactory.rethrowExpression()); + } + + void test_visitReturnStatement_expression() { + _assertSource( + "return a;", AstFactory.returnStatement2(AstFactory.identifier3("a"))); + } + + void test_visitReturnStatement_noExpression() { + _assertSource("return;", AstFactory.returnStatement()); + } + + void test_visitScriptTag() { + String scriptTag = "!#/bin/dart.exe"; + _assertSource(scriptTag, AstFactory.scriptTag(scriptTag)); + } + + void test_visitSimpleFormalParameter_annotation() { + SimpleFormalParameter parameter = AstFactory.simpleFormalParameter3('x'); + parameter.metadata.add(AstFactory.annotation(AstFactory.identifier3("A"))); + _assertSource('@A x', parameter); + } + + void test_visitSimpleFormalParameter_keyword() { + _assertSource("var a", AstFactory.simpleFormalParameter(Keyword.VAR, "a")); + } + + void test_visitSimpleFormalParameter_keyword_type() { + _assertSource( + "final A a", + AstFactory.simpleFormalParameter2( + Keyword.FINAL, AstFactory.typeName4("A"), "a")); + } + + void test_visitSimpleFormalParameter_type() { + _assertSource("A a", + AstFactory.simpleFormalParameter4(AstFactory.typeName4("A"), "a")); + } + + void test_visitSimpleIdentifier() { + _assertSource("a", AstFactory.identifier3("a")); + } + + void test_visitSimpleStringLiteral() { + _assertSource("'a'", AstFactory.string2("a")); + } + + void test_visitStringInterpolation() { + _assertSource( + "'a\${e}b'", + AstFactory.string([ + AstFactory.interpolationString("'a", "a"), + AstFactory.interpolationExpression(AstFactory.identifier3("e")), + AstFactory.interpolationString("b'", "b") + ])); + } + + void test_visitSuperConstructorInvocation() { + _assertSource("super()", AstFactory.superConstructorInvocation()); + } + + void test_visitSuperConstructorInvocation_named() { + _assertSource("super.c()", AstFactory.superConstructorInvocation2("c")); + } + + void test_visitSuperExpression() { + _assertSource("super", AstFactory.superExpression()); + } + + void test_visitSwitchCase_multipleLabels() { + _assertSource( + "l1: l2: case a: {}", + AstFactory.switchCase2( + [AstFactory.label2("l1"), AstFactory.label2("l2")], + AstFactory.identifier3("a"), + [AstFactory.block()])); + } + + void test_visitSwitchCase_multipleStatements() { + _assertSource( + "case a: {} {}", + AstFactory.switchCase(AstFactory.identifier3("a"), + [AstFactory.block(), AstFactory.block()])); + } + + void test_visitSwitchCase_noLabels() { + _assertSource( + "case a: {}", + AstFactory + .switchCase(AstFactory.identifier3("a"), [AstFactory.block()])); + } + + void test_visitSwitchCase_singleLabel() { + _assertSource( + "l1: case a: {}", + AstFactory.switchCase2([AstFactory.label2("l1")], + AstFactory.identifier3("a"), [AstFactory.block()])); + } + + void test_visitSwitchDefault_multipleLabels() { + _assertSource( + "l1: l2: default: {}", + AstFactory.switchDefault( + [AstFactory.label2("l1"), AstFactory.label2("l2")], + [AstFactory.block()])); + } + + void test_visitSwitchDefault_multipleStatements() { + _assertSource("default: {} {}", + AstFactory.switchDefault2([AstFactory.block(), AstFactory.block()])); + } + + void test_visitSwitchDefault_noLabels() { + _assertSource( + "default: {}", AstFactory.switchDefault2([AstFactory.block()])); + } + + void test_visitSwitchDefault_singleLabel() { + _assertSource( + "l1: default: {}", + AstFactory + .switchDefault([AstFactory.label2("l1")], [AstFactory.block()])); + } + + void test_visitSwitchStatement() { + _assertSource( + "switch (a) {case 'b': {} default: {}}", + AstFactory.switchStatement(AstFactory.identifier3("a"), [ + AstFactory.switchCase(AstFactory.string2("b"), [AstFactory.block()]), + AstFactory.switchDefault2([AstFactory.block()]) + ])); + } + + void test_visitSymbolLiteral_multiple() { + _assertSource("#a.b.c", AstFactory.symbolLiteral(["a", "b", "c"])); + } + + void test_visitSymbolLiteral_single() { + _assertSource("#a", AstFactory.symbolLiteral(["a"])); + } + + void test_visitThisExpression() { + _assertSource("this", AstFactory.thisExpression()); + } + + void test_visitThrowStatement() { + _assertSource( + "throw e", AstFactory.throwExpression2(AstFactory.identifier3("e"))); + } + + void test_visitTopLevelVariableDeclaration_multiple() { + _assertSource( + "var a;", + AstFactory.topLevelVariableDeclaration2( + Keyword.VAR, [AstFactory.variableDeclaration("a")])); + } + + void test_visitTopLevelVariableDeclaration_single() { + _assertSource( + "var a, b;", + AstFactory.topLevelVariableDeclaration2(Keyword.VAR, [ + AstFactory.variableDeclaration("a"), + AstFactory.variableDeclaration("b") + ])); + } + + void test_visitTryStatement_catch() { + _assertSource( + "try {} on E {}", + AstFactory.tryStatement2(AstFactory.block(), + [AstFactory.catchClause3(AstFactory.typeName4("E"))])); + } + + void test_visitTryStatement_catches() { + _assertSource( + "try {} on E {} on F {}", + AstFactory.tryStatement2(AstFactory.block(), [ + AstFactory.catchClause3(AstFactory.typeName4("E")), + AstFactory.catchClause3(AstFactory.typeName4("F")) + ])); + } + + void test_visitTryStatement_catchFinally() { + _assertSource( + "try {} on E {} finally {}", + AstFactory.tryStatement3( + AstFactory.block(), + [AstFactory.catchClause3(AstFactory.typeName4("E"))], + AstFactory.block())); + } + + void test_visitTryStatement_finally() { + _assertSource("try {} finally {}", + AstFactory.tryStatement(AstFactory.block(), AstFactory.block())); + } + + void test_visitTypeArgumentList_multiple() { + _assertSource( + "", + AstFactory.typeArgumentList( + [AstFactory.typeName4("E"), AstFactory.typeName4("F")])); + } + + void test_visitTypeArgumentList_single() { + _assertSource( + "", AstFactory.typeArgumentList([AstFactory.typeName4("E")])); + } + + void test_visitTypeName_multipleArgs() { + _assertSource( + "C", + AstFactory.typeName4( + "C", [AstFactory.typeName4("D"), AstFactory.typeName4("E")])); + } + + void test_visitTypeName_nestedArg() { + _assertSource( + "C>", + AstFactory.typeName4("C", [ + AstFactory.typeName4("D", [AstFactory.typeName4("E")]) + ])); + } + + void test_visitTypeName_noArgs() { + _assertSource("C", AstFactory.typeName4("C")); + } + + void test_visitTypeName_singleArg() { + _assertSource( + "C", AstFactory.typeName4("C", [AstFactory.typeName4("D")])); + } + + void test_visitTypeParameter_withExtends() { + _assertSource("E extends C", + AstFactory.typeParameter2("E", AstFactory.typeName4("C"))); + } + + void test_visitTypeParameter_withMetadata() { + TypeParameter parameter = AstFactory.typeParameter("E"); + parameter.metadata + .add(AstFactory.annotation(AstFactory.identifier3("deprecated"))); + _assertSource("@deprecated E", parameter); + } + + void test_visitTypeParameter_withoutExtends() { + _assertSource("E", AstFactory.typeParameter("E")); + } + + void test_visitTypeParameterList_multiple() { + _assertSource("", AstFactory.typeParameterList(["E", "F"])); + } + + void test_visitTypeParameterList_single() { + _assertSource("", AstFactory.typeParameterList(["E"])); + } + + void test_visitVariableDeclaration_initialized() { + _assertSource("a = b", + AstFactory.variableDeclaration2("a", AstFactory.identifier3("b"))); + } + + void test_visitVariableDeclaration_uninitialized() { + _assertSource("a", AstFactory.variableDeclaration("a")); + } + + void test_visitVariableDeclaration_withMetadata() { + VariableDeclaration declaration = AstFactory.variableDeclaration("a"); + declaration.metadata + .add(AstFactory.annotation(AstFactory.identifier3("deprecated"))); + _assertSource("@deprecated a", declaration); + } + + void test_visitVariableDeclarationList_const_type() { + _assertSource( + "const C a, b", + AstFactory.variableDeclarationList( + Keyword.CONST, AstFactory.typeName4("C"), [ + AstFactory.variableDeclaration("a"), + AstFactory.variableDeclaration("b") + ])); + } + + void test_visitVariableDeclarationList_final_noType() { + _assertSource( + "final a, b", + AstFactory.variableDeclarationList2(Keyword.FINAL, [ + AstFactory.variableDeclaration("a"), + AstFactory.variableDeclaration("b") + ])); + } + + void test_visitVariableDeclarationList_final_withMetadata() { + VariableDeclarationList declarationList = AstFactory + .variableDeclarationList2(Keyword.FINAL, [ + AstFactory.variableDeclaration("a"), + AstFactory.variableDeclaration("b") + ]); + declarationList.metadata + .add(AstFactory.annotation(AstFactory.identifier3("deprecated"))); + _assertSource("@deprecated final a, b", declarationList); + } + + void test_visitVariableDeclarationList_type() { + _assertSource( + "C a, b", + AstFactory.variableDeclarationList(null, AstFactory.typeName4("C"), [ + AstFactory.variableDeclaration("a"), + AstFactory.variableDeclaration("b") + ])); + } + + void test_visitVariableDeclarationList_var() { + _assertSource( + "var a, b", + AstFactory.variableDeclarationList2(Keyword.VAR, [ + AstFactory.variableDeclaration("a"), + AstFactory.variableDeclaration("b") + ])); + } + + void test_visitVariableDeclarationStatement() { + _assertSource( + "C c;", + AstFactory.variableDeclarationStatement(null, AstFactory.typeName4("C"), + [AstFactory.variableDeclaration("c")])); + } + + void test_visitWhileStatement() { + _assertSource( + "while (c) {}", + AstFactory.whileStatement( + AstFactory.identifier3("c"), AstFactory.block())); + } + + void test_visitWithClause_multiple() { + _assertSource( + "with A, B, C", + AstFactory.withClause([ + AstFactory.typeName4("A"), + AstFactory.typeName4("B"), + AstFactory.typeName4("C") + ])); + } + + void test_visitWithClause_single() { + _assertSource("with A", AstFactory.withClause([AstFactory.typeName4("A")])); + } + + void test_visitYieldStatement() { + _assertSource( + "yield e;", AstFactory.yieldStatement(AstFactory.identifier3("e"))); + } + + void test_visitYieldStatement_each() { + _assertSource("yield* e;", + AstFactory.yieldEachStatement(AstFactory.identifier3("e"))); + } + + /** + * Assert that a `ToSourceVisitor2` will produce the [expectedSource] when + * visiting the given [node]. + */ + void _assertSource(String expectedSource, AstNode node) { + StringBuffer buffer = new StringBuffer(); + node.accept(new ToSourceVisitor2(buffer)); + expect(buffer.toString(), expectedSource); + } +} + @reflectiveTest class ToSourceVisitorTest extends EngineTestCase { void test_visitAdjacentStrings() { @@ -3333,12 +5569,8 @@ class ToSourceVisitorTest extends EngineTestCase { } /** - * Assert that a `ToSourceVisitor` will produce the expected source when visiting the given - * node. - * - * @param expectedSource the source string that the visitor is expected to produce - * @param node the AST node being visited to produce the actual source - * @throws AFE if the visitor does not produce the expected source for the given node + * Assert that a `ToSourceVisitor` will produce the [expectedSource] when + * visiting the given [node]. */ void _assertSource(String expectedSource, AstNode node) { PrintStringWriter writer = new PrintStringWriter();