| // Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file |
| // 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. |
| |
| import 'package:analyzer/dart/ast/doc_comment.dart'; |
| import 'package:analyzer/dart/ast/syntactic_entity.dart'; |
| import 'package:analyzer/dart/ast/token.dart'; |
| import 'package:analyzer/dart/ast/visitor.dart'; |
| import 'package:analyzer/dart/element/element2.dart'; |
| import 'package:analyzer/dart/element/type.dart'; |
| import 'package:analyzer/src/dart/ast/ast.dart'; |
| import 'package:analyzer/src/dart/ast/extensions.dart'; |
| import 'package:analyzer/src/dart/element/element.dart'; |
| import 'package:analyzer/src/utilities/extensions/string.dart'; |
| import 'package:analyzer_utilities/testing/tree_string_sink.dart'; |
| import 'package:test/test.dart'; |
| |
| import '../../util/element_printer.dart'; |
| |
| /// Prints AST as a tree, with properties and children. |
| class ResolvedAstPrinter extends ThrowingAstVisitor<void> { |
| final TreeStringSink _sink; |
| final ElementPrinter _elementPrinter; |
| final ResolvedNodeTextConfiguration configuration; |
| |
| /// If `true`, selected tokens and nodes should be printed with offsets. |
| final bool _withOffsets; |
| |
| /// If `true`, resolution should be printed. |
| final bool _withResolution; |
| |
| final Map<Token, String> _tokenIdMap = Map.identity(); |
| |
| ResolvedAstPrinter({ |
| required TreeStringSink sink, |
| required ElementPrinter elementPrinter, |
| required this.configuration, |
| bool withOffsets = false, |
| bool withResolution = true, |
| }) : _sink = sink, |
| _elementPrinter = elementPrinter, |
| _withOffsets = withOffsets, |
| _withResolution = withResolution; |
| |
| @override |
| void visitAdjacentStrings(AdjacentStrings node) { |
| _sink.writeln('AdjacentStrings'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| _writeRaw('stringValue', node.stringValue); |
| }); |
| } |
| |
| @override |
| void visitAnnotation(Annotation node) { |
| _sink.writeln('Annotation'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeElement2('element2', node.element2); |
| }); |
| } |
| |
| @override |
| void visitArgumentList(ArgumentList node) { |
| _sink.writeln('ArgumentList'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitAsExpression(AsExpression node) { |
| _sink.writeln('AsExpression'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitAssertInitializer(AssertInitializer node) { |
| _sink.writeln('AssertInitializer'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitAssertStatement(AssertStatement node) { |
| _sink.writeln('AssertStatement'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitAssignedVariablePattern( |
| covariant AssignedVariablePatternImpl node, |
| ) { |
| _sink.writeln('AssignedVariablePattern'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| if (_withResolution) { |
| _writeElement2('element2', node.element2); |
| _writePatternMatchedValueType(node); |
| } |
| }); |
| } |
| |
| @override |
| void visitAssignmentExpression(AssignmentExpression node) { |
| _sink.writeln('AssignmentExpression'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeElement2('readElement2', node.readElement2); |
| _writeType('readType', node.readType); |
| _writeElement2('writeElement2', node.writeElement2); |
| _writeType('writeType', node.writeType); |
| _writeElement2('element', node.element); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitAugmentedExpression(AugmentedExpression node) { |
| _sink.writeln('AugmentedExpression'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeFragment('fragment', node.fragment); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitAugmentedInvocation(AugmentedInvocation node) { |
| _sink.writeln('AugmentedInvocation'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeFragment('fragment', node.fragment); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitAwaitExpression(AwaitExpression node) { |
| _sink.writeln('AwaitExpression'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitBinaryExpression(BinaryExpression node) { |
| _sink.writeln('BinaryExpression'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeElement2('element', node.element); |
| _writeType('staticInvokeType', node.staticInvokeType); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitBlock(Block node) { |
| _sink.writeln('Block'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitBlockFunctionBody(BlockFunctionBody node) { |
| _sink.writeln('BlockFunctionBody'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitBooleanLiteral(BooleanLiteral node) { |
| _sink.writeln('BooleanLiteral'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitBreakStatement(BreakStatement node) { |
| _sink.writeln('BreakStatement'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitCascadeExpression(CascadeExpression node) { |
| _sink.writeln('CascadeExpression'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitCaseClause(CaseClause node) { |
| _sink.writeln('CaseClause'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitCastPattern(CastPattern node) { |
| _sink.writeln('CastPattern'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writePatternMatchedValueType(node); |
| }); |
| } |
| |
| @override |
| void visitCatchClause(CatchClause node) { |
| _sink.writeln('CatchClause'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitCatchClauseParameter(CatchClauseParameter node) { |
| _sink.writeln('CatchClauseParameter'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeDeclaredFragment(node.declaredFragment); |
| }); |
| } |
| |
| @override |
| void visitClassDeclaration(ClassDeclaration node) { |
| _sink.writeln('ClassDeclaration'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeDeclaredFragment(node.declaredFragment); |
| }); |
| } |
| |
| @override |
| void visitClassTypeAlias(ClassTypeAlias node) { |
| _sink.writeln('ClassTypeAlias'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeDeclaredFragment(node.declaredFragment); |
| }); |
| } |
| |
| @override |
| void visitComment(Comment node) { |
| _sink.writeln('Comment'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| if (node.codeBlocks.isNotEmpty) { |
| _sink.writelnWithIndent('codeBlocks'); |
| _sink.withIndent(() { |
| for (var codeBlock in node.codeBlocks) { |
| _writeMdCodeBlock(codeBlock); |
| } |
| }); |
| } |
| if (node.docImports.isNotEmpty) { |
| _sink.writelnWithIndent('docImports'); |
| _sink.withIndent(() { |
| for (var docImport in node.docImports) { |
| _writeDocImport(docImport); |
| } |
| }); |
| } |
| if (node.docDirectives.isNotEmpty) { |
| _sink.writelnWithIndent('docDirectives'); |
| _sink.withIndent(() { |
| for (var docDirective in node.docDirectives) { |
| switch (docDirective) { |
| case SimpleDocDirective(): |
| _sink.writelnWithIndent('SimpleDocDirective'); |
| _sink.withIndent(() { |
| _sink.writelnWithIndent('tag'); |
| _writeDocDirectiveTag(docDirective.tag); |
| }); |
| case BlockDocDirective(:var openingTag, :var closingTag): |
| _sink.writelnWithIndent('BlockDocDirective'); |
| _sink.withIndent(() { |
| _sink.writelnWithIndent('openingTag'); |
| _writeDocDirectiveTag(openingTag); |
| if (closingTag != null) { |
| _sink.writelnWithIndent('closingTag'); |
| _writeDocDirectiveTag(closingTag); |
| } |
| }); |
| } |
| } |
| }); |
| } |
| if (node.hasNodoc) { |
| _sink.writelnWithIndent('hasNodoc: true'); |
| } |
| }); |
| } |
| |
| @override |
| void visitCommentReference(CommentReference node) { |
| _sink.writeln('CommentReference'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitCompilationUnit(CompilationUnit node) { |
| _sink.writeln('CompilationUnit'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitConditionalExpression(ConditionalExpression node) { |
| _sink.writeln('ConditionalExpression'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitConfiguration(Configuration node) { |
| _sink.writeln('Configuration'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| _sink.withIndent(() { |
| _sink.writeWithIndent('resolvedUri: '); |
| _elementPrinter.writeDirectiveUri(node.resolvedUri); |
| }); |
| } |
| |
| @override |
| void visitConstantPattern(ConstantPattern node) { |
| _sink.writeln('ConstantPattern'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writePatternMatchedValueType(node); |
| }); |
| } |
| |
| @override |
| void visitConstructorDeclaration(ConstructorDeclaration node) { |
| _sink.writeln('ConstructorDeclaration'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeDeclaredFragment(node.declaredFragment); |
| }); |
| } |
| |
| @override |
| void visitConstructorFieldInitializer(ConstructorFieldInitializer node) { |
| _sink.writeln('ConstructorFieldInitializer'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitConstructorName(ConstructorName node) { |
| _sink.writeln('ConstructorName'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeElement2('element', node.element); |
| }); |
| } |
| |
| @override |
| void visitConstructorReference(ConstructorReference node) { |
| _sink.writeln('ConstructorReference'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitConstructorSelector(ConstructorSelector node) { |
| _checkChildrenEntitiesLinking(node); |
| _sink.writeln('ConstructorSelector'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitContinueStatement(ContinueStatement node) { |
| _sink.writeln('ContinueStatement'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitDeclaredIdentifier(DeclaredIdentifier node) { |
| _sink.writeln('DeclaredIdentifier'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeDeclaredFragment(node.declaredFragment); |
| }); |
| } |
| |
| @override |
| void visitDeclaredVariablePattern( |
| covariant DeclaredVariablePatternImpl node, |
| ) { |
| _sink.writeln('DeclaredVariablePattern'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| if (_withResolution) { |
| var fragment = node.declaredFragment; |
| if (fragment != null) { |
| _sink.writeWithIndent('declaredElement: '); |
| _sink.writeIf(fragment.hasImplicitType, 'hasImplicitType '); |
| _sink.writeIf(fragment.isFinal, 'isFinal '); |
| _sink.writeln('${fragment.name}@${fragment.nameOffset}'); |
| _sink.withIndent(() { |
| _writeType('type', fragment.type); |
| }); |
| } |
| _writePatternMatchedValueType(node); |
| } |
| }); |
| } |
| |
| @override |
| void visitDefaultFormalParameter(DefaultFormalParameter node) { |
| _sink.writeln('DefaultFormalParameter'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _assertFormalParameterDeclaredElement(node); |
| _writeDeclaredFragment(node.declaredFragment); |
| }); |
| } |
| |
| @override |
| void visitDoStatement(DoStatement node) { |
| _sink.writeln('DoStatement'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitDotShorthandInvocation(DotShorthandInvocation node) { |
| _sink.writeln('DotShorthandInvocation'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticInvokeType', node.staticInvokeType); |
| _writeType('staticType', node.staticType); |
| _writeTypeList('typeArgumentTypes', node.typeArgumentTypes); |
| }); |
| } |
| |
| @override |
| void visitDottedName(DottedName node) { |
| _sink.writeln('DottedName'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitDoubleLiteral(DoubleLiteral node) { |
| _sink.writeln('DoubleLiteral'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitEmptyFunctionBody(EmptyFunctionBody node) { |
| _sink.writeln('EmptyFunctionBody'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitEnumConstantArguments(EnumConstantArguments node) { |
| _checkChildrenEntitiesLinking(node); |
| _sink.writeln('EnumConstantArguments'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitEnumConstantDeclaration(EnumConstantDeclaration node) { |
| _checkChildrenEntitiesLinking(node); |
| _sink.writeln('EnumConstantDeclaration'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| if (_withResolution) { |
| _writeElement2('constructorElement2', node.constructorElement2); |
| _writeDeclaredFragment(node.declaredFragment); |
| } |
| }); |
| } |
| |
| @override |
| void visitEnumDeclaration(EnumDeclaration node) { |
| _sink.writeln('EnumDeclaration'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeDeclaredFragment(node.declaredFragment); |
| }); |
| } |
| |
| @override |
| void visitExportDirective(ExportDirective node) { |
| _sink.writeln('ExportDirective'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| if (_withResolution) { |
| _elementPrinter.writeLibraryExport('libraryExport', node.libraryExport); |
| } |
| }); |
| } |
| |
| @override |
| void visitExpressionFunctionBody(ExpressionFunctionBody node) { |
| _sink.writeln('ExpressionFunctionBody'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitExpressionStatement(ExpressionStatement node) { |
| _sink.writeln('ExpressionStatement'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitExtendsClause(ExtendsClause node) { |
| _sink.writeln('ExtendsClause'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitExtensionDeclaration(ExtensionDeclaration node) { |
| _sink.writeln('ExtensionDeclaration'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeDeclaredFragment(node.declaredFragment); |
| }); |
| } |
| |
| @override |
| void visitExtensionOnClause(ExtensionOnClause node) { |
| _sink.writeln('ExtensionOnClause'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitExtensionOverride(ExtensionOverride node) { |
| _sink.writeln('ExtensionOverride'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeElement2('element2', node.element2); |
| _writeType('extendedType', node.extendedType); |
| _writeType('staticType', node.staticType); |
| _writeTypeList('typeArgumentTypes', node.typeArgumentTypes); |
| }); |
| } |
| |
| @override |
| void visitExtensionTypeDeclaration(ExtensionTypeDeclaration node) { |
| _sink.writeln('ExtensionTypeDeclaration'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeDeclaredFragment(node.declaredFragment); |
| }); |
| } |
| |
| @override |
| void visitFieldDeclaration(FieldDeclaration node) { |
| _sink.writeln('FieldDeclaration'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeDeclaredFragment(node.declaredFragment); |
| }); |
| } |
| |
| @override |
| void visitFieldFormalParameter(FieldFormalParameter node) { |
| _sink.writeln('FieldFormalParameter'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _assertFormalParameterDeclaredElement(node); |
| _writeDeclaredFragment(node.declaredFragment); |
| }); |
| } |
| |
| @override |
| void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) { |
| _sink.writeln('ForEachPartsWithDeclaration'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) { |
| _sink.writeln('ForEachPartsWithIdentifier'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitForEachPartsWithPattern(ForEachPartsWithPattern node) { |
| _sink.writeln('ForEachPartsWithPattern'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitForElement(ForElement node) { |
| _sink.writeln('ForElement'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitFormalParameterList(FormalParameterList node) { |
| _sink.writeln('FormalParameterList'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitForPartsWithDeclarations(ForPartsWithDeclarations node) { |
| _sink.writeln('ForPartsWithDeclarations'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitForPartsWithExpression(ForPartsWithExpression node) { |
| _sink.writeln('ForPartsWithExpression'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitForPartsWithPattern(ForPartsWithPattern node) { |
| _sink.writeln('ForPartsWithPattern'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitForStatement(ForStatement node) { |
| _sink.writeln('ForStatement'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitFunctionDeclaration(FunctionDeclaration node) { |
| _sink.writeln('FunctionDeclaration'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeDeclaredFragment(node.declaredFragment); |
| }); |
| } |
| |
| @override |
| void visitFunctionDeclarationStatement(FunctionDeclarationStatement node) { |
| _sink.writeln('FunctionDeclarationStatement'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitFunctionExpression(FunctionExpression node) { |
| _sink.writeln('FunctionExpression'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeDeclaredFragment(node.declaredFragment); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { |
| _sink.writeln('FunctionExpressionInvocation'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeElement2('element', node.element); |
| _writeType('staticInvokeType', node.staticInvokeType); |
| _writeType('staticType', node.staticType); |
| _writeTypeList('typeArgumentTypes', node.typeArgumentTypes); |
| }); |
| } |
| |
| @override |
| void visitFunctionReference(FunctionReference node) { |
| _sink.writeln('FunctionReference'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| _writeTypeList('typeArgumentTypes', node.typeArgumentTypes); |
| }); |
| } |
| |
| @override |
| void visitFunctionTypeAlias(FunctionTypeAlias node) { |
| _sink.writeln('FunctionTypeAlias'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeDeclaredFragment(node.declaredFragment); |
| }); |
| } |
| |
| @override |
| void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { |
| _sink.writeln('FunctionTypedFormalParameter'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _assertFormalParameterDeclaredElement(node); |
| _writeDeclaredFragment(node.declaredFragment); |
| }); |
| } |
| |
| @override |
| void visitGenericFunctionType(covariant GenericFunctionTypeImpl node) { |
| _sink.writeln('GenericFunctionType'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| if (_withResolution) { |
| _writeGenericFunctionTypeElement( |
| 'declaredElement', |
| node.declaredFragment, |
| ); |
| } |
| _writeType('type', node.type); |
| }); |
| } |
| |
| @override |
| void visitGenericTypeAlias(GenericTypeAlias node) { |
| _sink.writeln('GenericTypeAlias'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeDeclaredFragment(node.declaredFragment); |
| }); |
| } |
| |
| @override |
| void visitGuardedPattern(GuardedPattern node) { |
| _sink.writeln('GuardedPattern'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitHideCombinator(HideCombinator node) { |
| _sink.writeln('HideCombinator'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitIfElement(IfElement node) { |
| _sink.writeln('IfElement'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitIfStatement(IfStatement node) { |
| _sink.writeln('IfStatement'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitImplementsClause(ImplementsClause node) { |
| _sink.writeln('ImplementsClause'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitImplicitCallReference(ImplicitCallReference node) { |
| _sink.writeln('ImplicitCallReference'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeElement2('element', node.element); |
| _writeType('staticType', node.staticType); |
| _writeTypeList('typeArgumentTypes', node.typeArgumentTypes); |
| }); |
| } |
| |
| @override |
| void visitImportDirective(ImportDirective node) { |
| _sink.writeln('ImportDirective'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| if (_withResolution) { |
| _elementPrinter.writeLibraryImport('libraryImport', node.libraryImport); |
| } |
| }); |
| } |
| |
| @override |
| void visitImportPrefixReference(ImportPrefixReference node) { |
| _sink.writeln('ImportPrefixReference'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeElement2('element2', node.element2); |
| }); |
| } |
| |
| @override |
| void visitIndexExpression(IndexExpression node) { |
| _sink.writeln('IndexExpression'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeElement2('element', node.element); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitInstanceCreationExpression(InstanceCreationExpression node) { |
| _sink.writeln('InstanceCreationExpression'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitIntegerLiteral(IntegerLiteral node) { |
| _sink.writeln('IntegerLiteral'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitInterpolationExpression(InterpolationExpression node) { |
| _sink.writeln('InterpolationExpression'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitInterpolationString(InterpolationString node) { |
| _sink.writeln('InterpolationString'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitIsExpression(IsExpression node) { |
| _sink.writeln('IsExpression'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitLabel(Label node) { |
| _sink.writeln('Label'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitLabeledStatement(LabeledStatement node) { |
| _sink.writeln('LabeledStatement'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitLibraryDirective(LibraryDirective node) { |
| _sink.writeln('LibraryDirective'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeElement2('element2', node.element2); |
| }); |
| } |
| |
| @override |
| void visitLibraryIdentifier(LibraryIdentifier node) { |
| _sink.writeln('LibraryIdentifier'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeElement2('element', node.element); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitListLiteral(ListLiteral node) { |
| _sink.writeln('ListLiteral'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitListPattern(ListPattern node) { |
| _sink.writeln('ListPattern'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writePatternMatchedValueType(node); |
| _writeType('requiredType', node.requiredType); |
| }); |
| } |
| |
| @override |
| void visitLogicalAndPattern(LogicalAndPattern node) { |
| _sink.writeln('LogicalAndPattern'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writePatternMatchedValueType(node); |
| }); |
| } |
| |
| @override |
| void visitLogicalOrPattern(LogicalOrPattern node) { |
| _sink.writeln('LogicalOrPattern'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writePatternMatchedValueType(node); |
| }); |
| } |
| |
| @override |
| void visitMapLiteralEntry(MapLiteralEntry node) { |
| _sink.writeln('MapLiteralEntry'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitMapPattern(MapPattern node) { |
| _sink.writeln('MapPattern'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writePatternMatchedValueType(node); |
| _writeType('requiredType', node.requiredType); |
| }); |
| } |
| |
| @override |
| void visitMapPatternEntry(MapPatternEntry node) { |
| _sink.writeln('MapPatternEntry'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitMethodDeclaration(MethodDeclaration node) { |
| _sink.writeln('MethodDeclaration'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeDeclaredFragment(node.declaredFragment); |
| }); |
| } |
| |
| @override |
| void visitMethodInvocation(MethodInvocation node) { |
| _sink.writeln('MethodInvocation'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticInvokeType', node.staticInvokeType); |
| _writeType('staticType', node.staticType); |
| _writeTypeList('typeArgumentTypes', node.typeArgumentTypes); |
| }); |
| } |
| |
| @override |
| void visitMixinDeclaration(MixinDeclaration node) { |
| _sink.writeln('MixinDeclaration'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeDeclaredFragment(node.declaredFragment); |
| }); |
| } |
| |
| @override |
| void visitMixinOnClause(MixinOnClause node) { |
| _sink.writeln('MixinOnClause'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitNamedExpression(NamedExpression node) { |
| _sink.writeln('NamedExpression'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| // Types of the node and its expression must be the same. |
| if (node.expression.staticType != node.staticType) { |
| var nodeType = node.staticType; |
| var expressionType = node.expression.staticType; |
| fail( |
| 'Must be the same:\n' |
| 'nodeType: $nodeType\n' |
| 'expressionType: $expressionType', |
| ); |
| } |
| }); |
| } |
| |
| @override |
| void visitNamedType(NamedType node) { |
| _sink.writeln('NamedType'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeElement2('element2', node.element2); |
| _writeType('type', node.type); |
| }); |
| } |
| |
| @override |
| void visitNullAssertPattern(NullAssertPattern node) { |
| _sink.writeln('NullAssertPattern'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writePatternMatchedValueType(node); |
| }); |
| } |
| |
| @override |
| void visitNullAwareElement(NullAwareElement node) { |
| _sink.writeln('NullAwareElement'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitNullCheckPattern(NullCheckPattern node) { |
| _sink.writeln('NullCheckPattern'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writePatternMatchedValueType(node); |
| }); |
| } |
| |
| @override |
| void visitNullLiteral(NullLiteral node) { |
| _sink.writeln('NullLiteral'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitObjectPattern(ObjectPattern node) { |
| _sink.writeln('ObjectPattern'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writePatternMatchedValueType(node); |
| }); |
| } |
| |
| @override |
| void visitParenthesizedExpression(ParenthesizedExpression node) { |
| _sink.writeln('ParenthesizedExpression'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitParenthesizedPattern(ParenthesizedPattern node) { |
| _sink.writeln('ParenthesizedPattern'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writePatternMatchedValueType(node); |
| }); |
| } |
| |
| @override |
| void visitPartDirective(PartDirective node) { |
| _sink.writeln('PartDirective'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| if (_withResolution) { |
| _elementPrinter.writePartInclude('partInclude', node.partInclude); |
| } |
| }); |
| } |
| |
| @override |
| void visitPartOfDirective(PartOfDirective node) { |
| _sink.writeln('PartOfDirective'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitPatternAssignment(covariant PatternAssignmentImpl node) { |
| _sink.writeln('PatternAssignment'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeType('patternTypeSchema', node.patternTypeSchema); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitPatternField(PatternField node) { |
| _sink.writeln('PatternField'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeElement2('element2', node.element2); |
| }); |
| } |
| |
| @override |
| void visitPatternFieldName(PatternFieldName node) { |
| _sink.writeln('PatternFieldName'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitPatternVariableDeclaration( |
| covariant PatternVariableDeclarationImpl node, |
| ) { |
| _sink.writeln('PatternVariableDeclaration'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeType('patternTypeSchema', node.patternTypeSchema); |
| }); |
| } |
| |
| @override |
| void visitPatternVariableDeclarationStatement( |
| PatternVariableDeclarationStatement node) { |
| _sink.writeln('PatternVariableDeclarationStatement'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitPostfixExpression(PostfixExpression node) { |
| _sink.writeln('PostfixExpression'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| if (node.operator.type.isIncrementOperator) { |
| _writeElement2('readElement2', node.readElement2); |
| _writeType('readType', node.readType); |
| _writeElement2('writeElement2', node.writeElement2); |
| _writeType('writeType', node.writeType); |
| } |
| _writeElement2('element', node.element); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitPrefixedIdentifier(PrefixedIdentifier node) { |
| _sink.writeln('PrefixedIdentifier'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeElement2('element', node.element); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitPrefixExpression(PrefixExpression node) { |
| _sink.writeln('PrefixExpression'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| if (node.operator.type.isIncrementOperator) { |
| _writeElement2('readElement2', node.readElement2); |
| _writeType('readType', node.readType); |
| _writeElement2('writeElement2', node.writeElement2); |
| _writeType('writeType', node.writeType); |
| } |
| _writeElement2('element', node.element); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitPropertyAccess(PropertyAccess node) { |
| _sink.writeln('PropertyAccess'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitRecordLiteral(RecordLiteral node) { |
| _sink.writeln('RecordLiteral'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitRecordPattern(RecordPattern node) { |
| _sink.writeln('RecordPattern'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writePatternMatchedValueType(node); |
| }); |
| } |
| |
| @override |
| void visitRecordTypeAnnotation(RecordTypeAnnotation node) { |
| _sink.writeln('RecordTypeAnnotation'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeType('type', node.type); |
| }); |
| } |
| |
| @override |
| void visitRecordTypeAnnotationNamedField( |
| RecordTypeAnnotationNamedField node) { |
| _sink.writeln('RecordTypeAnnotationNamedField'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitRecordTypeAnnotationNamedFields( |
| RecordTypeAnnotationNamedFields node) { |
| _sink.writeln('RecordTypeAnnotationNamedFields'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitRecordTypeAnnotationPositionalField( |
| RecordTypeAnnotationPositionalField node) { |
| _sink.writeln('RecordTypeAnnotationPositionalField'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitRedirectingConstructorInvocation( |
| RedirectingConstructorInvocation node, |
| ) { |
| _sink.writeln('RedirectingConstructorInvocation'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeElement2('element', node.element); |
| }); |
| } |
| |
| @override |
| void visitRelationalPattern(RelationalPattern node) { |
| _sink.writeln('RelationalPattern'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeElement2('element2', node.element2); |
| _writePatternMatchedValueType(node); |
| }); |
| } |
| |
| @override |
| void visitRepresentationConstructorName(RepresentationConstructorName node) { |
| _sink.writeln('RepresentationConstructorName'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitRepresentationDeclaration(RepresentationDeclaration node) { |
| _sink.writeln('RepresentationDeclaration'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeFragment('fieldFragment', node.fieldFragment); |
| _writeFragment('constructorFragment', node.constructorFragment); |
| }); |
| } |
| |
| @override |
| void visitRestPatternElement(RestPatternElement node) { |
| _sink.writeln('RestPatternElement'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitRethrowExpression(RethrowExpression node) { |
| _sink.writeln('RethrowExpression'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitReturnStatement(ReturnStatement node) { |
| _sink.writeln('ReturnStatement'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitSetOrMapLiteral(SetOrMapLiteral node) { |
| _sink.writeln('SetOrMapLiteral'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeRaw('isMap', node.isMap); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitShowCombinator(ShowCombinator node) { |
| _sink.writeln('ShowCombinator'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitSimpleFormalParameter(SimpleFormalParameter node) { |
| _sink.writeln('SimpleFormalParameter'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeDeclaredFragment(node.declaredFragment); |
| }); |
| } |
| |
| @override |
| void visitSimpleIdentifier(SimpleIdentifier node) { |
| _sink.writeln('SimpleIdentifier'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeElement2('element', node.element); |
| _writeType('staticType', node.staticType); |
| _writeTypeList( |
| 'tearOffTypeArgumentTypes', |
| node.tearOffTypeArgumentTypes, |
| ); |
| }); |
| } |
| |
| @override |
| void visitSimpleStringLiteral(SimpleStringLiteral node) { |
| _sink.writeln('SimpleStringLiteral'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitSpreadElement(SpreadElement node) { |
| _sink.writeln('SpreadElement'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitStringInterpolation(StringInterpolation node) { |
| _sink.writeln('StringInterpolation'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| _writeRaw('stringValue', node.stringValue); |
| }); |
| } |
| |
| @override |
| void visitSuperConstructorInvocation(SuperConstructorInvocation node) { |
| _sink.writeln('SuperConstructorInvocation'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeElement2('element', node.element); |
| }); |
| } |
| |
| @override |
| void visitSuperExpression(SuperExpression node) { |
| _sink.writeln('SuperExpression'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitSuperFormalParameter(SuperFormalParameter node) { |
| _checkChildrenEntitiesLinking(node); |
| _sink.writeln('SuperFormalParameter'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _assertFormalParameterDeclaredElement(node); |
| _writeDeclaredFragment(node.declaredFragment); |
| }); |
| } |
| |
| @override |
| void visitSwitchCase(SwitchCase node) { |
| _sink.writeln('SwitchCase'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitSwitchDefault(SwitchDefault node) { |
| _sink.writeln('SwitchDefault'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitSwitchExpression(SwitchExpression node) { |
| _sink.writeln('SwitchExpression'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitSwitchExpressionCase(SwitchExpressionCase node) { |
| _sink.writeln('SwitchExpressionCase'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitSwitchPatternCase(SwitchPatternCase node) { |
| _sink.writeln('SwitchPatternCase'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitSwitchStatement(SwitchStatement node) { |
| _sink.writeln('SwitchStatement'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitSymbolLiteral(SymbolLiteral node) { |
| _sink.writeln('SymbolLiteral'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| }); |
| } |
| |
| @override |
| void visitThisExpression(ThisExpression node) { |
| _sink.writeln('ThisExpression'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitThrowExpression(ThrowExpression node) { |
| _sink.writeln('ThrowExpression'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { |
| _sink.writeln('TopLevelVariableDeclaration'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeDeclaredFragment(node.declaredFragment); |
| }); |
| } |
| |
| @override |
| void visitTryStatement(TryStatement node) { |
| _sink.writeln('TryStatement'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitTypeArgumentList(TypeArgumentList node) { |
| _sink.writeln('TypeArgumentList'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitTypeLiteral(TypeLiteral node) { |
| _sink.writeln('TypeLiteral'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeParameterElement(node); |
| _writeType('staticType', node.staticType); |
| }); |
| } |
| |
| @override |
| void visitTypeParameter(TypeParameter node) { |
| _sink.writeln('TypeParameter'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeDeclaredFragment(node.declaredFragment); |
| }); |
| } |
| |
| @override |
| void visitTypeParameterList(TypeParameterList node) { |
| _sink.writeln('TypeParameterList'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitVariableDeclaration(VariableDeclaration node) { |
| _sink.writeln('VariableDeclaration'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writeDeclaredFragment(node.declaredFragment); |
| }); |
| } |
| |
| @override |
| void visitVariableDeclarationList(VariableDeclarationList node) { |
| _sink.writeln('VariableDeclarationList'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitVariableDeclarationStatement(VariableDeclarationStatement node) { |
| _sink.writeln('VariableDeclarationStatement'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitWhenClause(WhenClause node) { |
| _sink.writeln('WhenClause'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitWhileStatement(WhileStatement node) { |
| _sink.writeln('WhileStatement'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitWildcardPattern( |
| covariant WildcardPatternImpl node, |
| ) { |
| _sink.writeln('WildcardPattern'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| _writePatternMatchedValueType(node); |
| }); |
| } |
| |
| @override |
| void visitWithClause(WithClause node) { |
| _sink.writeln('WithClause'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| @override |
| void visitYieldStatement(YieldStatement node) { |
| _sink.writeln('YieldStatement'); |
| _sink.withIndent(() { |
| _writeNamedChildEntities(node); |
| }); |
| } |
| |
| void _assertFormalParameterDeclaredElement(FormalParameter node) { |
| if (_withResolution) { |
| var declaredFragment = node.declaredFragment; |
| var expected = _expectedFormalParameterElements(node); |
| _assertHasIdenticalElement(expected, declaredFragment); |
| } |
| } |
| |
| /// Check that children entities of the [node] link to each other. |
| void _checkChildrenEntitiesLinking(AstNode node) { |
| Token? lastEnd; |
| for (var entity in node.childEntities) { |
| if (lastEnd != null) { |
| var begin = _entityBeginToken(entity); |
| expect(lastEnd.next, begin); |
| expect(begin.previous, lastEnd); |
| } |
| lastEnd = _entityEndToken(entity); |
| } |
| } |
| |
| /// Check that the actual parent of [child] is [parent]. |
| void _checkParentOfChild(AstNode parent, AstNode child) { |
| var actualParent = child.parent; |
| if (actualParent == null) { |
| fail(''' |
| No parent. |
| Child: (${child.runtimeType}) $child |
| Expected parent: (${parent.runtimeType}) $parent |
| '''); |
| } else if (actualParent != parent) { |
| fail(''' |
| Wrong parent. |
| Child: (${child.runtimeType}) $child |
| Actual parent: (${actualParent.runtimeType}) $actualParent |
| Expected parent: (${parent.runtimeType}) $parent |
| '''); |
| } |
| } |
| |
| String _getTokenId(Token? token) { |
| if (token == null) { |
| return '<null>'; |
| } |
| return _tokenIdMap[token] ??= 'T${_tokenIdMap.length}'; |
| } |
| |
| void _writeDeclaredFragment(Fragment? fragment) { |
| if (_withResolution) { |
| if (fragment is LocalVariableElementImpl) { |
| _sink.writeWithIndent('declaredElement:'); |
| _sink.writeIf(fragment.hasImplicitType, ' hasImplicitType'); |
| _sink.writeIf(fragment.isConst, ' isConst'); |
| _sink.writeIf(fragment.isFinal, ' isFinal'); |
| _sink.writeIf(fragment.isLate, ' isLate'); |
| // TODO(scheglov): This crashes. |
| // _writeIf(element.hasInitializer, ' hasInitializer'); |
| _sink.writeln(' ${fragment.name}@${fragment.nameOffset}'); |
| _sink.withIndent(() { |
| _writeType('type', fragment.type); |
| }); |
| } else { |
| _writeFragment('declaredElement', fragment); |
| if (fragment is ExecutableElementImpl) { |
| _sink.withIndent(() { |
| _writeType('type', fragment.type); |
| }); |
| } else if (fragment is ParameterElementImpl) { |
| _sink.withIndent(() { |
| _writeType('type', fragment.type); |
| }); |
| } |
| } |
| } |
| } |
| |
| void _writeDocDirectiveTag(DocDirectiveTag docDirective) { |
| _sink.withIndent(() { |
| _sink.writelnWithIndent( |
| 'offset: [${docDirective.offset}, ${docDirective.end}]'); |
| _sink.writelnWithIndent('type: [${docDirective.type}]'); |
| if (docDirective.positionalArguments.isNotEmpty) { |
| _sink.writelnWithIndent('positionalArguments'); |
| _sink.withIndent(() { |
| for (var argument in docDirective.positionalArguments) { |
| _sink.writelnWithIndent(argument.value); |
| } |
| }); |
| } |
| if (docDirective.namedArguments.isNotEmpty) { |
| _sink.writelnWithIndent('namedArguments'); |
| _sink.withIndent(() { |
| for (var argument in docDirective.namedArguments) { |
| _sink.writeWithIndent(argument.name); |
| _sink.writeln('=${argument.value}'); |
| } |
| }); |
| } |
| }); |
| } |
| |
| void _writeDocImport(DocImport docImport) { |
| _sink.writelnWithIndent('DocImport'); |
| _sink.withIndent(() { |
| _sink.writelnWithIndent('offset: ${docImport.offset}'); |
| _writeNode('import', docImport.import); |
| }); |
| } |
| |
| void _writeElement2(String name, Element2? element) { |
| if (_withResolution) { |
| _elementPrinter.writeNamedElement2(name, element); |
| } |
| } |
| |
| void _writeFragment(String name, Fragment? fragment) { |
| if (_withResolution) { |
| _elementPrinter.writeNamedFragment(name, fragment); |
| } |
| } |
| |
| void _writeGenericFunctionTypeElement( |
| String name, |
| GenericFunctionTypeElementImpl? element, |
| ) { |
| _sink.writeWithIndent('$name: '); |
| if (element == null) { |
| _sink.writeln('<null>'); |
| } else { |
| _sink.withIndent(() { |
| _sink.writeln('GenericFunctionTypeElement'); |
| _writeParameterElements(element.parameters); |
| _writeType('returnType', element.returnType); |
| _writeType('type', element.type); |
| }); |
| } |
| } |
| |
| void _writeMdCodeBlock(MdCodeBlock codeBlock) { |
| _sink.writelnWithIndent('MdCodeBlock'); |
| _sink.withIndent(() { |
| var infoString = codeBlock.infoString; |
| _sink.writelnWithIndent('infoString: ${infoString ?? '<empty>'}'); |
| _sink.writelnWithIndent('type: ${codeBlock.type}'); |
| assert(codeBlock.lines.isNotEmpty); |
| _sink.writelnWithIndent('lines'); |
| _sink.withIndent(() { |
| for (var line in codeBlock.lines) { |
| _sink.writelnWithIndent('MdCodeBlockLine'); |
| _sink.withIndent(() { |
| _sink.writelnWithIndent('offset: ${line.offset}'); |
| _sink.writelnWithIndent('length: ${line.length}'); |
| }); |
| } |
| }); |
| }); |
| } |
| |
| void _writeNamedChildEntities(AstNode node) { |
| node as AstNodeImpl; |
| for (var entity in node.namedChildEntities) { |
| var value = entity.value; |
| if (value is Token) { |
| _writeToken(entity.name, value); |
| } else if (value is AstNode) { |
| _checkParentOfChild(node, value); |
| if (value is ArgumentList && configuration.skipArgumentList) { |
| } else { |
| _writeNode(entity.name, value); |
| } |
| } else if (value is List<Token>) { |
| _writeTokenList(entity.name, value); |
| } else if (value is List<AstNode>) { |
| _writeNodeList(node, entity.name, value); |
| } else { |
| throw UnimplementedError('(${value.runtimeType}) $value'); |
| } |
| } |
| } |
| |
| void _writeNode(String name, AstNode? node) { |
| if (node != null) { |
| _sink.writeWithIndent('$name: '); |
| node.accept(this); |
| } |
| } |
| |
| void _writeNodeList(AstNode parent, String name, List<AstNode> nodeList) { |
| if (nodeList.isNotEmpty) { |
| _sink.writelnWithIndent(name); |
| _sink.withIndent(() { |
| for (var node in nodeList) { |
| _checkParentOfChild(parent, node); |
| _sink.writeIndent(); |
| node.accept(this); |
| } |
| }); |
| } |
| } |
| |
| void _writeOffset(String name, int offset) { |
| _sink.writelnWithIndent('$name: $offset'); |
| } |
| |
| /// If [node] is at a position where it is an argument for an invocation, |
| /// writes the corresponding parameter element. |
| void _writeParameterElement(Expression node) { |
| if (configuration.withParameterElements) { |
| var parent = node.parent; |
| if (parent is ArgumentList || |
| parent is AssignmentExpression && parent.rightHandSide == node || |
| parent is BinaryExpression && parent.rightOperand == node || |
| parent is IndexExpression && parent.index == node) { |
| _writeElement2('correspondingParameter', node.correspondingParameter); |
| } |
| } |
| } |
| |
| void _writeParameterElements(List<ParameterElementImpl> parameters) { |
| _sink.writelnWithIndent('parameters'); |
| _sink.withIndent(() { |
| for (var parameter in parameters) { |
| var name = parameter.name; |
| _sink.writelnWithIndent(name.isNotEmpty ? name : '<empty>'); |
| _sink.withIndent(() { |
| _writeParameterKind(parameter); |
| _writeType('type', parameter.type); |
| }); |
| } |
| }); |
| } |
| |
| void _writeParameterKind(ParameterElementImpl parameter) { |
| if (parameter.isOptionalNamed) { |
| _sink.writelnWithIndent('kind: optional named'); |
| } else if (parameter.isOptionalPositional) { |
| _sink.writelnWithIndent('kind: optional positional'); |
| } else if (parameter.isRequiredNamed) { |
| _sink.writelnWithIndent('kind: required named'); |
| } else if (parameter.isRequiredPositional) { |
| _sink.writelnWithIndent('kind: required positional'); |
| } else { |
| throw StateError('Unknown kind: $parameter'); |
| } |
| } |
| |
| void _writePatternMatchedValueType(DartPattern node) { |
| if (_withResolution) { |
| var matchedValueType = node.matchedValueType; |
| if (matchedValueType != null) { |
| _writeType('matchedValueType', matchedValueType); |
| } else { |
| fail('No matchedValueType: $node'); |
| } |
| } |
| } |
| |
| void _writeRaw(String name, Object? value) { |
| _sink.writelnWithIndent('$name: $value'); |
| } |
| |
| void _writeToken(String name, Token? token) { |
| if (token == null) { |
| return; |
| } |
| |
| _sink.writeIndentedLine(() { |
| _sink.write('$name: '); |
| if (configuration.withTokenPreviousNext) { |
| _sink.write(_getTokenId(token)); |
| _sink.write(' '); |
| } |
| _sink.write(token.lexeme.ifNotEmptyOrElse('<empty>')); |
| if (_withOffsets) { |
| _sink.write(' @${token.offset}'); |
| } |
| if (token.isSynthetic) { |
| _sink.write(' <synthetic>'); |
| } |
| }); |
| |
| if (configuration.withTokenPreviousNext) { |
| _sink.withIndent(() { |
| if (token.previous case var previous?) { |
| if (!previous.isEof) { |
| if (_tokenIdMap[previous] == null) { |
| _writeToken('previousX', previous); |
| } else { |
| _sink.writelnWithIndent( |
| 'previous: ${_getTokenId(previous)} |${previous.lexeme}|', |
| ); |
| } |
| } |
| } else { |
| _sink.writelnWithIndent('previous: <null>'); |
| } |
| |
| if (token.next case var next?) { |
| _sink.writelnWithIndent( |
| 'next: ${_getTokenId(next)} |${next.lexeme}|', |
| ); |
| } else { |
| _sink.writelnWithIndent('next: <null>'); |
| } |
| }); |
| } |
| } |
| |
| void _writeTokenList(String name, List<Token> tokens) { |
| if (tokens.isNotEmpty) { |
| _sink.writelnWithIndent(name); |
| _sink.withIndent(() { |
| for (var token in tokens) { |
| _sink.writelnWithIndent(token.lexeme); |
| if (_withOffsets) { |
| _sink.withIndent(() { |
| _writeOffset('offset', token.offset); |
| }); |
| } |
| } |
| }); |
| } |
| } |
| |
| void _writeType(String name, DartType? type) { |
| if (_withResolution) { |
| _elementPrinter.writeNamedType(name, type); |
| } |
| } |
| |
| void _writeTypeList(String name, List<DartType>? types) { |
| if (_withResolution) { |
| _elementPrinter.writeTypeList(name, types); |
| } |
| } |
| |
| static void _assertHasIdenticalElement<T>(List<T> elements, T expected) { |
| for (var element in elements) { |
| if (identical(element, expected)) { |
| return; |
| } |
| } |
| fail('No $expected in $elements'); |
| } |
| |
| static Token _entityBeginToken(SyntacticEntity entity) { |
| if (entity is Token) { |
| return entity; |
| } else if (entity is AstNode) { |
| return entity.beginToken; |
| } else { |
| throw UnimplementedError('(${entity.runtimeType}) $entity'); |
| } |
| } |
| |
| static Token _entityEndToken(SyntacticEntity entity) { |
| if (entity is Token) { |
| return entity; |
| } else if (entity is AstNode) { |
| return entity.endToken; |
| } else { |
| throw UnimplementedError('(${entity.runtimeType}) $entity'); |
| } |
| } |
| |
| /// Every [FormalParameter] declares an element, and this element must be |
| /// in the list of formal parameter elements of some declaration, e.g. of |
| /// [ConstructorDeclaration], [MethodDeclaration], or a local |
| /// [FunctionDeclaration]. |
| static List<FormalParameterFragment> _expectedFormalParameterElements( |
| FormalParameter node, |
| ) { |
| var parametersParent = node.parentFormalParameterList.parent; |
| if (parametersParent is ConstructorDeclaration) { |
| var declaredFragment = parametersParent.declaredFragment!; |
| return declaredFragment.formalParameters; |
| } else if (parametersParent is FormalParameter) { |
| var declaredFragment = parametersParent.declaredFragment!; |
| declaredFragment as ParameterElementImpl; |
| return declaredFragment.parameters; |
| } else if (parametersParent is FunctionExpression) { |
| var declaredFragment = parametersParent.declaredFragment!; |
| return declaredFragment.formalParameters; |
| } else if (parametersParent is GenericFunctionTypeImpl) { |
| var declaredFragment = parametersParent.declaredFragment!; |
| return declaredFragment.parameters; |
| } else if (parametersParent is MethodDeclaration) { |
| var declaredFragment = parametersParent.declaredFragment!; |
| return declaredFragment.formalParameters; |
| } |
| throw UnimplementedError( |
| '(${parametersParent.runtimeType}) $parametersParent', |
| ); |
| } |
| } |
| |
| class ResolvedNodeTextConfiguration { |
| bool skipArgumentList = false; |
| |
| /// If `true`, elements of [InterfaceType] should be printed. |
| bool withInterfaceTypeElements = false; |
| |
| /// If `true`, [Expression.correspondingParameter] should be printed. |
| bool withParameterElements = true; |
| |
| /// If `true`, `redirectedConstructor` properties of [ConstructorElement2]s |
| /// should be printer. |
| bool withRedirectedConstructors = false; |
| |
| /// If `true`, `superConstructor` properties of [ConstructorElement2]s |
| /// should be printer. |
| bool withSuperConstructors = false; |
| |
| /// If `true`, print IDs of each token, `previous` and `next` tokens. |
| bool withTokenPreviousNext = false; |
| } |