| // 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/ast.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/analysis/experiments.dart'; |
| import 'package:analyzer/src/dart/ast/ast.dart'; |
| import 'package:analyzer/src/dart/element/member.dart'; |
| import 'package:analyzer/src/summary/format.dart'; |
| import 'package:analyzer/src/summary/idl.dart'; |
| import 'package:analyzer/src/summary2/ast_binary_flags.dart'; |
| import 'package:analyzer/src/summary2/informative_data.dart'; |
| import 'package:analyzer/src/summary2/lazy_ast.dart'; |
| import 'package:analyzer/src/summary2/linking_bundle_context.dart'; |
| import 'package:analyzer/src/summary2/tokens_writer.dart'; |
| |
| var timerAstBinaryWriter = Stopwatch(); |
| var timerAstBinaryWriterClass = Stopwatch(); |
| var timerAstBinaryWriterDirective = Stopwatch(); |
| var timerAstBinaryWriterFunctionBody = Stopwatch(); |
| var timerAstBinaryWriterMixin = Stopwatch(); |
| var timerAstBinaryWriterTopVar = Stopwatch(); |
| var timerAstBinaryWriterTypedef = Stopwatch(); |
| |
| /// Serializer of fully resolved ASTs into flat buffers. |
| class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> { |
| final LinkingBundleContext _linkingContext; |
| |
| /// Is `true` if the current [ClassDeclaration] has a const constructor, |
| /// so initializers of final fields should be written. |
| bool _hasConstConstructor = false; |
| |
| AstBinaryWriter(this._linkingContext); |
| |
| @override |
| LinkedNodeBuilder visitAdjacentStrings(AdjacentStrings node) { |
| return LinkedNodeBuilder.adjacentStrings( |
| adjacentStrings_strings: _writeNodeList(node.strings), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitAnnotation(Annotation node) { |
| var elementComponents = _componentsOfElement(node.element); |
| |
| LinkedNodeBuilder storedArguments; |
| var arguments = node.arguments; |
| if (arguments != null) { |
| if (arguments.arguments.every(_isSerializableExpression)) { |
| storedArguments = arguments.accept(this); |
| } else { |
| storedArguments = LinkedNodeBuilder.argumentList(); |
| } |
| } |
| |
| return LinkedNodeBuilder.annotation( |
| annotation_arguments: storedArguments, |
| annotation_constructorName: node.constructorName?.accept(this), |
| annotation_element: elementComponents.rawElement, |
| annotation_substitution: elementComponents.substitution, |
| annotation_name: node.name?.accept(this), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitArgumentList(ArgumentList node) { |
| return LinkedNodeBuilder.argumentList( |
| argumentList_arguments: _writeNodeList(node.arguments), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitAsExpression(AsExpression node) { |
| return LinkedNodeBuilder.asExpression( |
| asExpression_expression: node.expression.accept(this), |
| asExpression_type: node.type.accept(this), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitAssertInitializer(AssertInitializer node) { |
| return LinkedNodeBuilder.assertInitializer( |
| assertInitializer_condition: node.condition.accept(this), |
| assertInitializer_message: node.message?.accept(this), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitAssertStatement(AssertStatement node) { |
| var builder = LinkedNodeBuilder.assertStatement( |
| assertStatement_condition: node.condition.accept(this), |
| assertStatement_message: node.message?.accept(this), |
| ); |
| _storeStatement(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitAssignmentExpression(AssignmentExpression node) { |
| var elementComponents = _componentsOfElement(node.staticElement); |
| return LinkedNodeBuilder.assignmentExpression( |
| assignmentExpression_element: elementComponents.rawElement, |
| assignmentExpression_substitution: elementComponents.substitution, |
| assignmentExpression_leftHandSide: node.leftHandSide.accept(this), |
| assignmentExpression_operator: TokensWriter.astToBinaryTokenType( |
| node.operator.type, |
| ), |
| assignmentExpression_rightHandSide: node.rightHandSide.accept(this), |
| expression_type: _writeType(node.staticType), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitAwaitExpression(AwaitExpression node) { |
| return LinkedNodeBuilder.awaitExpression( |
| awaitExpression_expression: node.expression.accept(this), |
| expression_type: _writeType(node.staticType), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitBinaryExpression(BinaryExpression node) { |
| var elementComponents = _componentsOfElement(node.staticElement); |
| return LinkedNodeBuilder.binaryExpression( |
| binaryExpression_element: elementComponents.rawElement, |
| binaryExpression_substitution: elementComponents.substitution, |
| binaryExpression_leftOperand: node.leftOperand.accept(this), |
| binaryExpression_operator: TokensWriter.astToBinaryTokenType( |
| node.operator.type, |
| ), |
| binaryExpression_rightOperand: node.rightOperand.accept(this), |
| expression_type: _writeType(node.staticType), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitBlock(Block node) { |
| return LinkedNodeBuilder.block( |
| block_statements: _writeNodeList(node.statements), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitBlockFunctionBody(BlockFunctionBody node) { |
| timerAstBinaryWriterFunctionBody.start(); |
| try { |
| var builder = LinkedNodeBuilder.blockFunctionBody( |
| blockFunctionBody_block: node.block.accept(this), |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| isAsync: node.keyword?.keyword == Keyword.ASYNC, |
| isStar: node.star != null, |
| isSync: node.keyword?.keyword == Keyword.SYNC, |
| ); |
| return builder; |
| } finally { |
| timerAstBinaryWriterFunctionBody.stop(); |
| } |
| } |
| |
| @override |
| LinkedNodeBuilder visitBooleanLiteral(BooleanLiteral node) { |
| return LinkedNodeBuilder.booleanLiteral( |
| booleanLiteral_value: node.value, |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitBreakStatement(BreakStatement node) { |
| var builder = LinkedNodeBuilder.breakStatement( |
| breakStatement_label: node.label?.accept(this), |
| ); |
| _storeStatement(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitCascadeExpression(CascadeExpression node) { |
| var builder = LinkedNodeBuilder.cascadeExpression( |
| cascadeExpression_target: node.target.accept(this), |
| cascadeExpression_sections: _writeNodeList(node.cascadeSections), |
| ); |
| _storeExpression(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitCatchClause(CatchClause node) { |
| return LinkedNodeBuilder.catchClause( |
| catchClause_body: node.body.accept(this), |
| catchClause_exceptionParameter: node.exceptionParameter?.accept(this), |
| catchClause_exceptionType: node.exceptionType?.accept(this), |
| catchClause_stackTraceParameter: node.stackTraceParameter?.accept(this), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitClassDeclaration(ClassDeclaration node) { |
| try { |
| timerAstBinaryWriterClass.start(); |
| |
| _hasConstConstructor = false; |
| for (var member in node.members) { |
| if (member is ConstructorDeclaration && member.constKeyword != null) { |
| _hasConstConstructor = true; |
| break; |
| } |
| } |
| |
| var builder = LinkedNodeBuilder.classDeclaration( |
| classDeclaration_extendsClause: node.extendsClause?.accept(this), |
| classDeclaration_nativeClause: node.nativeClause?.accept(this), |
| classDeclaration_withClause: node.withClause?.accept(this), |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| isAbstract: node.abstractKeyword != null, |
| ); |
| _storeClassOrMixinDeclaration(builder, node); |
| return builder; |
| } finally { |
| timerAstBinaryWriterClass.stop(); |
| } |
| } |
| |
| @override |
| LinkedNodeBuilder visitClassTypeAlias(ClassTypeAlias node) { |
| timerAstBinaryWriterClass.start(); |
| try { |
| var builder = LinkedNodeBuilder.classTypeAlias( |
| classTypeAlias_implementsClause: node.implementsClause?.accept(this), |
| classTypeAlias_superclass: node.superclass.accept(this), |
| classTypeAlias_typeParameters: node.typeParameters?.accept(this), |
| classTypeAlias_withClause: node.withClause.accept(this), |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| isAbstract: node.abstractKeyword != null, |
| ); |
| _storeTypeAlias(builder, node); |
| _storeIsSimpleBounded(builder, node); |
| return builder; |
| } finally { |
| timerAstBinaryWriterClass.stop(); |
| } |
| } |
| |
| @override |
| LinkedNodeBuilder visitComment(Comment node) { |
| LinkedNodeCommentType type; |
| if (node.isBlock) { |
| type = LinkedNodeCommentType.block; |
| } else if (node.isDocumentation) { |
| type = LinkedNodeCommentType.documentation; |
| } else if (node.isEndOfLine) { |
| type = LinkedNodeCommentType.endOfLine; |
| } |
| |
| return LinkedNodeBuilder.comment( |
| comment_tokens: node.tokens.map((t) => t.lexeme).toList(), |
| comment_type: type, |
| // TODO(scheglov) restore |
| // comment_references: _writeNodeList(node.references), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitCommentReference(CommentReference node) { |
| // var identifier = node.identifier; |
| // _tokensWriter.writeTokens( |
| // node.newKeyword ?? identifier.beginToken, |
| // identifier.endToken, |
| // ); |
| // |
| // return LinkedNodeBuilder.commentReference( |
| // commentReference_identifier: identifier.accept(this), |
| // commentReference_newKeyword: _getToken(node.newKeyword), |
| // ); |
| return null; |
| } |
| |
| @override |
| LinkedNodeBuilder visitCompilationUnit(CompilationUnit node) { |
| var nodeImpl = node as CompilationUnitImpl; |
| var builder = LinkedNodeBuilder.compilationUnit( |
| compilationUnit_declarations: _writeNodeList(node.declarations), |
| compilationUnit_directives: _writeNodeList(node.directives), |
| compilationUnit_featureSet: |
| (node.featureSet as ExperimentStatus).toStorage(), |
| compilationUnit_languageVersion: LinkedLibraryLanguageVersionBuilder( |
| package: LinkedLanguageVersionBuilder( |
| major: nodeImpl.languageVersion.package.major, |
| minor: nodeImpl.languageVersion.package.minor, |
| ), |
| override2: nodeImpl.languageVersion.override != null |
| ? LinkedLanguageVersionBuilder( |
| major: nodeImpl.languageVersion.override.major, |
| minor: nodeImpl.languageVersion.override.minor, |
| ) |
| : null, |
| ), |
| compilationUnit_scriptTag: node.scriptTag?.accept(this), |
| informativeId: getInformativeId(node), |
| ); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitConditionalExpression(ConditionalExpression node) { |
| var builder = LinkedNodeBuilder.conditionalExpression( |
| conditionalExpression_condition: node.condition.accept(this), |
| conditionalExpression_elseExpression: node.elseExpression.accept(this), |
| conditionalExpression_thenExpression: node.thenExpression.accept(this), |
| ); |
| _storeExpression(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitConfiguration(Configuration node) { |
| var builder = LinkedNodeBuilder.configuration( |
| configuration_name: node.name?.accept(this), |
| configuration_value: node.value?.accept(this), |
| configuration_uri: node.uri?.accept(this), |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| hasEqual: node.equalToken != null, |
| ); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitConstructorDeclaration(ConstructorDeclaration node) { |
| var builder = LinkedNodeBuilder.constructorDeclaration( |
| constructorDeclaration_initializers: _writeNodeList(node.initializers), |
| constructorDeclaration_parameters: node.parameters.accept(this), |
| constructorDeclaration_redirectedConstructor: |
| node.redirectedConstructor?.accept(this), |
| constructorDeclaration_returnType: node.returnType.accept(this), |
| informativeId: getInformativeId(node), |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| hasName: node.name != null, |
| hasSeparatorColon: node.separator?.type == TokenType.COLON, |
| hasSeparatorEquals: node.separator?.type == TokenType.EQ, |
| isAbstract: node.body is EmptyFunctionBody, |
| isConst: node.constKeyword != null, |
| isExternal: node.externalKeyword != null, |
| isFactory: node.factoryKeyword != null, |
| ); |
| builder.name = node.name?.name; |
| _storeClassMember(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitConstructorFieldInitializer( |
| ConstructorFieldInitializer node) { |
| var builder = LinkedNodeBuilder.constructorFieldInitializer( |
| constructorFieldInitializer_expression: node.expression.accept(this), |
| constructorFieldInitializer_fieldName: node.fieldName.accept(this), |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| hasThis: node.thisKeyword != null, |
| ); |
| _storeConstructorInitializer(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitConstructorName(ConstructorName node) { |
| var elementComponents = _componentsOfElement(node.staticElement); |
| return LinkedNodeBuilder.constructorName( |
| constructorName_element: elementComponents.rawElement, |
| constructorName_substitution: elementComponents.substitution, |
| constructorName_name: node.name?.accept(this), |
| constructorName_type: node.type.accept(this), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitContinueStatement(ContinueStatement node) { |
| var builder = LinkedNodeBuilder.continueStatement( |
| continueStatement_label: node.label?.accept(this), |
| ); |
| _storeStatement(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitDeclaredIdentifier(DeclaredIdentifier node) { |
| var builder = LinkedNodeBuilder.declaredIdentifier( |
| declaredIdentifier_identifier: node.identifier.accept(this), |
| declaredIdentifier_type: node.type?.accept(this), |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| isConst: node.keyword?.keyword == Keyword.CONST, |
| isFinal: node.keyword?.keyword == Keyword.FINAL, |
| isVar: node.keyword?.keyword == Keyword.VAR, |
| ); |
| _storeDeclaration(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitDefaultFormalParameter(DefaultFormalParameter node) { |
| var defaultValue = node.defaultValue; |
| if (!_isSerializableExpression(defaultValue)) { |
| defaultValue = null; |
| } |
| |
| var builder = LinkedNodeBuilder.defaultFormalParameter( |
| defaultFormalParameter_defaultValue: defaultValue?.accept(this), |
| defaultFormalParameter_kind: _toParameterKind(node), |
| defaultFormalParameter_parameter: node.parameter.accept(this), |
| informativeId: getInformativeId(node), |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| hasInitializer: node.defaultValue != null, |
| ); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitDoStatement(DoStatement node) { |
| return LinkedNodeBuilder.doStatement( |
| doStatement_body: node.body.accept(this), |
| doStatement_condition: node.condition.accept(this), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitDottedName(DottedName node) { |
| return LinkedNodeBuilder.dottedName( |
| dottedName_components: _writeNodeList(node.components), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitDoubleLiteral(DoubleLiteral node) { |
| return LinkedNodeBuilder.doubleLiteral( |
| doubleLiteral_value: node.value, |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitEmptyFunctionBody(EmptyFunctionBody node) { |
| var builder = LinkedNodeBuilder.emptyFunctionBody(); |
| _storeFunctionBody(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitEmptyStatement(EmptyStatement node) { |
| return LinkedNodeBuilder.emptyStatement(); |
| } |
| |
| @override |
| LinkedNodeBuilder visitEnumConstantDeclaration(EnumConstantDeclaration node) { |
| var builder = LinkedNodeBuilder.enumConstantDeclaration( |
| informativeId: getInformativeId(node), |
| ); |
| builder..name = node.name.name; |
| _storeDeclaration(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitEnumDeclaration(EnumDeclaration node) { |
| var builder = LinkedNodeBuilder.enumDeclaration( |
| enumDeclaration_constants: _writeNodeList(node.constants), |
| ); |
| _storeNamedCompilationUnitMember(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitExportDirective(ExportDirective node) { |
| timerAstBinaryWriterDirective.start(); |
| try { |
| var builder = LinkedNodeBuilder.exportDirective(); |
| _storeNamespaceDirective(builder, node); |
| return builder; |
| } finally { |
| timerAstBinaryWriterDirective.stop(); |
| } |
| } |
| |
| @override |
| LinkedNodeBuilder visitExpressionFunctionBody(ExpressionFunctionBody node) { |
| timerAstBinaryWriterFunctionBody.start(); |
| try { |
| var builder = LinkedNodeBuilder.expressionFunctionBody( |
| expressionFunctionBody_expression: node.expression.accept(this), |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| isAsync: node.keyword?.keyword == Keyword.ASYNC, |
| isSync: node.keyword?.keyword == Keyword.SYNC, |
| ); |
| return builder; |
| } finally { |
| timerAstBinaryWriterFunctionBody.stop(); |
| } |
| } |
| |
| @override |
| LinkedNodeBuilder visitExpressionStatement(ExpressionStatement node) { |
| return LinkedNodeBuilder.expressionStatement( |
| expressionStatement_expression: node.expression.accept(this), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitExtendsClause(ExtendsClause node) { |
| return LinkedNodeBuilder.extendsClause( |
| extendsClause_superclass: node.superclass.accept(this), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitExtensionDeclaration(ExtensionDeclaration node) { |
| var builder = LinkedNodeBuilder.extensionDeclaration( |
| extensionDeclaration_extendedType: node.extendedType.accept(this), |
| extensionDeclaration_members: _writeNodeList(node.members), |
| extensionDeclaration_typeParameters: node.typeParameters?.accept(this), |
| ); |
| |
| _storeCompilationUnitMember(builder, node); |
| _storeInformativeId(builder, node); |
| builder.name = node.name?.name; |
| LazyExtensionDeclaration.get(node).put(builder); |
| |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitExtensionOverride(ExtensionOverride node) { |
| var builder = LinkedNodeBuilder.extensionOverride( |
| extensionOverride_arguments: _writeNodeList( |
| node.argumentList.arguments, |
| ), |
| extensionOverride_extensionName: node.extensionName.accept(this), |
| extensionOverride_typeArguments: node.typeArguments?.accept(this), |
| extensionOverride_typeArgumentTypes: |
| node.typeArgumentTypes.map(_writeType).toList(), |
| extensionOverride_extendedType: _writeType(node.extendedType), |
| ); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitFieldDeclaration(FieldDeclaration node) { |
| var builder = LinkedNodeBuilder.fieldDeclaration( |
| fieldDeclaration_fields: node.fields.accept(this), |
| informativeId: getInformativeId(node), |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| isAbstract: node.abstractKeyword != null, |
| isCovariant: node.covariantKeyword != null, |
| isExternal: node.externalKeyword != null, |
| isStatic: node.staticKeyword != null, |
| ); |
| _storeClassMember(builder, node); |
| |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitFieldFormalParameter(FieldFormalParameter node) { |
| var builder = LinkedNodeBuilder.fieldFormalParameter( |
| fieldFormalParameter_formalParameters: node.parameters?.accept(this), |
| fieldFormalParameter_type: node.type?.accept(this), |
| fieldFormalParameter_typeParameters: node.typeParameters?.accept(this), |
| ); |
| _storeNormalFormalParameter(builder, node, node.keyword); |
| builder.flags |= AstBinaryFlags.encode(hasQuestion: node.question != null); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitForEachPartsWithDeclaration( |
| ForEachPartsWithDeclaration node) { |
| var builder = LinkedNodeBuilder.forEachPartsWithDeclaration( |
| forEachPartsWithDeclaration_loopVariable: node.loopVariable.accept(this), |
| ); |
| _storeForEachParts(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitForEachPartsWithIdentifier( |
| ForEachPartsWithIdentifier node) { |
| var builder = LinkedNodeBuilder.forEachPartsWithIdentifier( |
| forEachPartsWithIdentifier_identifier: node.identifier.accept(this), |
| ); |
| _storeForEachParts(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitForElement(ForElement node) { |
| var builder = LinkedNodeBuilder.forElement( |
| forElement_body: node.body.accept(this), |
| ); |
| _storeForMixin(builder, node as ForElementImpl); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitFormalParameterList(FormalParameterList node) { |
| var builder = LinkedNodeBuilder.formalParameterList( |
| formalParameterList_parameters: _writeNodeList(node.parameters), |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| isDelimiterCurly: |
| node.leftDelimiter?.type == TokenType.OPEN_CURLY_BRACKET, |
| isDelimiterSquare: |
| node.leftDelimiter?.type == TokenType.OPEN_SQUARE_BRACKET, |
| ); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitForPartsWithDeclarations( |
| ForPartsWithDeclarations node) { |
| var builder = LinkedNodeBuilder.forPartsWithDeclarations( |
| forPartsWithDeclarations_variables: node.variables.accept(this), |
| ); |
| _storeForParts(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitForPartsWithExpression(ForPartsWithExpression node) { |
| var builder = LinkedNodeBuilder.forPartsWithExpression( |
| forPartsWithExpression_initialization: node.initialization?.accept(this), |
| ); |
| _storeForParts(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitForStatement(ForStatement node) { |
| var builder = LinkedNodeBuilder.forStatement( |
| forStatement_body: node.body.accept(this), |
| ); |
| _storeForMixin(builder, node as ForStatementImpl); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitFunctionDeclaration(FunctionDeclaration node) { |
| var builder = LinkedNodeBuilder.functionDeclaration( |
| functionDeclaration_returnType: node.returnType?.accept(this), |
| functionDeclaration_functionExpression: |
| node.functionExpression?.accept(this), |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| isExternal: node.externalKeyword != null, |
| isGet: node.isGetter, |
| isSet: node.isSetter, |
| ); |
| _storeNamedCompilationUnitMember(builder, node); |
| _writeActualReturnType(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitFunctionDeclarationStatement( |
| FunctionDeclarationStatement node) { |
| return LinkedNodeBuilder.functionDeclarationStatement( |
| functionDeclarationStatement_functionDeclaration: |
| node.functionDeclaration.accept(this), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitFunctionExpression(FunctionExpression node) { |
| var bodyToStore = node.body; |
| if (node.parent.parent is CompilationUnit) { |
| bodyToStore = null; |
| } |
| var builder = LinkedNodeBuilder.functionExpression( |
| functionExpression_typeParameters: node.typeParameters?.accept(this), |
| functionExpression_formalParameters: node.parameters?.accept(this), |
| functionExpression_body: bodyToStore?.accept(this), |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| isAsync: node.body?.isAsynchronous ?? false, |
| isGenerator: node.body?.isGenerator ?? false, |
| ); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitFunctionExpressionInvocation( |
| FunctionExpressionInvocation node) { |
| var builder = LinkedNodeBuilder.functionExpressionInvocation( |
| functionExpressionInvocation_function: node.function?.accept(this), |
| ); |
| _storeInvocationExpression(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitFunctionTypeAlias(FunctionTypeAlias node) { |
| timerAstBinaryWriterTypedef.start(); |
| try { |
| var builder = LinkedNodeBuilder.functionTypeAlias( |
| functionTypeAlias_formalParameters: node.parameters.accept(this), |
| functionTypeAlias_returnType: node.returnType?.accept(this), |
| functionTypeAlias_typeParameters: node.typeParameters?.accept(this), |
| typeAlias_hasSelfReference: |
| LazyFunctionTypeAlias.getHasSelfReference(node), |
| ); |
| _storeTypeAlias(builder, node); |
| _writeActualReturnType(builder, node); |
| _storeIsSimpleBounded(builder, node); |
| return builder; |
| } finally { |
| timerAstBinaryWriterTypedef.stop(); |
| } |
| } |
| |
| @override |
| LinkedNodeBuilder visitFunctionTypedFormalParameter( |
| FunctionTypedFormalParameter node) { |
| var builder = LinkedNodeBuilder.functionTypedFormalParameter( |
| functionTypedFormalParameter_formalParameters: |
| node.parameters.accept(this), |
| functionTypedFormalParameter_returnType: node.returnType?.accept(this), |
| functionTypedFormalParameter_typeParameters: |
| node.typeParameters?.accept(this), |
| ); |
| _storeNormalFormalParameter(builder, node, null); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitGenericFunctionType(GenericFunctionType node) { |
| var id = LazyAst.getGenericFunctionTypeId(node); |
| assert(id != null); |
| |
| var builder = LinkedNodeBuilder.genericFunctionType( |
| genericFunctionType_id: id, |
| genericFunctionType_returnType: node.returnType?.accept(this), |
| genericFunctionType_typeParameters: node.typeParameters?.accept(this), |
| genericFunctionType_formalParameters: node.parameters.accept(this), |
| genericFunctionType_type: _writeType(node.type), |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| hasQuestion: node.question != null, |
| ); |
| _writeActualReturnType(builder, node); |
| |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitGenericTypeAlias(GenericTypeAlias node) { |
| timerAstBinaryWriterTypedef.start(); |
| try { |
| var builder = LinkedNodeBuilder.genericTypeAlias( |
| genericTypeAlias_typeParameters: node.typeParameters?.accept(this), |
| genericTypeAlias_functionType: node.functionType?.accept(this), |
| typeAlias_hasSelfReference: |
| LazyGenericTypeAlias.getHasSelfReference(node), |
| ); |
| _storeTypeAlias(builder, node); |
| _storeIsSimpleBounded(builder, node); |
| return builder; |
| } finally { |
| timerAstBinaryWriterTypedef.stop(); |
| } |
| } |
| |
| @override |
| LinkedNodeBuilder visitHideCombinator(HideCombinator node) { |
| var builder = LinkedNodeBuilder.hideCombinator( |
| names: node.hiddenNames.map((id) => id.name).toList(), |
| ); |
| _storeInformativeId(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitIfElement(IfElement node) { |
| var builder = LinkedNodeBuilder.ifElement( |
| ifMixin_condition: node.condition.accept(this), |
| ifElement_elseElement: node.elseElement?.accept(this), |
| ifElement_thenElement: node.thenElement.accept(this), |
| ); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitIfStatement(IfStatement node) { |
| var builder = LinkedNodeBuilder.ifStatement( |
| ifMixin_condition: node.condition.accept(this), |
| ifStatement_elseStatement: node.elseStatement?.accept(this), |
| ifStatement_thenStatement: node.thenStatement.accept(this), |
| ); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitImplementsClause(ImplementsClause node) { |
| return LinkedNodeBuilder.implementsClause( |
| implementsClause_interfaces: _writeNodeList(node.interfaces), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitImportDirective(ImportDirective node) { |
| timerAstBinaryWriterDirective.start(); |
| try { |
| var builder = LinkedNodeBuilder.importDirective( |
| importDirective_prefix: node.prefix?.name, |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| isDeferred: node.deferredKeyword != null, |
| ); |
| _storeNamespaceDirective(builder, node); |
| return builder; |
| } finally { |
| timerAstBinaryWriterDirective.stop(); |
| } |
| } |
| |
| @override |
| LinkedNodeBuilder visitIndexExpression(IndexExpression node) { |
| var elementComponents = _componentsOfElement(node.staticElement); |
| var builder = LinkedNodeBuilder.indexExpression( |
| indexExpression_element: elementComponents.rawElement, |
| indexExpression_substitution: elementComponents.substitution, |
| indexExpression_index: node.index.accept(this), |
| indexExpression_target: node.target?.accept(this), |
| expression_type: _writeType(node.staticType), |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| hasPeriod: node.period != null, |
| hasQuestion: node.question != null, |
| ); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitInstanceCreationExpression( |
| InstanceCreationExpression node) { |
| InstanceCreationExpressionImpl nodeImpl = node; |
| var builder = LinkedNodeBuilder.instanceCreationExpression( |
| instanceCreationExpression_arguments: _writeNodeList( |
| node.argumentList.arguments, |
| ), |
| instanceCreationExpression_constructorName: |
| node.constructorName.accept(this), |
| instanceCreationExpression_typeArguments: |
| nodeImpl.typeArguments?.accept(this), |
| expression_type: _writeType(node.staticType), |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| isConst: node.keyword?.type == Keyword.CONST, |
| isNew: node.keyword?.type == Keyword.NEW, |
| ); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitIntegerLiteral(IntegerLiteral node) { |
| return LinkedNodeBuilder.integerLiteral( |
| expression_type: _writeType(node.staticType), |
| integerLiteral_value: node.value, |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitInterpolationExpression(InterpolationExpression node) { |
| return LinkedNodeBuilder.interpolationExpression( |
| interpolationExpression_expression: node.expression.accept(this), |
| )..flags = AstBinaryFlags.encode( |
| isStringInterpolationIdentifier: |
| node.leftBracket.type == TokenType.STRING_INTERPOLATION_IDENTIFIER, |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitInterpolationString(InterpolationString node) { |
| return LinkedNodeBuilder.interpolationString( |
| interpolationString_value: node.value, |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitIsExpression(IsExpression node) { |
| var builder = LinkedNodeBuilder.isExpression( |
| isExpression_expression: node.expression.accept(this), |
| isExpression_type: node.type.accept(this), |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| hasNot: node.notOperator != null, |
| ); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitLabel(Label node) { |
| return LinkedNodeBuilder.label( |
| label_label: node.label.accept(this), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitLabeledStatement(LabeledStatement node) { |
| return LinkedNodeBuilder.labeledStatement( |
| labeledStatement_labels: _writeNodeList(node.labels), |
| labeledStatement_statement: node.statement.accept(this), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitLibraryDirective(LibraryDirective node) { |
| timerAstBinaryWriterDirective.start(); |
| try { |
| var builder = LinkedNodeBuilder.libraryDirective( |
| informativeId: getInformativeId(node), |
| libraryDirective_name: node.name.accept(this), |
| ); |
| _storeDirective(builder, node); |
| return builder; |
| } finally { |
| timerAstBinaryWriterDirective.stop(); |
| } |
| } |
| |
| @override |
| LinkedNodeBuilder visitLibraryIdentifier(LibraryIdentifier node) { |
| return LinkedNodeBuilder.libraryIdentifier( |
| libraryIdentifier_components: _writeNodeList(node.components), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitListLiteral(ListLiteral node) { |
| var builder = LinkedNodeBuilder.listLiteral( |
| listLiteral_elements: _writeNodeList(node.elements), |
| ); |
| _storeTypedLiteral(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitMapLiteralEntry(MapLiteralEntry node) { |
| return LinkedNodeBuilder.mapLiteralEntry( |
| mapLiteralEntry_key: node.key.accept(this), |
| mapLiteralEntry_value: node.value.accept(this), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitMethodDeclaration(MethodDeclaration node) { |
| var builder = LinkedNodeBuilder.methodDeclaration( |
| methodDeclaration_returnType: node.returnType?.accept(this), |
| methodDeclaration_typeParameters: node.typeParameters?.accept(this), |
| methodDeclaration_formalParameters: node.parameters?.accept(this), |
| methodDeclaration_hasOperatorEqualWithParameterTypeFromObject: |
| LazyAst.hasOperatorEqualParameterTypeFromObject(node), |
| ); |
| builder.name = node.name.name; |
| builder.flags = AstBinaryFlags.encode( |
| isAbstract: node.body is EmptyFunctionBody, |
| isAsync: node.body?.isAsynchronous ?? false, |
| isExternal: node.externalKeyword != null, |
| isGenerator: node.body?.isGenerator ?? false, |
| isGet: node.isGetter, |
| isNative: node.body is NativeFunctionBody, |
| isOperator: node.operatorKeyword != null, |
| isSet: node.isSetter, |
| isStatic: node.isStatic, |
| ); |
| builder.topLevelTypeInferenceError = LazyAst.getTypeInferenceError(node); |
| _storeClassMember(builder, node); |
| _storeInformativeId(builder, node); |
| _writeActualReturnType(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitMethodInvocation(MethodInvocation node) { |
| var builder = LinkedNodeBuilder.methodInvocation( |
| methodInvocation_methodName: node.methodName?.accept(this), |
| methodInvocation_target: node.target?.accept(this), |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| hasPeriod: node.operator?.type == TokenType.PERIOD, |
| hasPeriod2: node.operator?.type == TokenType.PERIOD_PERIOD, |
| ); |
| _storeInvocationExpression(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitMixinDeclaration(MixinDeclaration node) { |
| timerAstBinaryWriterMixin.start(); |
| try { |
| var builder = LinkedNodeBuilder.mixinDeclaration( |
| mixinDeclaration_onClause: node.onClause?.accept(this), |
| ); |
| _storeClassOrMixinDeclaration(builder, node); |
| LazyMixinDeclaration.get(node).put(builder); |
| return builder; |
| } finally { |
| timerAstBinaryWriterMixin.stop(); |
| } |
| } |
| |
| @override |
| LinkedNodeBuilder visitNamedExpression(NamedExpression node) { |
| return LinkedNodeBuilder.namedExpression( |
| namedExpression_expression: node.expression.accept(this), |
| namedExpression_name: node.name.accept(this), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitNativeClause(NativeClause node) { |
| return LinkedNodeBuilder.nativeClause( |
| nativeClause_name: node.name.accept(this), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitNativeFunctionBody(NativeFunctionBody node) { |
| return LinkedNodeBuilder.nativeFunctionBody( |
| nativeFunctionBody_stringLiteral: node.stringLiteral?.accept(this), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitNullLiteral(NullLiteral node) { |
| return LinkedNodeBuilder.nullLiteral(); |
| } |
| |
| @override |
| LinkedNodeBuilder visitOnClause(OnClause node) { |
| return LinkedNodeBuilder.onClause( |
| onClause_superclassConstraints: |
| _writeNodeList(node.superclassConstraints), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitParenthesizedExpression(ParenthesizedExpression node) { |
| var builder = LinkedNodeBuilder.parenthesizedExpression( |
| parenthesizedExpression_expression: node.expression.accept(this), |
| ); |
| _storeExpression(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitPartDirective(PartDirective node) { |
| timerAstBinaryWriterDirective.start(); |
| try { |
| var builder = LinkedNodeBuilder.partDirective(); |
| _storeUriBasedDirective(builder, node); |
| return builder; |
| } finally { |
| timerAstBinaryWriterDirective.stop(); |
| } |
| } |
| |
| @override |
| LinkedNodeBuilder visitPartOfDirective(PartOfDirective node) { |
| timerAstBinaryWriterDirective.start(); |
| try { |
| var builder = LinkedNodeBuilder.partOfDirective( |
| partOfDirective_libraryName: node.libraryName?.accept(this), |
| partOfDirective_uri: node.uri?.accept(this), |
| ); |
| _storeDirective(builder, node); |
| return builder; |
| } finally { |
| timerAstBinaryWriterDirective.stop(); |
| } |
| } |
| |
| @override |
| LinkedNodeBuilder visitPostfixExpression(PostfixExpression node) { |
| var elementComponents = _componentsOfElement(node.staticElement); |
| return LinkedNodeBuilder.postfixExpression( |
| expression_type: _writeType(node.staticType), |
| postfixExpression_element: elementComponents.rawElement, |
| postfixExpression_substitution: elementComponents.substitution, |
| postfixExpression_operand: node.operand.accept(this), |
| postfixExpression_operator: TokensWriter.astToBinaryTokenType( |
| node.operator.type, |
| ), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitPrefixedIdentifier(PrefixedIdentifier node) { |
| return LinkedNodeBuilder.prefixedIdentifier( |
| prefixedIdentifier_identifier: node.identifier.accept(this), |
| prefixedIdentifier_prefix: node.prefix.accept(this), |
| expression_type: _writeType(node.staticType), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitPrefixExpression(PrefixExpression node) { |
| var elementComponents = _componentsOfElement(node.staticElement); |
| return LinkedNodeBuilder.prefixExpression( |
| expression_type: _writeType(node.staticType), |
| prefixExpression_element: elementComponents.rawElement, |
| prefixExpression_substitution: elementComponents.substitution, |
| prefixExpression_operand: node.operand.accept(this), |
| prefixExpression_operator: TokensWriter.astToBinaryTokenType( |
| node.operator.type, |
| ), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitPropertyAccess(PropertyAccess node) { |
| var builder = LinkedNodeBuilder.propertyAccess( |
| propertyAccess_operator: TokensWriter.astToBinaryTokenType( |
| node.operator.type, |
| ), |
| propertyAccess_propertyName: node.propertyName.accept(this), |
| propertyAccess_target: node.target?.accept(this), |
| ); |
| _storeExpression(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitRedirectingConstructorInvocation( |
| RedirectingConstructorInvocation node) { |
| var elementComponents = _componentsOfElement(node.staticElement); |
| var builder = LinkedNodeBuilder.redirectingConstructorInvocation( |
| redirectingConstructorInvocation_arguments: |
| node.argumentList.accept(this), |
| redirectingConstructorInvocation_constructorName: |
| node.constructorName?.accept(this), |
| redirectingConstructorInvocation_element: elementComponents.rawElement, |
| redirectingConstructorInvocation_substitution: |
| elementComponents.substitution, |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| hasThis: node.thisKeyword != null, |
| ); |
| _storeConstructorInitializer(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitRethrowExpression(RethrowExpression node) { |
| return LinkedNodeBuilder.rethrowExpression( |
| expression_type: _writeType(node.staticType), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitReturnStatement(ReturnStatement node) { |
| return LinkedNodeBuilder.returnStatement( |
| returnStatement_expression: node.expression?.accept(this), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitScriptTag(ScriptTag node) { |
| return null; |
| } |
| |
| @override |
| LinkedNodeBuilder visitSetOrMapLiteral(SetOrMapLiteral node) { |
| var builder = LinkedNodeBuilder.setOrMapLiteral( |
| setOrMapLiteral_elements: _writeNodeList(node.elements), |
| ); |
| _storeTypedLiteral(builder, node, isMap: node.isMap, isSet: node.isSet); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitShowCombinator(ShowCombinator node) { |
| var builder = LinkedNodeBuilder.showCombinator( |
| names: node.shownNames.map((id) => id.name).toList(), |
| ); |
| _storeInformativeId(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitSimpleFormalParameter(SimpleFormalParameter node) { |
| var builder = LinkedNodeBuilder.simpleFormalParameter( |
| simpleFormalParameter_type: node.type?.accept(this), |
| ); |
| builder.topLevelTypeInferenceError = LazyAst.getTypeInferenceError(node); |
| _storeNormalFormalParameter(builder, node, node.keyword); |
| _storeInheritsCovariant(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitSimpleIdentifier(SimpleIdentifier node) { |
| Element element; |
| if (!node.inDeclarationContext()) { |
| element = node.staticElement; |
| if (element is MultiplyDefinedElement) { |
| element = null; |
| } |
| } |
| |
| var elementComponents = _componentsOfElement(element); |
| var builder = LinkedNodeBuilder.simpleIdentifier( |
| simpleIdentifier_element: elementComponents.rawElement, |
| simpleIdentifier_substitution: elementComponents.substitution, |
| expression_type: _writeType(node.staticType), |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| isDeclaration: node is DeclaredSimpleIdentifier, |
| ); |
| builder.name = node.name; |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitSimpleStringLiteral(SimpleStringLiteral node) { |
| var builder = LinkedNodeBuilder.simpleStringLiteral( |
| simpleStringLiteral_value: node.value, |
| ); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitSpreadElement(SpreadElement node) { |
| return LinkedNodeBuilder.spreadElement( |
| spreadElement_expression: node.expression.accept(this), |
| spreadElement_spreadOperator: TokensWriter.astToBinaryTokenType( |
| node.spreadOperator.type, |
| ), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitStringInterpolation(StringInterpolation node) { |
| return LinkedNodeBuilder.stringInterpolation( |
| stringInterpolation_elements: _writeNodeList(node.elements), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitSuperConstructorInvocation( |
| SuperConstructorInvocation node) { |
| var elementComponents = _componentsOfElement(node.staticElement); |
| var builder = LinkedNodeBuilder.superConstructorInvocation( |
| superConstructorInvocation_arguments: node.argumentList.accept(this), |
| superConstructorInvocation_constructorName: |
| node.constructorName?.accept(this), |
| superConstructorInvocation_element: elementComponents.rawElement, |
| superConstructorInvocation_substitution: elementComponents.substitution, |
| ); |
| _storeConstructorInitializer(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitSuperExpression(SuperExpression node) { |
| var builder = LinkedNodeBuilder.superExpression(); |
| _storeExpression(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitSwitchCase(SwitchCase node) { |
| var builder = LinkedNodeBuilder.switchCase( |
| switchCase_expression: node.expression.accept(this), |
| ); |
| _storeSwitchMember(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitSwitchDefault(SwitchDefault node) { |
| var builder = LinkedNodeBuilder.switchDefault(); |
| _storeSwitchMember(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitSwitchStatement(SwitchStatement node) { |
| return LinkedNodeBuilder.switchStatement( |
| switchStatement_expression: node.expression.accept(this), |
| switchStatement_members: _writeNodeList(node.members), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitSymbolLiteral(SymbolLiteral node) { |
| var builder = LinkedNodeBuilder.symbolLiteral( |
| names: node.components.map((t) => t.lexeme).toList(), |
| ); |
| _storeExpression(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitThisExpression(ThisExpression node) { |
| var builder = LinkedNodeBuilder.thisExpression(); |
| _storeExpression(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitThrowExpression(ThrowExpression node) { |
| return LinkedNodeBuilder.throwExpression( |
| throwExpression_expression: node.expression.accept(this), |
| expression_type: _writeType(node.staticType), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitTopLevelVariableDeclaration( |
| TopLevelVariableDeclaration node) { |
| timerAstBinaryWriterTopVar.start(); |
| try { |
| var builder = LinkedNodeBuilder.topLevelVariableDeclaration( |
| informativeId: getInformativeId(node), |
| topLevelVariableDeclaration_variableList: node.variables?.accept(this), |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| isExternal: node.externalKeyword != null, |
| ); |
| _storeCompilationUnitMember(builder, node); |
| |
| return builder; |
| } finally { |
| timerAstBinaryWriterTopVar.stop(); |
| } |
| } |
| |
| @override |
| LinkedNodeBuilder visitTryStatement(TryStatement node) { |
| return LinkedNodeBuilder.tryStatement( |
| tryStatement_body: node.body.accept(this), |
| tryStatement_catchClauses: _writeNodeList(node.catchClauses), |
| tryStatement_finallyBlock: node.finallyBlock?.accept(this), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitTypeArgumentList(TypeArgumentList node) { |
| return LinkedNodeBuilder.typeArgumentList( |
| typeArgumentList_arguments: _writeNodeList(node.arguments), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitTypeName(TypeName node) { |
| return LinkedNodeBuilder.typeName( |
| typeName_name: node.name.accept(this), |
| typeName_type: _writeType(node.type), |
| typeName_typeArguments: _writeNodeList( |
| node.typeArguments?.arguments, |
| ), |
| )..flags = AstBinaryFlags.encode( |
| hasQuestion: node.question != null, |
| hasTypeArguments: node.typeArguments != null, |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitTypeParameter(TypeParameter node) { |
| var builder = LinkedNodeBuilder.typeParameter( |
| typeParameter_bound: node.bound?.accept(this), |
| typeParameter_defaultType: _writeType(LazyAst.getDefaultType(node)), |
| typeParameter_variance: _getVarianceToken(node), |
| informativeId: getInformativeId(node), |
| ); |
| builder.name = node.name.name; |
| _storeDeclaration(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitTypeParameterList(TypeParameterList node) { |
| return LinkedNodeBuilder.typeParameterList( |
| typeParameterList_typeParameters: _writeNodeList(node.typeParameters), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitVariableDeclaration(VariableDeclaration node) { |
| var initializer = node.initializer; |
| var declarationList = node.parent as VariableDeclarationList; |
| var declaration = declarationList.parent; |
| if (declaration is TopLevelVariableDeclaration) { |
| if (!declarationList.isConst) { |
| initializer = null; |
| } |
| } else if (declaration is FieldDeclaration) { |
| if (!(declarationList.isConst || |
| !declaration.isStatic && |
| declarationList.isFinal && |
| _hasConstConstructor)) { |
| initializer = null; |
| } |
| } |
| |
| if (!_isSerializableExpression(initializer)) { |
| initializer = null; |
| } |
| |
| var builder = LinkedNodeBuilder.variableDeclaration( |
| informativeId: getInformativeId(node), |
| variableDeclaration_initializer: initializer?.accept(this), |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| hasInitializer: node.initializer != null, |
| ); |
| builder.name = node.name.name; |
| builder.topLevelTypeInferenceError = LazyAst.getTypeInferenceError(node); |
| _writeActualType(builder, node); |
| _storeInheritsCovariant(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitVariableDeclarationList(VariableDeclarationList node) { |
| var builder = LinkedNodeBuilder.variableDeclarationList( |
| variableDeclarationList_type: node.type?.accept(this), |
| variableDeclarationList_variables: _writeNodeList(node.variables), |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| isConst: node.isConst, |
| isFinal: node.isFinal, |
| isLate: node.lateKeyword != null, |
| isVar: node.keyword?.keyword == Keyword.VAR, |
| ); |
| _storeAnnotatedNode(builder, node); |
| return builder; |
| } |
| |
| @override |
| LinkedNodeBuilder visitVariableDeclarationStatement( |
| VariableDeclarationStatement node) { |
| return LinkedNodeBuilder.variableDeclarationStatement( |
| variableDeclarationStatement_variables: node.variables.accept(this), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitWhileStatement(WhileStatement node) { |
| return LinkedNodeBuilder.whileStatement( |
| whileStatement_body: node.body.accept(this), |
| whileStatement_condition: node.condition.accept(this), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitWithClause(WithClause node) { |
| return LinkedNodeBuilder.withClause( |
| withClause_mixinTypes: _writeNodeList(node.mixinTypes), |
| ); |
| } |
| |
| @override |
| LinkedNodeBuilder visitYieldStatement(YieldStatement node) { |
| var builder = LinkedNodeBuilder.yieldStatement( |
| yieldStatement_expression: node.expression.accept(this), |
| ); |
| builder.flags = AstBinaryFlags.encode( |
| isStar: node.star != null, |
| ); |
| _storeStatement(builder, node); |
| return builder; |
| } |
| |
| LinkedNodeBuilder writeUnit(CompilationUnit unit) { |
| timerAstBinaryWriter.start(); |
| try { |
| return unit.accept(this); |
| } finally { |
| timerAstBinaryWriter.stop(); |
| } |
| } |
| |
| _ElementComponents _componentsOfElement(Element element) { |
| if (element is ParameterMember) { |
| element = element.declaration; |
| } |
| |
| if (element is Member) { |
| var elementIndex = _indexOfElement(element.declaration); |
| var substitution = element.substitution.map; |
| var substitutionBuilder = LinkedNodeTypeSubstitutionBuilder( |
| isLegacy: element.isLegacy, |
| typeParameters: substitution.keys.map(_indexOfElement).toList(), |
| typeArguments: substitution.values.map(_writeType).toList(), |
| ); |
| return _ElementComponents(elementIndex, substitutionBuilder); |
| } |
| |
| var elementIndex = _indexOfElement(element); |
| return _ElementComponents(elementIndex, null); |
| } |
| |
| UnlinkedTokenType _getVarianceToken(TypeParameter parameter) { |
| // TODO (kallentu) : Clean up TypeParameterImpl casting once variance is |
| // added to the interface. |
| var parameterImpl = parameter as TypeParameterImpl; |
| return parameterImpl.varianceKeyword != null |
| ? TokensWriter.astToBinaryTokenType(parameterImpl.varianceKeyword.type) |
| : null; |
| } |
| |
| int _indexOfElement(Element element) { |
| return _linkingContext.indexOfElement(element); |
| } |
| |
| void _storeAnnotatedNode(LinkedNodeBuilder builder, AnnotatedNode node) { |
| builder.annotatedNode_metadata = _writeNodeList(node.metadata); |
| } |
| |
| void _storeClassMember(LinkedNodeBuilder builder, ClassMember node) { |
| _storeDeclaration(builder, node); |
| } |
| |
| void _storeClassOrMixinDeclaration( |
| LinkedNodeBuilder builder, ClassOrMixinDeclaration node) { |
| builder |
| ..classOrMixinDeclaration_implementsClause = |
| node.implementsClause?.accept(this) |
| ..classOrMixinDeclaration_members = _writeNodeList(node.members) |
| ..classOrMixinDeclaration_typeParameters = |
| node.typeParameters?.accept(this); |
| _storeNamedCompilationUnitMember(builder, node); |
| _storeIsSimpleBounded(builder, node); |
| } |
| |
| void _storeCompilationUnitMember( |
| LinkedNodeBuilder builder, CompilationUnitMember node) { |
| _storeDeclaration(builder, node); |
| } |
| |
| void _storeConstructorInitializer( |
| LinkedNodeBuilder builder, ConstructorInitializer node) {} |
| |
| void _storeDeclaration(LinkedNodeBuilder builder, Declaration node) { |
| _storeAnnotatedNode(builder, node); |
| } |
| |
| void _storeDirective(LinkedNodeBuilder builder, Directive node) { |
| _storeAnnotatedNode(builder, node); |
| _storeInformativeId(builder, node); |
| } |
| |
| void _storeExpression(LinkedNodeBuilder builder, Expression node) { |
| builder.expression_type = _writeType(node.staticType); |
| } |
| |
| void _storeForEachParts(LinkedNodeBuilder builder, ForEachParts node) { |
| _storeForLoopParts(builder, node); |
| builder..forEachParts_iterable = node.iterable?.accept(this); |
| } |
| |
| void _storeForLoopParts(LinkedNodeBuilder builder, ForLoopParts node) {} |
| |
| void _storeFormalParameter(LinkedNodeBuilder builder, FormalParameter node) { |
| _writeActualType(builder, node); |
| } |
| |
| void _storeForMixin(LinkedNodeBuilder builder, ForMixin node) { |
| builder.flags = AstBinaryFlags.encode( |
| hasAwait: node.awaitKeyword != null, |
| ); |
| builder..forMixin_forLoopParts = node.forLoopParts.accept(this); |
| } |
| |
| void _storeForParts(LinkedNodeBuilder builder, ForParts node) { |
| _storeForLoopParts(builder, node); |
| builder |
| ..forParts_condition = node.condition?.accept(this) |
| ..forParts_updaters = _writeNodeList(node.updaters); |
| } |
| |
| void _storeFunctionBody(LinkedNodeBuilder builder, FunctionBody node) {} |
| |
| void _storeInformativeId(LinkedNodeBuilder builder, AstNode node) { |
| builder.informativeId = getInformativeId(node); |
| } |
| |
| void _storeInheritsCovariant(LinkedNodeBuilder builder, AstNode node) { |
| var value = LazyAst.getInheritsCovariant(node); |
| builder.inheritsCovariant = value; |
| } |
| |
| void _storeInvocationExpression( |
| LinkedNodeBuilder builder, InvocationExpression node) { |
| _storeExpression(builder, node); |
| builder |
| ..invocationExpression_arguments = node.argumentList.accept(this) |
| ..invocationExpression_invokeType = _writeType(node.staticInvokeType) |
| ..invocationExpression_typeArguments = node.typeArguments?.accept(this); |
| } |
| |
| void _storeIsSimpleBounded(LinkedNodeBuilder builder, AstNode node) { |
| var flag = LazyAst.isSimplyBounded(node); |
| // TODO(scheglov) Check for `null` when writing resolved AST. |
| builder.simplyBoundable_isSimplyBounded = flag; |
| } |
| |
| void _storeNamedCompilationUnitMember( |
| LinkedNodeBuilder builder, NamedCompilationUnitMember node) { |
| _storeCompilationUnitMember(builder, node); |
| _storeInformativeId(builder, node); |
| builder.name = node.name.name; |
| } |
| |
| void _storeNamespaceDirective( |
| LinkedNodeBuilder builder, NamespaceDirective node) { |
| _storeUriBasedDirective(builder, node); |
| builder |
| ..namespaceDirective_combinators = _writeNodeList(node.combinators) |
| ..namespaceDirective_configurations = _writeNodeList(node.configurations) |
| ..namespaceDirective_selectedUri = LazyDirective.getSelectedUri(node); |
| } |
| |
| void _storeNormalFormalParameter( |
| LinkedNodeBuilder builder, NormalFormalParameter node, Token keyword) { |
| _storeFormalParameter(builder, node); |
| builder |
| ..flags = AstBinaryFlags.encode( |
| isConst: keyword?.type == Keyword.CONST, |
| isCovariant: node.covariantKeyword != null, |
| isFinal: keyword?.type == Keyword.FINAL, |
| isRequired: node.requiredKeyword != null, |
| isVar: keyword?.type == Keyword.VAR, |
| ) |
| ..informativeId = getInformativeId(node) |
| ..name = node.identifier?.name |
| ..normalFormalParameter_metadata = _writeNodeList(node.metadata); |
| } |
| |
| void _storeStatement(LinkedNodeBuilder builder, Statement node) {} |
| |
| void _storeSwitchMember(LinkedNodeBuilder builder, SwitchMember node) { |
| builder.switchMember_labels = _writeNodeList(node.labels); |
| builder.switchMember_statements = _writeNodeList(node.statements); |
| } |
| |
| void _storeTypeAlias(LinkedNodeBuilder builder, TypeAlias node) { |
| _storeNamedCompilationUnitMember(builder, node); |
| } |
| |
| void _storeTypedLiteral(LinkedNodeBuilder builder, TypedLiteral node, |
| {bool isMap = false, bool isSet = false}) { |
| _storeExpression(builder, node); |
| builder |
| ..flags = AstBinaryFlags.encode( |
| hasTypeArguments: node.typeArguments != null, |
| isConst: node.constKeyword != null, |
| isMap: isMap, |
| isSet: isSet, |
| ) |
| ..typedLiteral_typeArguments = _writeNodeList( |
| node.typeArguments?.arguments, |
| ); |
| } |
| |
| void _storeUriBasedDirective( |
| LinkedNodeBuilder builder, UriBasedDirective node) { |
| _storeDirective(builder, node); |
| builder |
| ..uriBasedDirective_uri = node.uri.accept(this) |
| ..uriBasedDirective_uriContent = node.uriContent |
| ..uriBasedDirective_uriElement = _indexOfElement(node.uriElement); |
| } |
| |
| void _writeActualReturnType(LinkedNodeBuilder builder, AstNode node) { |
| var type = LazyAst.getReturnType(node); |
| // TODO(scheglov) Check for `null` when writing resolved AST. |
| builder.actualReturnType = _writeType(type); |
| } |
| |
| void _writeActualType(LinkedNodeBuilder builder, AstNode node) { |
| var type = LazyAst.getType(node); |
| // TODO(scheglov) Check for `null` when writing resolved AST. |
| builder.actualType = _writeType(type); |
| } |
| |
| List<LinkedNodeBuilder> _writeNodeList(List<AstNode> nodeList) { |
| if (nodeList == null) { |
| return const <LinkedNodeBuilder>[]; |
| } |
| |
| var result = List<LinkedNodeBuilder>.filled( |
| nodeList.length, |
| null, |
| growable: true, |
| ); |
| for (var i = 0; i < nodeList.length; ++i) { |
| result[i] = nodeList[i].accept(this); |
| } |
| return result; |
| } |
| |
| LinkedNodeTypeBuilder _writeType(DartType type) { |
| return _linkingContext.writeType(type); |
| } |
| |
| /// Return `true` if the expression might be successfully serialized. |
| /// |
| /// This does not mean that the expression is constant, it just means that |
| /// we know that it might be serialized and deserialized. For example |
| /// function expressions are problematic, and are not necessary to |
| /// deserialize, so we choose not to do this. |
| static bool _isSerializableExpression(Expression node) { |
| if (node == null) return false; |
| |
| var visitor = _IsSerializableExpressionVisitor(); |
| node.accept(visitor); |
| return visitor.result; |
| } |
| |
| static LinkedNodeFormalParameterKind _toParameterKind(FormalParameter node) { |
| if (node.isRequiredPositional) { |
| return LinkedNodeFormalParameterKind.requiredPositional; |
| } else if (node.isRequiredNamed) { |
| return LinkedNodeFormalParameterKind.requiredNamed; |
| } else if (node.isOptionalPositional) { |
| return LinkedNodeFormalParameterKind.optionalPositional; |
| } else if (node.isOptionalNamed) { |
| return LinkedNodeFormalParameterKind.optionalNamed; |
| } else { |
| throw StateError('Unknown kind of parameter'); |
| } |
| } |
| } |
| |
| /// Components of a [Member] - the raw element, and the substitution. |
| class _ElementComponents { |
| final int rawElement; |
| final LinkedNodeTypeSubstitutionBuilder substitution; |
| |
| _ElementComponents(this.rawElement, this.substitution); |
| } |
| |
| class _IsSerializableExpressionVisitor extends RecursiveAstVisitor<void> { |
| bool result = true; |
| |
| @override |
| void visitFunctionExpression(FunctionExpression node) { |
| result = false; |
| } |
| } |