blob: 3a6c119a7f928918f1aca98134a759f8449d650b [file] [edit]
// 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/element.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 ThrowingAstVisitor2<void>
implements AstVisitor<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;
_AstView _view = _AstView.v2;
/// Whether to print the V1 view of child entities alongside their V2 view.
///
/// This inline V1 view is needed when the root is shared between the two AST
/// views. It is redundant when a distinct V1 root is printed separately.
bool _includeInlineV1ChildEntities = true;
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);
_writeElement('element', node.element);
});
}
@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) {
_writeElement('element', node.element);
_writePatternMatchedValueType(node);
}
});
}
@override
void visitAssignmentExpression(AssignmentExpression node) {
_sink.writeln('AssignmentExpression');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
_writeElement('readElement', node.readElement);
_writeType('readType', node.readType);
_writeElement('writeElement', node.writeElement);
_writeType('writeType', node.writeType);
_writeElement('element', node.element);
_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);
_writeElement('element', node.element);
_writeType('staticInvokeType', node.staticInvokeType);
_writeType('staticType', node.staticType);
});
}
@override
void visitBinaryOperatorInvocation(BinaryOperatorInvocation node) {
_sink.writeln('BinaryOperatorInvocation');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
_writeRaw('binaryOperator', node.binaryOperator.name);
_writeElement('element', node.element);
_writeType('staticType', node.staticType);
});
}
@override
void visitBlock(Block node) {
_sink.writeln('Block');
_sink.withIndent(() {
_writeNamedChildEntities(node);
});
}
@override
void visitBlockClassBody(BlockClassBody node) {
_sink.writeln('BlockClassBody');
_sink.withIndent(() {
_writeNamedChildEntities(node);
});
}
@override
void visitBlockEnumBody(BlockEnumBody node) {
_sink.writeln('BlockEnumBody');
_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 visitCallInvocation(covariant CallInvocationImpl node) {
_sink.writeln('CallInvocation');
_sink.withIndent(() {
_writeNamedChildEntities(node);
if (_withResolution) {
_writeInvocationResolution('resolution', node.resolution);
}
_writeParameterElement(node);
_writeType('staticType', node.staticType);
_writeTypeList('typeArgumentTypes', node.typeArgumentTypes);
});
}
@override
void visitCascadeExpression(CascadeExpression node) {
_sink.writeln('CascadeExpression');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
_writeType('staticType', node.staticType);
});
}
@override
void visitCascadeIndexAssignmentTarget(
covariant CascadeIndexAssignmentTargetImpl node,
) {
_sink.writeln('CascadeIndexAssignmentTarget');
_sink.withIndent(() {
_writeNamedChildEntities(node);
if (_withResolution) {
_writeIndexReadResolution('read', node.read);
_writeIndexWriteResolution('write', node.write);
}
});
}
@override
void visitCascadeIndexExpression(covariant CascadeIndexExpressionImpl node) {
_sink.writeln('CascadeIndexExpression');
_sink.withIndent(() {
_writeNamedChildEntities(node);
if (_withResolution) {
_writeIndexReadResolution('resolution', node.resolution);
}
_writeParameterElement(node);
_writeType('staticType', node.staticType);
});
}
@override
void visitCascadeMethodInvocation(
covariant CascadeMethodInvocationImpl node,
) {
_sink.writeln('CascadeMethodInvocation');
_sink.withIndent(() {
_writeNamedChildEntities(node);
if (_withResolution) {
_writeInvocationResolution('resolution', node.resolution);
}
_writeParameterElement(node);
_writeType('staticType', node.staticType);
_writeTypeList('typeArgumentTypes', node.typeArgumentTypes);
});
}
@override
void visitCascadePropertyAssignmentTarget(
covariant CascadePropertyAssignmentTargetImpl node,
) {
_sink.writeln('CascadePropertyAssignmentTarget');
_sink.withIndent(() {
_writeNamedChildEntities(node);
if (_withResolution) {
_writeNamedReadResolution('read', node.read);
_writeNamedWriteResolution('write', node.write);
}
});
}
@override
void visitCascadePropertyExtraction(
covariant CascadePropertyExtractionImpl node,
) {
_sink.writeln('CascadePropertyExtraction');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
if (_withResolution) {
_writeNamedReadResolution('resolution', node.resolution);
}
_writeType('staticType', node.staticType);
});
}
@override
void visitCascadeSection(CascadeSection node) {
_sink.writeln('CascadeSection');
_sink.withIndent(() {
_writeNamedChildEntities(node);
});
}
@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 visitCombinatorName(CombinatorName node) {
_sink.writeln('CombinatorName');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeElement('element', node.element);
_writeElement('setterElement', node.setterElement);
});
}
@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(covariant CompilationUnitImpl node) {
_sink.writeln('CompilationUnit');
_sink.withIndent(() {
_writeNamedChildEntities(node);
});
}
@override
void visitCompoundAssignment(CompoundAssignment node) {
_sink.writeln('CompoundAssignment');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_sink.writelnWithIndent('binaryOperator: ${node.binaryOperator.name}');
_writeParameterElement(node);
_writeElement('element', node.element);
_writeType('operatorResultType', node.operatorResultType);
_writeType('staticType', node.staticType);
});
}
@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);
_writeElement('fieldElement', node.fieldElement);
});
}
@override
void visitConstructorInvocation(ConstructorInvocation node) {
_sink.writeln('ConstructorInvocation');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
_writeType('staticType', node.staticType);
});
}
@override
void visitConstructorName(ConstructorName node) {
_sink.writeln('ConstructorName');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeElement('element', node.element);
});
}
@override
void visitConstructorReference(ConstructorReference node) {
_sink.writeln('ConstructorReference');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
_writeType('staticType', node.staticType);
});
}
@override
void visitConstructorReference2(ConstructorReference2 node) {
_sink.writeln('ConstructorReference2');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeElement('element', node.element);
});
}
@override
void visitConstructorSelector(ConstructorSelector node) {
_checkChildrenEntitiesLinking(node);
_sink.writeln('ConstructorSelector');
_sink.withIndent(() {
_writeNamedChildEntities(node);
});
}
@override
void visitConstructorTearOff(ConstructorTearOff node) {
_sink.writeln('ConstructorTearOff');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
_writeElement('element', node.element);
_writeType('staticType', node.staticType);
});
}
@override
void visitConstructorTypeReference(
covariant ConstructorTypeReferenceImpl node,
) {
_sink.writeln('ConstructorTypeReference');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeElement('element', node.element);
_writeType('type', node.type);
});
}
@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) {
_writeDeclaredFragment(node.declaredFragment);
_writePatternMatchedValueType(node);
}
});
}
@override
void visitDelimitedFormalParameters(DelimitedFormalParameters node) {
_sink.writeln('DelimitedFormalParameters');
_sink.withIndent(() {
_writeNamedChildEntities(node);
});
}
@override
void visitDirectAssignment(DirectAssignment node) {
_sink.writeln('DirectAssignment');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
_writeType('staticType', node.staticType);
});
}
@override
void visitDoStatement(DoStatement node) {
_sink.writeln('DoStatement');
_sink.withIndent(() {
_writeNamedChildEntities(node);
});
}
@override
void visitDotShorthandConstructorInvocation(
covariant DotShorthandConstructorInvocationImpl node,
) {
_sink.writeln('DotShorthandConstructorInvocation');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_sink.writelnWithIndent('isDotShorthand: ${node.isDotShorthand}');
_writeParameterElement(node);
_writeType('staticType', node.staticType);
});
}
@override
void visitDotShorthandConstructorInvocation2(
covariant DotShorthandConstructorInvocation2Impl node,
) {
_sink.writeln('DotShorthandConstructorInvocation2');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_sink.writelnWithIndent('isDotShorthand: ${node.isDotShorthand}');
if (_withResolution) {
_writeDotShorthandContextResolution(
'shorthandContext',
node.shorthandContext,
);
}
_writeElement('element', node.element);
_writeParameterElement(node);
_writeType('staticType', node.staticType);
});
}
@override
void visitDotShorthandInvocation(covariant DotShorthandInvocationImpl node) {
_sink.writeln('DotShorthandInvocation');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_sink.writelnWithIndent('isDotShorthand: ${node.isDotShorthand}');
_writeParameterElement(node);
_writeType('staticInvokeType', node.staticInvokeType);
_writeType('staticType', node.staticType);
_writeTypeList('typeArgumentTypes', node.typeArgumentTypes);
});
}
@override
void visitDotShorthandMethodInvocation(
covariant DotShorthandMethodInvocationImpl node,
) {
_sink.writeln('DotShorthandMethodInvocation');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_sink.writelnWithIndent('isDotShorthand: ${node.isDotShorthand}');
if (_withResolution) {
_writeDotShorthandContextResolution(
'shorthandContext',
node.shorthandContext,
);
_writeInvocationResolution('resolution', node.resolution);
}
_writeParameterElement(node);
_writeType('staticType', node.staticType);
_writeTypeList('typeArgumentTypes', node.typeArgumentTypes);
});
}
@override
void visitDotShorthandNameExpression(
covariant DotShorthandNameExpressionImpl node,
) {
_sink.writeln('DotShorthandNameExpression');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_sink.writelnWithIndent('isDotShorthand: ${node.isDotShorthand}');
if (_withResolution) {
_writeDotShorthandContextResolution(
'shorthandContext',
node.shorthandContext,
);
_writeNamedReadResolution('resolution', node.resolution);
}
_writeParameterElement(node);
_writeType('staticType', node.staticType);
});
}
@override
void visitDotShorthandPropertyAccess(
covariant DotShorthandPropertyAccessImpl node,
) {
_sink.writeln('DotShorthandPropertyAccess');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_sink.writelnWithIndent('isDotShorthand: ${node.isDotShorthand}');
_writeParameterElement(node);
_writeType('staticType', node.staticType);
});
}
@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 visitEmptyClassBody(EmptyClassBody node) {
_sink.writeln('EmptyClassBody');
_sink.withIndent(() {
_writeNamedChildEntities(node);
});
}
@override
void visitEmptyEnumBody(EmptyEnumBody node) {
_sink.writeln('EmptyEnumBody');
_sink.withIndent(() {
_writeNamedChildEntities(node);
});
}
@override
void visitEmptyFunctionBody(EmptyFunctionBody node) {
_sink.writeln('EmptyFunctionBody');
_sink.withIndent(() {
_writeNamedChildEntities(node);
});
}
@override
void visitEmptyStatement(EmptyStatement node) {
_sink.writeln('EmptyStatement');
_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) {
_writeElement('constructorElement', node.constructorElement);
_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);
_writeElement('element', node.element);
_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);
if (_withResolution) {
_writeNamedWriteResolution(
'write',
(node as ForEachPartsWithIdentifierImpl).write,
);
}
});
}
@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 visitFormalParameterDefaultClause(FormalParameterDefaultClause node) {
_sink.writeln('FormalParameterDefaultClause');
_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);
_writeElement('element', node.element);
_writeType('staticInvokeType', node.staticInvokeType);
_writeType('staticType', node.staticType);
_writeTypeList('typeArgumentTypes', node.typeArgumentTypes);
});
}
@override
void visitFunctionInstantiation(FunctionInstantiation node) {
_sink.writeln('FunctionInstantiation');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
_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 visitFunctionTypedFormalParameterSuffix(
FunctionTypedFormalParameterSuffix node,
) {
_sink.writeln('FunctionTypedFormalParameterSuffix');
_sink.withIndent(() {
_writeNamedChildEntities(node);
});
}
@override
void visitGenericFunctionType(covariant GenericFunctionTypeImpl node) {
_sink.writeln('GenericFunctionType');
_sink.withIndent(() {
_writeNamedChildEntities(node);
if (_withResolution) {
_writeGenericFunctionTypeFragment(
'declaredFragment',
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 visitIfNull(IfNull node) {
_sink.writeln('IfNull');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
_writeType('staticType', node.staticType);
});
}
@override
void visitIfNullAssignment(IfNullAssignment node) {
_sink.writeln('IfNullAssignment');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
_writeType('staticType', node.staticType);
});
}
@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);
_writeElement('element', node.element);
_writeType('staticType', node.staticType);
_writeTypeList('typeArgumentTypes', node.typeArgumentTypes);
});
}
@override
void visitImplicitCallTearOff(ImplicitCallTearOff node) {
_sink.writeln('ImplicitCallTearOff');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
_writeElement('element', node.element);
_writeType('staticType', node.staticType);
});
}
@override
void visitImplicitFunctionInstantiation(ImplicitFunctionInstantiation node) {
_sink.writeln('ImplicitFunctionInstantiation');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
_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 visitImportPrefixedAssignmentTarget(
covariant ImportPrefixedAssignmentTargetImpl node,
) {
_sink.writeln('ImportPrefixedAssignmentTarget');
_sink.withIndent(() {
_writeNamedChildEntities(node);
if (_withResolution) {
_writeNamedReadResolution('read', node.read);
_writeNamedWriteResolution('write', node.write);
}
});
}
@override
void visitImportPrefixedFunctionInvocation(
covariant ImportPrefixedFunctionInvocationImpl node,
) {
_sink.writeln('ImportPrefixedFunctionInvocation');
_sink.withIndent(() {
_writeNamedChildEntities(node);
if (_withResolution) {
_writeInvocationResolution('resolution', node.resolution);
}
_writeParameterElement(node);
_writeType('staticType', node.staticType);
_writeTypeList('typeArgumentTypes', node.typeArgumentTypes);
});
}
@override
void visitImportPrefixedNameExpression(
covariant ImportPrefixedNameExpressionImpl node,
) {
_sink.writeln('ImportPrefixedNameExpression');
_sink.withIndent(() {
_writeNamedChildEntities(node);
if (_withResolution) {
_writeNamedReadResolution('resolution', node.resolution);
}
_writeParameterElement(node);
_writeType('staticType', node.staticType);
});
}
@override
void visitImportPrefixReference(ImportPrefixReference node) {
_sink.writeln('ImportPrefixReference');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeElement('element', node.element);
});
}
@override
void visitIncrementOrDecrementExpression(
IncrementOrDecrementExpression node,
) {
_sink.writeln('IncrementOrDecrementExpression');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_sink.writelnWithIndent('operation: ${node.operation.name}');
_sink.writelnWithIndent('position: ${node.position.name}');
_writeParameterElement(node);
_writeElement('element', node.element);
_writeType('operatorResultType', node.operatorResultType);
_writeType('staticType', node.staticType);
});
}
@override
void visitIndexExpression(IndexExpression node) {
_sink.writeln('IndexExpression');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
_writeElement('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 visitInvalidExpressionAssignmentTarget(
InvalidExpressionAssignmentTarget node,
) {
_sink.writeln('InvalidExpressionAssignmentTarget');
_sink.withIndent(() {
_writeNamedChildEntities(node);
if (_withResolution) {
switch (node.read) {
case InvalidReadResolutionImpl(:var type):
expect(type, isA<InvalidType>());
_sink.writelnWithIndent('read: InvalidReadResolution');
}
switch (node.write) {
case InvalidWriteResolutionImpl(:var acceptedType):
expect(acceptedType, isA<InvalidType>());
_sink.writelnWithIndent('write: InvalidWriteResolution');
}
}
});
}
@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);
_writeDeclaredFragment(node.declaredFragment);
});
}
@override
void visitLabeledStatement(LabeledStatement node) {
_sink.writeln('LabeledStatement');
_sink.withIndent(() {
_writeNamedChildEntities(node);
});
}
@override
void visitLabelReference(LabelReference node) {
_sink.writeln('LabelReference');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeElement('element', node.element);
});
}
@override
void visitLibraryDirective(LibraryDirective node) {
_sink.writeln('LibraryDirective');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeElement('element', node.element);
});
}
@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 visitLogicalAnd(LogicalAnd node) {
_sink.writeln('LogicalAnd');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
_writeType('staticType', node.staticType);
});
}
@override
void visitLogicalAndPattern(LogicalAndPattern node) {
_sink.writeln('LogicalAndPattern');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writePatternMatchedValueType(node);
});
}
@override
void visitLogicalNot(LogicalNot node) {
_sink.writeln('LogicalNot');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
_writeType('staticType', node.staticType);
});
}
@override
void visitLogicalOr(LogicalOr node) {
_sink.writeln('LogicalOr');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
_writeType('staticType', node.staticType);
});
}
@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 visitNamedArgument(NamedArgument node) {
_sink.writeln('NamedArgument');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
});
}
@override
void visitNamedType(NamedType node) {
_sink.writeln('NamedType');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeElement('element', node.element);
_writeType('type', node.type);
});
}
@override
void visitNameWithTypeParameters(NameWithTypeParameters node) {
_sink.writeln('NameWithTypeParameters');
_sink.withIndent(() {
_writeNamedChildEntities(node);
});
}
@override
void visitNativeClause(NativeClause node) {
_sink.writeln('NativeClause');
_sink.withIndent(() {
_writeNamedChildEntities(node);
});
}
@override
void visitNullAssertionExpression(NullAssertionExpression node) {
_sink.writeln('NullAssertionExpression');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
_writeType('staticType', node.staticType);
});
}
@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 visitParsedNameAccess(ParsedNameAccess node) {
_sink.writeln('ParsedNameAccess');
_sink.withIndent(() => _writeNamedChildEntities(node));
}
@override
void visitParsedNameAccessAssignmentTarget(
ParsedNameAccessAssignmentTarget node,
) {
_sink.writeln('ParsedNameAccessAssignmentTarget');
_sink.withIndent(() => _writeNamedChildEntities(node));
}
@override
void visitParsedTypeArguments(ParsedTypeArguments node) {
_sink.writeln('ParsedTypeArguments');
_sink.withIndent(() => _writeNamedChildEntities(node));
}
@override
void visitParsedUnqualifiedName(ParsedUnqualifiedName node) {
_sink.writeln('ParsedUnqualifiedName');
_sink.withIndent(() => _writeNamedChildEntities(node));
}
@override
void visitParsedUnqualifiedNameAssignmentTarget(
ParsedUnqualifiedNameAssignmentTarget node,
) {
_sink.writeln('ParsedUnqualifiedNameAssignmentTarget');
_sink.withIndent(() => _writeNamedChildEntities(node));
}
@override
void visitParsedValueArguments(ParsedValueArguments node) {
_sink.writeln('ParsedValueArguments');
_sink.withIndent(() => _writeNamedChildEntities(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);
_writeElement('element', node.element);
});
}
@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) {
_writeElement('readElement', node.readElement);
_writeType('readType', node.readType);
_writeElement('writeElement', node.writeElement);
_writeType('writeType', node.writeType);
}
_writeElement('element', node.element);
_writeType('staticType', node.staticType);
});
}
@override
void visitPrefixedIdentifier(PrefixedIdentifier node) {
_sink.writeln('PrefixedIdentifier');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
_writeElement('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) {
_writeElement('readElement', node.readElement);
_writeType('readType', node.readType);
_writeElement('writeElement', node.writeElement);
_writeType('writeType', node.writeType);
}
_writeElement('element', node.element);
_writeType('staticType', node.staticType);
});
}
@override
void visitPrimaryConstructorBody(PrimaryConstructorBody node) {
_sink.writeln('PrimaryConstructorBody');
_sink.withIndent(() {
_writeNamedChildEntities(node);
});
}
@override
void visitPrimaryConstructorDeclaration(PrimaryConstructorDeclaration node) {
_sink.writeln('PrimaryConstructorDeclaration');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeDeclaredFragment(node.declaredFragment);
});
}
@override
void visitPrimaryConstructorName(PrimaryConstructorName node) {
_sink.writeln('PrimaryConstructorName');
_sink.withIndent(() {
_writeNamedChildEntities(node);
});
}
@override
void visitPropertyAccess(PropertyAccess node) {
_sink.writeln('PropertyAccess');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
_writeType('staticType', node.staticType);
});
}
@override
void visitReceiverIndexAssignmentTarget(
covariant ReceiverIndexAssignmentTargetImpl node,
) {
_sink.writeln('ReceiverIndexAssignmentTarget');
_sink.withIndent(() {
_writeNamedChildEntities(node);
if (_withResolution) {
_writeIndexReadResolution('read', node.read);
_writeIndexWriteResolution('write', node.write);
}
});
}
@override
void visitReceiverIndexExpression(
covariant ReceiverIndexExpressionImpl node,
) {
_sink.writeln('ReceiverIndexExpression');
_sink.withIndent(() {
_writeNamedChildEntities(node);
if (_withResolution) {
_writeIndexReadResolution('resolution', node.resolution);
}
_writeParameterElement(node);
_writeType('staticType', node.staticType);
});
}
@override
void visitReceiverMethodInvocation(
covariant ReceiverMethodInvocationImpl node,
) {
_sink.writeln('ReceiverMethodInvocation');
_sink.withIndent(() {
_writeNamedChildEntities(node);
if (_withResolution) {
_writeInvocationResolution('resolution', node.resolution);
}
_writeParameterElement(node);
_writeType('staticType', node.staticType);
_writeTypeList('typeArgumentTypes', node.typeArgumentTypes);
});
}
@override
void visitReceiverPropertyAssignmentTarget(
covariant ReceiverPropertyAssignmentTargetImpl node,
) {
_sink.writeln('ReceiverPropertyAssignmentTarget');
_sink.withIndent(() {
_writeNamedChildEntities(node);
if (_withResolution) {
_writeNamedReadResolution('read', node.read);
_writeNamedWriteResolution('write', node.write);
}
});
}
@override
void visitReceiverPropertyExtraction(
covariant ReceiverPropertyExtractionImpl node,
) {
_sink.writeln('ReceiverPropertyExtraction');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
if (_withResolution) {
_writeNamedReadResolution('resolution', node.resolution);
}
_writeType('staticType', node.staticType);
});
}
@override
void visitRecordLiteral(RecordLiteral node) {
_sink.writeln('RecordLiteral');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeType('staticType', node.staticType);
});
}
@override
void visitRecordLiteralNamedField(RecordLiteralNamedField node) {
_sink.writeln('RecordLiteralNamedField');
_sink.withIndent(() {
_writeNamedChildEntities(node);
});
}
@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);
_writeElement('element', node.element);
});
}
@override
void visitRegularFormalParameter(RegularFormalParameter node) {
_sink.writeln('RegularFormalParameter');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeDeclaredFragment(node.declaredFragment);
});
}
@override
void visitRelationalPattern(RelationalPattern node) {
_sink.writeln('RelationalPattern');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeElement('element', node.element);
_writePatternMatchedValueType(node);
});
}
@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 visitScriptTag(ScriptTag node) {
_sink.writeln('ScriptTag');
_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 visitSimpleIdentifier(SimpleIdentifier node) {
_sink.writeln('SimpleIdentifier');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
_writeElement('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 visitStaticQualifier(StaticQualifier node) {
_sink.writeln('StaticQualifier');
_sink.withIndent(() {
_writeNamedChildEntities(node);
if (_withResolution) {
_writeElement('element', node.element);
}
});
}
@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);
_writeElement('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 visitTopLevelGetterDeclaration(TopLevelGetterDeclaration node) {
_sink.writeln('TopLevelGetterDeclaration');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeDeclaredFragment(node.declaredFragment);
});
}
@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 visitUnaryOperatorInvocation(UnaryOperatorInvocation node) {
_sink.writeln('UnaryOperatorInvocation');
_sink.withIndent(() {
_writeNamedChildEntities(node);
_writeParameterElement(node);
_writeRaw('unaryOperator', node.unaryOperator.name);
_writeElement('element', node.element);
_writeType('staticType', node.staticType);
});
}
@override
void visitUnqualifiedFunctionInvocation(
covariant UnqualifiedFunctionInvocationImpl node,
) {
_sink.writeln('UnqualifiedFunctionInvocation');
_sink.withIndent(() {
_writeNamedChildEntities(node);
if (_withResolution) {
_writeInvocationResolution('resolution', node.resolution);
}
_writeParameterElement(node);
_writeType('staticType', node.staticType);
_writeTypeList('typeArgumentTypes', node.typeArgumentTypes);
});
}
@override
void visitUnqualifiedNameAssignmentTarget(
covariant UnqualifiedNameAssignmentTargetImpl node,
) {
_sink.writeln('UnqualifiedNameAssignmentTarget');
_sink.withIndent(() {
_writeNamedChildEntities(node);
if (_withResolution) {
_writeNamedReadResolution('read', node.read);
_writeNamedWriteResolution('write', node.write);
}
});
}
@override
void visitUnqualifiedNameExpression(
covariant UnqualifiedNameExpressionImpl node,
) {
_sink.writeln('UnqualifiedNameExpression');
_sink.withIndent(() {
_writeNamedChildEntities(node);
if (_withResolution) {
_writeNamedReadResolution('resolution', node.resolution);
}
_writeParameterElement(node);
_writeType('staticType', node.staticType);
});
}
@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 writeNode(AstNode node) {
var view = node is AstNodeImpl && node.astNodeApi == AstNodeApi.v1
? _AstView.v1
: _AstView.v2;
_withView(view, () {
_acceptInView(node);
});
// TODO(scheglov): https://github.com/dart-lang/sdk/issues/63806
if (node is FormalParameterListImpl &&
node.allFormalParameters.isNotEmpty) {
_sink.writeln('FormalParameterList(v1)');
_sink.withIndent(() {
_withView(_AstView.v1, () {
_writeNamedChildEntities(node);
});
});
}
}
/// Writes [node] and its V1 compatibility view when the V2 root has a
/// distinct projection.
void writeNodeWithV1Projection(AstNode node) {
AstNode? v1;
if (node case TopLevelDeclarationImpl declaration) {
v1 = V1Projection.toV1CompilationUnitMember(declaration);
} else if (node case ExpressionImpl expression) {
v1 = V1Projection.toV1Expression(expression);
}
if (v1 == null || identical(v1, node)) {
writeNode(node);
return;
}
_withInlineV1ChildEntities(false, () => writeNode(node));
_sink.writeWithIndent('V1: ');
writeNode(v1);
}
void _acceptInView(AstNode node) {
switch (_view) {
case _AstView.v1:
node.accept(this);
case _AstView.v2:
node.accept2(this);
}
}
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 _viewChildEntities(node)) {
if (entity is Comment) {
continue;
}
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 = _viewParent(child);
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}';
}
bool _isCorrespondingParameterValue(AstNode parent, Expression node) {
return switch (parent) {
AssignmentExpression parent => identical(switch (_view) {
_AstView.v1 => parent.rightHandSide,
_AstView.v2 => parent.rightHandSide2,
}, node),
BinaryExpression parent => identical(switch (_view) {
_AstView.v1 => parent.rightOperand,
_AstView.v2 => parent.rightOperand2,
}, node),
DirectAssignment(:var value) ||
IfNullAssignment(:var value) ||
CompoundAssignment(:var value) => identical(value, node),
BinaryOperatorInvocation(:var rightOperand) => identical(
rightOperand,
node,
),
IndexAssignmentTarget(:var index) ||
IndexExpression2(:var index) => identical(index, node),
IndexExpression parent => identical(switch (_view) {
_AstView.v1 => parent.index,
_AstView.v2 => parent.index2,
}, node),
_ => false,
};
}
Iterable<SyntacticEntity> _viewChildEntities(AstNode node) {
return switch (_view) {
_AstView.v1 => node.childEntities,
_AstView.v2 => node.childEntities2,
};
}
AstNode? _viewParent(AstNode node) {
return switch (_view) {
_AstView.v1 => node.parent,
_AstView.v2 => node.parent2,
};
}
T _withInlineV1ChildEntities<T>(bool value, T Function() operation) {
var previousValue = _includeInlineV1ChildEntities;
_includeInlineV1ChildEntities = value;
try {
return operation();
} finally {
_includeInlineV1ChildEntities = previousValue;
}
}
T _withView<T>(_AstView view, T Function() operation) {
var previousView = _view;
_view = view;
try {
return operation();
} finally {
_view = previousView;
}
}
void _writeDeclaredFragment(Fragment? fragment) {
if (_withResolution) {
if (fragment is LocalVariableFragmentImpl) {
_writeDeclaredLocalVariableFragment(fragment);
} else if (fragment is TypeParameterFragmentImpl) {
_writeFragment('declaredFragment', fragment);
_sink.withIndent(() {
_writeType('defaultType', fragment.element.defaultType);
});
} else {
_writeFragment('declaredFragment', fragment);
if (fragment is ExecutableFragmentImpl) {
_sink.withIndent(() {
var element = fragment.element;
_elementPrinter.writeNamedElement2('element', element);
_sink.withIndent(() {
_writeType('type', element.type);
});
});
} else if (fragment is FormalParameterFragmentImpl) {
_sink.withIndent(() {
var element = fragment.element;
_sink.writeIndentedLine(() {
_sink.write('element:');
_writeVariableElementFlags(element);
});
_sink.withIndent(() {
_writeType('type', element.type);
if (element is FieldFormalParameterElementImpl) {
_elementPrinter.writeNamedElement2('field', element.field);
}
});
});
}
}
}
}
void _writeDeclaredLocalVariableFragment(LocalVariableFragmentImpl fragment) {
_sink.writeIndentedLine(() {
_sink.write('declaredFragment: ');
_sink.writeIf(fragment.isConst, 'isConst ');
_sink.writeIf(fragment.isFinal, 'isFinal ');
_sink.writeIf(fragment.isLate, 'isLate ');
_sink.writeIf(fragment.isPrivate, 'isPrivate ');
_sink.writeIf(fragment.isPublic, 'isPublic ');
_sink.writeIf(fragment.isStatic, 'isStatic ');
_sink.write('${fragment.name ?? ''}@${fragment.nameOffset}');
});
_sink.withIndent(() {
var element = fragment.element;
_sink.writeIndentedLine(() {
_sink.write('element:');
_writeVariableElementFlags(element);
expect(element.firstFragment, same(fragment));
expect(element.fragments, hasLength(1));
});
_sink.withIndent(() {
_writeType('type', element.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 _writeDotShorthandContextResolution(
String name,
DotShorthandContextResolutionImpl? resolution,
) {
switch (resolution) {
case null:
_sink.writelnWithIndent('$name: <null>');
case ValidDotShorthandContextResolutionImpl():
_sink.writelnWithIndent('$name: ValidDotShorthandContextResolution');
_sink.withIndent(() {
_writeType('contextType', resolution.contextType);
_writeType('lookupType', resolution.lookupType);
});
case InvalidDotShorthandContextResolutionImpl():
_sink.writelnWithIndent('$name: InvalidDotShorthandContextResolution');
_sink.withIndent(() {
_writeType('contextType', resolution.contextType);
});
}
}
void _writeElement(String name, Element? element) {
if (_withResolution) {
_elementPrinter.writeNamedElement2(name, element);
}
}
void _writeFormalParameterFragments(
List<FormalParameterFragmentImpl> fragments,
) {
_sink.writelnWithIndent('parameters');
_sink.withIndent(() {
for (var fragment in fragments) {
var name = fragment.name;
_sink.writelnWithIndent(name ?? '<empty>');
_sink.withIndent(() {
_writeParameterKind(fragment);
var element = fragment.element;
_sink.writeIndentedLine(() {
_sink.write('element:');
_sink.writeIf(element.hasImplicitType, ' hasImplicitType');
_sink.writeIf(element.isConst, ' isConst');
_sink.writeIf(element.isFinal, ' isFinal');
});
_sink.withIndent(() {
_writeType('type', element.type);
});
});
}
});
}
void _writeFragment(String name, Fragment? fragment) {
if (_withResolution) {
_elementPrinter.writeNamedFragment(name, fragment);
}
}
void _writeGenericFunctionTypeFragment(
String name,
GenericFunctionTypeFragmentImpl? fragment,
) {
_sink.writeWithIndent('$name: ');
if (fragment == null) {
_sink.writeln('<null>');
} else {
_sink.withIndent(() {
_sink.writeln('GenericFunctionTypeElement');
_writeFormalParameterFragments(fragment.formalParameters);
var element = fragment.element;
_writeType('returnType', element.returnType);
_writeType('type', element.type);
});
}
}
void _writeIndexReadResolution(
String name,
IndexReadResolutionImpl? resolution,
) {
switch (resolution) {
case null:
_sink.writelnWithIndent('$name: <null>');
case DynamicIndexReadResolutionImpl():
_sink.writelnWithIndent('$name: DynamicIndexReadResolution');
_sink.withIndent(() {
_writeType('type', resolution.type);
});
case InvalidIndexReadResolutionImpl(:var recoveryElement):
expect(resolution.type, isA<InvalidType>());
_sink.writelnWithIndent('$name: InvalidIndexReadResolution');
_sink.withIndent(() {
_writeElement('recoveryElement', recoveryElement);
});
case MethodIndexReadResolutionImpl():
_sink.writelnWithIndent('$name: MethodIndexReadResolution');
_sink.withIndent(() {
_writeElement('element', resolution.element);
_writeType('invokeType', resolution.invokeType);
_writeType('type', resolution.type);
});
}
}
void _writeIndexWriteResolution(
String name,
IndexWriteResolutionImpl? resolution,
) {
switch (resolution) {
case null:
_sink.writelnWithIndent('$name: <null>');
case DynamicIndexWriteResolutionImpl():
_sink.writelnWithIndent('$name: DynamicIndexWriteResolution');
_sink.withIndent(() {
_writeType('acceptedType', resolution.acceptedType);
});
case InvalidIndexWriteResolutionImpl(:var recoveryElement):
expect(resolution.acceptedType, isA<InvalidType>());
_sink.writelnWithIndent('$name: InvalidIndexWriteResolution');
_sink.withIndent(() {
_writeElement('recoveryElement', recoveryElement);
});
case MethodIndexWriteResolutionImpl():
_sink.writelnWithIndent('$name: MethodIndexWriteResolution');
_sink.withIndent(() {
_writeElement('element', resolution.element);
_writeType('invokeType', resolution.invokeType);
_writeType('acceptedType', resolution.acceptedType);
});
}
}
void _writeInvocationResolution(
String name,
InvocationResolutionImpl? resolution,
) {
switch (resolution) {
case null:
_sink.writelnWithIndent('$name: <null>');
case DynamicInvocationResolutionImpl():
_sink.writelnWithIndent('$name: DynamicInvocationResolution');
_sink.withIndent(() {
_writeType('type', resolution.type);
});
case ExecutableInvocationResolutionImpl():
_sink.writelnWithIndent('$name: ExecutableInvocationResolution');
_sink.withIndent(() {
_writeElement('element', resolution.element);
_writeType('invokeType', resolution.invokeType);
_writeType('type', resolution.type);
});
case FunctionCallInvocationResolutionImpl():
_sink.writelnWithIndent('$name: FunctionCallInvocationResolution');
_sink.withIndent(() {
_writeType('invokeType', resolution.invokeType);
_writeType('type', resolution.type);
});
case FunctionInterfaceInvocationResolutionImpl():
_sink.writelnWithIndent('$name: FunctionInterfaceInvocationResolution');
_sink.withIndent(() {
_writeType('type', resolution.type);
});
case FunctionTypeInvocationResolutionImpl():
_sink.writelnWithIndent('$name: FunctionTypeInvocationResolution');
_sink.withIndent(() {
_writeType('invokeType', resolution.invokeType);
_writeType('type', resolution.type);
});
case InvalidInvocationResolutionImpl():
_sink.writelnWithIndent('$name: InvalidInvocationResolution');
_sink.withIndent(() {
_writeType('type', resolution.type);
_sink.writeElements('candidates', resolution.candidates, (candidate) {
_writeElement('candidate', candidate);
});
_writeInvocationResolution('recovery', resolution.recovery);
});
}
}
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;
if (_view == _AstView.v1) {
for (var entity in node.namedChildEntities) {
_writeNamedChildEntity(node, entity);
}
return;
}
var entities2 = node.namedChildEntities2.toList();
var entities =
!_includeInlineV1ChildEntities || node.astNodeApi == AstNodeApi.v2
? <ChildEntity>[]
: node.namedChildEntities.toList();
var entitiesByName = {for (var entity in entities) entity.name: entity};
var matchedV1Names = <String>{};
for (var entity2 in entities2) {
var entity = entitiesByName[entity2.name];
if (entity == null && entity2.name.endsWith('2')) {
var v1Name = entity2.name.substring(0, entity2.name.length - 1);
entity = entitiesByName[v1Name];
}
if (entity != null) {
matchedV1Names.add(entity.name);
}
_writeNamedChildEntity(node, entity2);
var entityValue = entity?.value;
// TODO(scheglov): https://github.com/dart-lang/sdk/issues/63806
if (entity2.value is FormalParameterListImpl &&
entityValue is FormalParameterListImpl &&
entityValue.allFormalParameters.isNotEmpty) {
_withView(_AstView.v1, () {
_writeNamedChildEntity(node, entity!, name: '${entity.name}(v1)');
});
} else if (entity != null &&
entity.name != entity2.name &&
!_sameChildEntityValue(entity2.value, entity.value)) {
_withView(_AstView.v1, () {
_writeNamedChildEntity(node, entity!, name: '${entity.name}(v1)');
});
}
}
// The V1 representation of a formal parameter list manually flattens its
// parameters. It is printed separately at the property containing the
// list, rather than as additional properties of the list itself.
// TODO(scheglov): https://github.com/dart-lang/sdk/issues/63806
if (node is FormalParameterListImpl) {
return;
}
_withView(_AstView.v1, () {
for (var entity in entities) {
if (!matchedV1Names.contains(entity.name)) {
_writeNamedChildEntity(node, entity);
}
}
});
}
void _writeNamedChildEntity(
AstNode parent,
ChildEntity entity, {
String? name,
}) {
name ??= entity.name;
var value = entity.value;
if (value is Token) {
_writeToken(name, value);
} else if (value is AstNode) {
_checkParentOfChild(parent, value);
if (value is ArgumentList && configuration.skipArgumentList) {
} else {
_writeNode(name, value);
}
} else if (value is List<Token>) {
_writeTokenList(name, value);
} else if (value is List<AstNode>) {
_writeNodeList(parent, name, value);
} else {
throw UnimplementedError('(${value.runtimeType}) $value');
}
}
void _writeNamedReadResolution(
String name,
NamedReadResolutionImpl? resolution,
) {
switch (resolution) {
case null:
_sink.writelnWithIndent('$name: <null>');
case DynamicPropertyReadResolutionImpl():
_sink.writelnWithIndent('$name: DynamicPropertyReadResolution');
_sink.withIndent(() {
_writeType('type', resolution.type);
});
case ExecutableTearOffResolutionImpl():
_sink.writelnWithIndent('$name: ExecutableTearOffResolution');
_sink.withIndent(() {
_writeElement('element', resolution.element);
_writeType('type', resolution.type);
});
case FunctionCallTearOffResolutionImpl():
_sink.writelnWithIndent('$name: FunctionCallTearOffResolution');
_sink.withIndent(() {
_writeType('type', resolution.type);
_writeType(
'associatedFunctionType',
resolution.associatedFunctionType,
);
});
case FunctionInterfaceCallTearOffResolutionImpl():
_sink.writelnWithIndent(
'$name: FunctionInterfaceCallTearOffResolution',
);
_sink.withIndent(() {
_writeType('type', resolution.type);
});
case GetterInvocationResolutionImpl():
_sink.writelnWithIndent('$name: GetterInvocationResolution');
_sink.withIndent(() {
_writeElement('element', resolution.element);
_writeType('invokeType', resolution.invokeType);
_writeType('type', resolution.type);
});
case InvalidNamedReadResolutionImpl():
expect(resolution.type, isA<InvalidType>());
_sink.writelnWithIndent('$name: InvalidNamedReadResolution');
_sink.withIndent(() {
_writeElement('recoveryElement', resolution.recoveryElement);
});
case RecordFieldReadResolutionImpl():
_sink.writelnWithIndent('$name: RecordFieldReadResolution');
_sink.withIndent(() {
_writeType('type', resolution.type);
});
case VariableReadResolutionImpl():
_sink.writelnWithIndent('$name: VariableReadResolution');
_sink.withIndent(() {
_writeElement('element', resolution.element);
_writeType('type', resolution.type);
});
}
}
void _writeNamedWriteResolution(
String name,
NamedWriteResolutionImpl? resolution,
) {
switch (resolution) {
case null:
_sink.writelnWithIndent('$name: <null>');
case InvalidNamedWriteResolutionImpl():
expect(resolution.acceptedType, isA<InvalidType>());
_sink.writelnWithIndent('$name: InvalidNamedWriteResolution');
_sink.withIndent(() {
_writeElement('recoveryElement', resolution.recoveryElement);
});
case SetterInvocationResolutionImpl():
_sink.writelnWithIndent('$name: SetterInvocationResolution');
_sink.withIndent(() {
_writeElement('element', resolution.element);
_writeType('acceptedType', resolution.acceptedType);
});
case VariableWriteResolutionImpl():
_sink.writelnWithIndent('$name: VariableWriteResolution');
_sink.withIndent(() {
_writeElement('element', resolution.element);
_writeType('acceptedType', resolution.acceptedType);
});
case DynamicPropertyWriteResolutionImpl():
_sink.writelnWithIndent('$name: DynamicPropertyWriteResolution');
_sink.withIndent(() {
_writeType('acceptedType', resolution.acceptedType);
});
}
}
void _writeNode(String name, AstNode? node) {
if (node != null) {
_sink.writeWithIndent('$name: ');
_acceptInView(node);
}
}
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();
_acceptInView(node);
}
});
}
}
/// If [node] is at a position where it is an argument for an invocation,
/// writes the corresponding parameter element.
void _writeParameterElement(AstNode node) {
if (configuration.withParameterElements) {
if (node is Argument && _viewParent(node) is ArgumentList) {
_writeElement('correspondingParameter', node.correspondingParameter);
return;
}
if (node is Expression) {
var parent = _viewParent(node);
if (parent != null && _isCorrespondingParameterValue(parent, node)) {
_writeElement('correspondingParameter', node.correspondingParameter);
}
}
}
}
void _writeParameterKind(FormalParameterFragmentImpl 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: ');
_writeTokenItem(token);
});
_writeTokenPreviousNext(token);
}
void _writeTokenItem(Token token) {
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>');
}
}
void _writeTokenList(String name, List<Token> tokens) {
if (tokens.isNotEmpty) {
_sink.writelnWithIndent(name);
_sink.withIndent(() {
for (var token in tokens) {
_sink.writeIndentedLine(() {
_writeTokenItem(token);
});
_writeTokenPreviousNext(token);
}
});
}
}
void _writeTokenPreviousNext(Token token) {
if (configuration.withTokenPreviousNext) {
_sink.withIndent(() {
if (token.previous case var previous?) {
if (!previous.isEof) {
if (_tokenIdMap[previous] == null) {
_sink.withIndent(() {
_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 _writeType(String name, DartType? type) {
if (_withResolution) {
_elementPrinter.writeNamedType(name, type);
}
}
void _writeTypeList(String name, List<DartType>? types) {
if (_withResolution) {
_elementPrinter.writeTypeList(name, types);
}
}
void _writeVariableElementFlags(VariableElementImpl element) {
_sink.writeIf(element.hasImplicitType, ' hasImplicitType');
_sink.writeIf(element.isConst, ' isConst');
_sink.writeIf(element.isFinal, ' isFinal');
_sink.writeIf(element.isLate, ' isLate');
_sink.writeIf(element.isPrivate, ' isPrivate');
_sink.writeIf(element.isPublic, ' isPublic');
_sink.writeIf(element.isStatic, ' isStatic');
}
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.parentFormalParameterList2.parent2;
if (parametersParent is ConstructorDeclaration) {
var declaredFragment = parametersParent.declaredFragment!;
return declaredFragment.formalParameters;
} else if (parametersParent is FormalParameter) {
return parametersParent.functionTypedSuffix!.formalParameters.parameters
.map((parameter) => parameter.declaredFragment!)
.toList();
} else if (parametersParent is FunctionExpression) {
var declaredFragment = parametersParent.declaredFragment!;
return declaredFragment.formalParameters;
} else if (parametersParent is GenericFunctionTypeImpl) {
var declaredFragment = parametersParent.declaredFragment!;
return declaredFragment.formalParameters;
} else if (parametersParent is MethodDeclaration) {
var declaredFragment = parametersParent.declaredFragment!;
return declaredFragment.formalParameters;
} else if (parametersParent is PrimaryConstructorDeclaration) {
var declaredFragment = parametersParent.declaredFragment!;
return declaredFragment.formalParameters;
}
throw UnimplementedError(
'(${parametersParent.runtimeType}) $parametersParent',
);
}
static bool _sameChildEntityValue(Object value2, Object value) {
if (identical(value2, value)) {
return true;
}
if (value2 is List<AstNode> && value is List<AstNode>) {
if (value2.length != value.length) {
return false;
}
for (var i = 0; i < value2.length; i++) {
if (!identical(value2[i], value[i])) {
return false;
}
}
return true;
}
return false;
}
}
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 [ConstructorElement]s
/// should be printer.
bool withRedirectedConstructors = false;
/// If `true`, `superConstructor` properties of [ConstructorElement]s
/// should be printer.
bool withSuperConstructors = false;
/// If `true`, print IDs of each token, `previous` and `next` tokens.
bool withTokenPreviousNext = false;
}
enum _AstView { v1, v2 }