Files
sdk/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
T
Konstantin Shcheglov e9d8109258 DeCo. Support empty bodies in membered declarations
Allow enums, extensions, and mixins to use `;` as their body and
represent that form explicitly in the AST. The parser now produces
`EmptyEnumBody` or `EmptyClassBody` for the empty form.

Also replace `LibraryIdentifier` with token-based `DottedName` and store
the full token sequence for dotted names. This preserves periods and
source offsets directly in the AST, which keeps printing, selection, and
directive name handling working with the new shape. See
https://github.com/dart-lang/sdk/issues/62819

See https://github.com/dart-lang/language/issues/4645

Google3 presubmit looks green:
https://fusion2.corp.google.com/presubmit/884063020/OCL:884063020:BASE:884079610:1773618867493:b2110d76

Change-Id: I2d023cd03b6423da634c3e14742e02a61dc3b403
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/486080
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2026-03-16 08:56:11 -07:00

1457 lines
46 KiB
Dart

// 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:_fe_analyzer_shared/src/scanner/string_canonicalizer.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/testing/token_factory.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary2/ast_binary_flags.dart';
import 'package:analyzer/src/summary2/ast_binary_tag.dart';
import 'package:analyzer/src/summary2/ast_binary_tokens.dart';
import 'package:analyzer/src/summary2/bundle_reader.dart';
import 'package:analyzer/src/summary2/unlinked_token_type.dart';
import 'package:collection/collection.dart';
/// Deserializer of ASTs.
class AstBinaryReader {
final ResolutionReader _reader;
AstBinaryReader({required ResolutionReader reader}) : _reader = reader;
AstNode readNode() {
var node = _readNode();
if (node is AstNodeImpl) {
AstNodeImpl.linkNodeTokens(node);
}
return node;
}
IntegerLiteral _createIntegerLiteral(String lexeme, int value) {
var node = IntegerLiteralImpl(
// TODO(srawlins): TokenType.INT_WITH_SEPARATORS?
literal: TokenFactory.tokenFromTypeAndString(TokenType.INT, lexeme),
value: value,
);
_readExpressionResolution(node);
return node;
}
AdjacentStrings _readAdjacentStrings() {
var components = _readNodeList<StringLiteralImpl>();
var node = AdjacentStringsImpl(strings: components);
_readExpressionResolution(node);
return node;
}
Annotation _readAnnotation() {
var name = _readNode() as IdentifierImpl;
var typeArguments = _readOptionalNode() as TypeArgumentListImpl?;
var constructorName = _readOptionalNode() as SimpleIdentifierImpl?;
var arguments = _readOptionalNode() as ArgumentListImpl?;
var node = AnnotationImpl(
atSign: Tokens.at(),
name: name,
typeArguments: typeArguments,
period: constructorName != null ? Tokens.period() : null,
constructorName: constructorName,
arguments: arguments,
);
node.element = _reader.readElement();
if (arguments != null) {
_resolveNamedExpressions(node.element, arguments);
}
return node;
}
ArgumentList _readArgumentList() {
var arguments = _readNodeList<ExpressionImpl>();
return ArgumentListImpl(
leftParenthesis: Tokens.openParenthesis(),
arguments: arguments,
rightParenthesis: Tokens.closeParenthesis(),
);
}
AsExpression _readAsExpression() {
var expression = _readNode() as ExpressionImpl;
var type = _readNode() as TypeAnnotationImpl;
var node = AsExpressionImpl(
expression: expression,
asOperator: Tokens.as_(),
type: type,
);
_readExpressionResolution(node);
return node;
}
AssertInitializer _readAssertInitializer() {
var condition = _readNode() as ExpressionImpl;
var message = _readOptionalNode() as ExpressionImpl?;
return AssertInitializerImpl(
assertKeyword: Tokens.assert_(),
leftParenthesis: Tokens.openParenthesis(),
condition: condition,
comma: message != null ? Tokens.comma() : null,
message: message,
rightParenthesis: Tokens.closeParenthesis(),
);
}
AssignmentExpression _readAssignmentExpression() {
var leftHandSide = _readNode() as ExpressionImpl;
var rightHandSide = _readNode() as ExpressionImpl;
var operatorType = UnlinkedTokenType.values[_readByte()];
var node = AssignmentExpressionImpl(
leftHandSide: leftHandSide,
operator: Tokens.fromType(operatorType),
rightHandSide: rightHandSide,
);
node.element = _reader.readElement() as InternalMethodElement?;
node.readElement = _reader.readElement();
node.readType = _reader.readType();
node.writeElement = _reader.readElement();
node.writeType = _reader.readType();
_readExpressionResolution(node);
return node;
}
AwaitExpression _readAwaitExpression() {
var expression = _readNode() as ExpressionImpl;
return AwaitExpressionImpl(
awaitKeyword: Tokens.await_(),
expression: expression,
);
}
BinaryExpression _readBinaryExpression() {
var leftOperand = _readNode() as ExpressionImpl;
var rightOperand = _readNode() as ExpressionImpl;
var operatorType = UnlinkedTokenType.values[_readByte()];
var node = BinaryExpressionImpl(
leftOperand: leftOperand,
operator: Tokens.fromType(operatorType),
rightOperand: rightOperand,
);
node.element = _reader.readElement() as MethodElement?;
node.staticInvokeType = _reader.readOptionalFunctionType();
_readExpressionResolution(node);
return node;
}
BooleanLiteral _readBooleanLiteral() {
var value = _readByte() == 1;
var node = BooleanLiteralImpl(
literal: value ? Tokens.true_() : Tokens.false_(),
value: value,
);
_readExpressionResolution(node);
return node;
}
int _readByte() {
return _reader.readByte();
}
CascadeExpression _readCascadeExpression() {
var target = _readNode() as ExpressionImpl;
var sections = _readNodeList<ExpressionImpl>();
var node = CascadeExpressionImpl(target: target, cascadeSections: sections);
node.setPseudoExpressionStaticType(target.staticType);
return node;
}
ConditionalExpression _readConditionalExpression() {
var condition = _readNode() as ExpressionImpl;
var thenExpression = _readNode() as ExpressionImpl;
var elseExpression = _readNode() as ExpressionImpl;
var node = ConditionalExpressionImpl(
condition: condition,
question: Tokens.question(),
thenExpression: thenExpression,
colon: Tokens.colon(),
elseExpression: elseExpression,
);
_readExpressionResolution(node);
return node;
}
ConstructorFieldInitializer _readConstructorFieldInitializer() {
var flags = _readByte();
var fieldName = _readNode() as SimpleIdentifierImpl;
var expression = _readNode() as ExpressionImpl;
var hasThis = AstBinaryFlags.hasThis(flags);
return ConstructorFieldInitializerImpl(
thisKeyword: hasThis ? Tokens.this_() : null,
period: hasThis ? Tokens.period() : null,
fieldName: fieldName,
equals: Tokens.eq(),
expression: expression,
);
}
ConstructorName _readConstructorName() {
var type = _readNode() as NamedTypeImpl;
var name = _readOptionalNode() as SimpleIdentifierImpl?;
var node = ConstructorNameImpl(
type: type,
period: name != null ? Tokens.period() : null,
name: name,
);
node.element = _reader.readElement() as InternalConstructorElement?;
return node;
}
ConstructorReference _readConstructorReference() {
var constructorName = _readNode() as ConstructorNameImpl;
var node = ConstructorReferenceImpl(constructorName: constructorName);
_readExpressionResolution(node);
return node;
}
Token _readDeclarationName() {
var name = _reader.readStringReference();
return StringToken(TokenType.STRING, name, -1);
}
DeclaredIdentifier _readDeclaredIdentifier() {
var flags = _readByte();
var type = _readOptionalNode() as TypeAnnotationImpl?;
var name = _readDeclarationName();
var metadata = _readNodeList<AnnotationImpl>();
return DeclaredIdentifierImpl(
comment: null,
metadata: metadata,
keyword: Tokens.choose(
AstBinaryFlags.isConst(flags),
Tokens.const_(),
AstBinaryFlags.isFinal(flags),
Tokens.final_(),
AstBinaryFlags.isVar(flags),
Tokens.var_(),
),
type: type,
name: name,
);
}
DefaultFormalParameter _readDefaultFormalParameter() {
var flags = _readByte();
var parameter = _readNode() as NormalFormalParameterImpl;
var defaultValue = _readOptionalNode() as ExpressionImpl?;
ParameterKind kind;
if (AstBinaryFlags.isPositional(flags)) {
kind = AstBinaryFlags.isRequired(flags)
? ParameterKind.REQUIRED
: ParameterKind.POSITIONAL;
} else {
kind = AstBinaryFlags.isRequired(flags)
? ParameterKind.NAMED_REQUIRED
: ParameterKind.NAMED;
}
var node = DefaultFormalParameterImpl(
parameter: parameter,
kind: kind,
separator: AstBinaryFlags.hasInitializer(flags) ? Tokens.colon() : null,
defaultValue: defaultValue,
);
var nonDefaultFragment = parameter.declaredFragment!;
var fragment = FormalParameterFragmentImpl(
name: nonDefaultFragment.name,
nameOffset: nonDefaultFragment.nameOffset,
parameterKind: kind,
);
if (parameter is SimpleFormalParameterImpl) {
parameter.declaredFragment = fragment;
}
node.declaredFragment = fragment;
fragment.element.type = nonDefaultFragment.element.type;
return node;
}
DotShorthandConstructorInvocation _readDotShorthandConstructorInvocation() {
var flags = _readByte();
var constructorName = _readNode() as SimpleIdentifierImpl;
var argumentList = _readNode() as ArgumentListImpl;
var node = DotShorthandConstructorInvocationImpl(
constKeyword: AstBinaryFlags.isConst(flags) ? Tokens.const_() : null,
period: Tokens.period(),
constructorName: constructorName,
typeArguments: null,
argumentList: argumentList,
)..isDotShorthand = AstBinaryFlags.isDotShorthand(flags);
_readExpressionResolution(node);
_resolveNamedExpressions(node.constructorName.element, node.argumentList);
return node;
}
DotShorthandInvocation _readDotShorthandInvocation() {
var flags = _readByte();
var memberName = _readNode() as SimpleIdentifierImpl;
var typeArguments = _readOptionalNode() as TypeArgumentListImpl?;
var arguments = _readNode() as ArgumentListImpl;
var node = DotShorthandInvocationImpl(
period: Tokens.period(),
memberName: memberName,
typeArguments: typeArguments,
argumentList: arguments,
)..isDotShorthand = AstBinaryFlags.isDotShorthand(flags);
_readInvocationExpression(node);
return node;
}
DotShorthandPropertyAccess _readDotShorthandPropertyAccess() {
var flags = _readByte();
var propertyName = _readNode() as SimpleIdentifierImpl;
var node = DotShorthandPropertyAccessImpl(
period: Tokens.period(),
propertyName: propertyName,
)..isDotShorthand = AstBinaryFlags.isDotShorthand(flags);
_readExpressionResolution(node);
return node;
}
DottedName _readDottedName() {
var count = _readUint32();
var tokens = <Token>[];
for (var i = 0; i < count; i++) {
var lexeme = _readStringReference();
var type = lexeme == '.' ? TokenType.PERIOD : TokenType.IDENTIFIER;
tokens.add(TokenFactory.tokenFromTypeAndString(type, lexeme));
}
return DottedNameImpl(tokens: tokens);
}
DoubleLiteral _readDoubleLiteral() {
var value = _reader.readDouble();
var node = DoubleLiteralImpl(
literal: StringToken(
TokenType.STRING,
considerCanonicalizeString('$value'),
-1,
),
value: value,
);
_readExpressionResolution(node);
return node;
}
void _readExpressionResolution(ExpressionImpl node) {
node.setPseudoExpressionStaticType(_reader.readType());
}
ExtensionOverride _readExtensionOverride() {
var importPrefix = _readOptionalNode() as ImportPrefixReferenceImpl?;
var extensionName = _readStringReference();
var element = _reader.readElement() as ExtensionElementImpl;
var typeArguments = _readOptionalNode() as TypeArgumentListImpl?;
var argumentList = _readNode() as ArgumentListImpl;
var node = ExtensionOverrideImpl(
importPrefix: importPrefix,
name: StringToken(TokenType.STRING, extensionName, -1),
element: element,
argumentList: argumentList,
typeArguments: typeArguments,
);
_readExpressionResolution(node);
return node;
}
FieldFormalParameter _readFieldFormalParameter() {
var typeParameters = _readOptionalNode() as TypeParameterListImpl?;
var type = _readOptionalNode() as TypeAnnotationImpl?;
var formalParameters = _readOptionalNode() as FormalParameterListImpl?;
var flags = _readByte();
var metadata = _readNodeList<AnnotationImpl>();
var name = _readDeclarationName();
var node = FieldFormalParameterImpl(
name: name,
period: Tokens.period(),
thisKeyword: Tokens.this_(),
covariantKeyword: AstBinaryFlags.isCovariant(flags)
? Tokens.covariant_()
: null,
typeParameters: typeParameters,
keyword: Tokens.choose(
AstBinaryFlags.isConst(flags),
Tokens.const_(),
AstBinaryFlags.isFinal(flags),
Tokens.final_(),
AstBinaryFlags.isVar(flags),
Tokens.var_(),
),
metadata: metadata,
comment: null,
type: type,
parameters: formalParameters,
question: AstBinaryFlags.hasQuestion(flags) ? Tokens.question() : null,
requiredKeyword: AstBinaryFlags.isRequired(flags)
? Tokens.required_()
: null,
);
return node;
}
ForEachPartsWithDeclaration _readForEachPartsWithDeclaration() {
var loopVariable = _readNode() as DeclaredIdentifierImpl;
var iterable = _readNode() as ExpressionImpl;
return ForEachPartsWithDeclarationImpl(
inKeyword: Tokens.in_(),
iterable: iterable,
loopVariable: loopVariable,
);
}
ForElement _readForElement() {
var flags = _readByte();
var forLoopParts = _readNode() as ForLoopPartsImpl;
var body = _readNode() as CollectionElementImpl;
return ForElementImpl(
awaitKeyword: AstBinaryFlags.hasAwait(flags) ? Tokens.await_() : null,
body: body,
forKeyword: Tokens.for_(),
forLoopParts: forLoopParts,
leftParenthesis: Tokens.openParenthesis(),
rightParenthesis: Tokens.closeParenthesis(),
);
}
FormalParameterList _readFormalParameterList() {
var flags = _readByte();
var parameters = _readNodeList<FormalParameterImpl>();
return FormalParameterListImpl(
leftParenthesis: Tokens.openParenthesis(),
parameters: parameters,
leftDelimiter: Tokens.choose(
AstBinaryFlags.isDelimiterCurly(flags),
Tokens.openCurlyBracket(),
AstBinaryFlags.isDelimiterSquare(flags),
Tokens.openSquareBracket(),
),
rightDelimiter: Tokens.choose(
AstBinaryFlags.isDelimiterCurly(flags),
Tokens.closeCurlyBracket(),
AstBinaryFlags.isDelimiterSquare(flags),
Tokens.closeSquareBracket(),
),
rightParenthesis: Tokens.closeParenthesis(),
);
}
ForPartsWithDeclarations _readForPartsWithDeclarations() {
var variables = _readNode() as VariableDeclarationListImpl;
var condition = _readOptionalNode() as ExpressionImpl?;
var updaters = _readNodeList<ExpressionImpl>();
return ForPartsWithDeclarationsImpl(
variables: variables,
condition: condition,
leftSeparator: Tokens.semicolon(),
rightSeparator: Tokens.semicolon(),
updaters: updaters,
);
}
ForPartsWithExpression _readForPartsWithExpression() {
var initialization = _readOptionalNode() as ExpressionImpl?;
var condition = _readOptionalNode() as ExpressionImpl?;
var updaters = _readNodeList<ExpressionImpl>();
return ForPartsWithExpressionImpl(
condition: condition,
initialization: initialization,
leftSeparator: Tokens.semicolon(),
rightSeparator: Tokens.semicolon(),
updaters: updaters,
);
}
FunctionExpressionInvocation _readFunctionExpressionInvocation() {
var function = _readNode() as ExpressionImpl;
var typeArguments = _readOptionalNode() as TypeArgumentListImpl?;
var arguments = _readNode() as ArgumentListImpl;
var node = FunctionExpressionInvocationImpl(
function: function,
typeArguments: typeArguments,
argumentList: arguments,
);
_readInvocationExpression(node);
return node;
}
FunctionReference _readFunctionReference() {
var function = _readNode() as ExpressionImpl;
var typeArguments = _readOptionalNode() as TypeArgumentListImpl?;
var node = FunctionReferenceImpl(
function: function,
typeArguments: typeArguments,
);
node.typeArgumentTypes = _reader.readOptionalTypeList();
_readExpressionResolution(node);
return node;
}
FunctionTypedFormalParameter _readFunctionTypedFormalParameter() {
var typeParameters = _readOptionalNode() as TypeParameterListImpl?;
var returnType = _readOptionalNode() as TypeAnnotationImpl?;
var formalParameters = _readNode() as FormalParameterListImpl;
var flags = _readByte();
var metadata = _readNodeList<AnnotationImpl>();
var name = _readDeclarationName();
var node = FunctionTypedFormalParameterImpl(
comment: null,
covariantKeyword: AstBinaryFlags.isCovariant(flags)
? Tokens.covariant_()
: null,
name: name,
metadata: metadata,
parameters: formalParameters,
requiredKeyword: AstBinaryFlags.isRequired(flags)
? Tokens.required_()
: null,
keyword: () {
if (AstBinaryFlags.isFinal(flags)) {
return Tokens.final_();
}
if (AstBinaryFlags.isVar(flags)) {
return Tokens.var_();
}
return null;
}(),
returnType: returnType,
typeParameters: typeParameters,
question: null,
);
return node;
}
GenericFunctionType _readGenericFunctionType() {
var flags = _readByte();
// TODO(scheglov): add type parameters to locals
var typeParameters = _readOptionalNode() as TypeParameterListImpl?;
var returnType = _readOptionalNode() as TypeAnnotationImpl?;
var formalParameters = _readNode() as FormalParameterListImpl;
var node = GenericFunctionTypeImpl(
returnType: returnType,
functionKeyword: Tokens.function(),
typeParameters: typeParameters,
parameters: formalParameters,
question: AstBinaryFlags.hasQuestion(flags) ? Tokens.question() : null,
);
var type = _reader.readRequiredType() as FunctionTypeImpl;
node.type = type;
var fragment = GenericFunctionTypeFragmentImpl();
fragment.formalParameters = formalParameters.parameters
.map((parameter) => parameter.declaredFragment!)
.toList();
node.declaredFragment = fragment;
_reader.currentLibraryFragment.encloseElement(fragment);
var element = fragment.element;
element.returnType = type.returnType;
element.type = type;
return node;
}
IfElement _readIfElement() {
var expression = _readNode() as ExpressionImpl;
var thenElement = _readNode() as CollectionElementImpl;
var elseElement = _readOptionalNode() as CollectionElementImpl?;
return IfElementImpl(
expression: expression,
caseClause: null,
elseElement: elseElement,
elseKeyword: elseElement != null ? Tokens.else_() : null,
ifKeyword: Tokens.if_(),
leftParenthesis: Tokens.openParenthesis(),
rightParenthesis: Tokens.closeParenthesis(),
thenElement: thenElement,
);
}
ImplicitCallReference _readImplicitCallReference() {
var expression = _readNode() as ExpressionImpl;
var typeArguments = _readOptionalNode() as TypeArgumentListImpl?;
var typeArgumentTypes = _reader.readOptionalTypeList()!;
var staticElement = _reader.readElement() as MethodElementImpl;
var node = ImplicitCallReferenceImpl(
expression: expression,
element: staticElement,
typeArguments: typeArguments,
typeArgumentTypes: typeArgumentTypes,
);
_readExpressionResolution(node);
return node;
}
ImportPrefixReferenceImpl _readImportPrefixReference() {
var name = _readStringReference();
var node = ImportPrefixReferenceImpl(
name: StringToken(TokenType.STRING, name, -1),
period: Tokens.period(),
);
node.element = _reader.readElement();
return node;
}
IndexExpression _readIndexExpression() {
var flags = _readByte();
var target = _readOptionalNode() as ExpressionImpl?;
var index = _readNode() as ExpressionImpl;
var node = IndexExpressionImpl(
target: target,
period: AstBinaryFlags.hasPeriod(flags) ? Tokens.periodPeriod() : null,
question: AstBinaryFlags.hasQuestion(flags) ? Tokens.question() : null,
leftBracket: Tokens.openSquareBracket(),
index: index,
rightBracket: Tokens.closeSquareBracket(),
);
node.element = _reader.readElement() as MethodElement?;
_readExpressionResolution(node);
return node;
}
InstanceCreationExpression _readInstanceCreationExpression() {
var flags = _readByte();
var constructorName = _readNode() as ConstructorNameImpl;
var argumentList = _readNode() as ArgumentListImpl;
var node = InstanceCreationExpressionImpl(
keyword: Tokens.choose(
AstBinaryFlags.isConst(flags),
Tokens.const_(),
AstBinaryFlags.isNew(flags),
Tokens.new_(),
),
constructorName: constructorName,
argumentList: argumentList,
typeArguments: null,
);
_readExpressionResolution(node);
_resolveNamedExpressions(node.constructorName.element, node.argumentList);
return node;
}
IntegerLiteral _readIntegerLiteralNegative() {
var lexeme = _readStringReference();
var value = (_readUint32() << 32) | _readUint32();
return _createIntegerLiteral(lexeme, -value);
}
IntegerLiteral _readIntegerLiteralNegative1() {
var lexeme = _readStringReference();
var value = _readByte();
return _createIntegerLiteral(lexeme, -value);
}
IntegerLiteral _readIntegerLiteralNull() {
var lexeme = _readStringReference();
var node = IntegerLiteralImpl(
// TODO(srawlins): TokenType.INT_WITH_SEPARATORS?
literal: TokenFactory.tokenFromTypeAndString(TokenType.INT, lexeme),
value: null,
);
_readExpressionResolution(node);
return node;
}
IntegerLiteral _readIntegerLiteralPositive() {
var lexeme = _readStringReference();
var value = (_readUint32() << 32) | _readUint32();
return _createIntegerLiteral(lexeme, value);
}
IntegerLiteral _readIntegerLiteralPositive1() {
var lexeme = _readStringReference();
var value = _readByte();
return _createIntegerLiteral(lexeme, value);
}
InterpolationExpression _readInterpolationExpression() {
var flags = _readByte();
var expression = _readNode() as ExpressionImpl;
var isIdentifier = AstBinaryFlags.isStringInterpolationIdentifier(flags);
return InterpolationExpressionImpl(
leftBracket: isIdentifier
? Tokens.stringInterpolationIdentifier()
: Tokens.stringInterpolationExpression(),
expression: expression,
rightBracket: isIdentifier ? null : Tokens.closeCurlyBracket(),
);
}
InterpolationString _readInterpolationString() {
var lexeme = _readStringReference();
var value = _readStringReference();
return InterpolationStringImpl(
contents: TokenFactory.tokenFromString(lexeme),
value: value,
);
}
void _readInvocationExpression(InvocationExpressionImpl node) {
node.staticInvokeType = _reader.readType();
node.typeArgumentTypes = _reader.readOptionalTypeList();
_readExpressionResolution(node);
}
IsExpression _readIsExpression() {
var flags = _readByte();
var expression = _readNode() as ExpressionImpl;
var type = _readNode() as TypeAnnotationImpl;
var node = IsExpressionImpl(
expression: expression,
isOperator: Tokens.is_(),
notOperator: AstBinaryFlags.hasNot(flags) ? Tokens.bang() : null,
type: type,
);
_readExpressionResolution(node);
return node;
}
ListLiteral _readListLiteral() {
var flags = _readByte();
var typeArguments = _readOptionalNode() as TypeArgumentListImpl?;
var elements = _readNodeList<CollectionElementImpl>();
var node = ListLiteralImpl(
constKeyword: AstBinaryFlags.isConst(flags) ? Tokens.const_() : null,
typeArguments: typeArguments,
leftBracket: Tokens.openSquareBracket(),
elements: elements,
rightBracket: Tokens.closeSquareBracket(),
);
_readExpressionResolution(node);
return node;
}
MapLiteralEntry _readMapLiteralEntry() {
var keyFlags = _readByte();
var key = _readNode() as ExpressionImpl;
var valueFlags = _readByte();
var value = _readNode() as ExpressionImpl;
return MapLiteralEntryImpl(
keyQuestion: AstBinaryFlags.hasQuestion(keyFlags)
? Tokens.question()
: null,
key: key,
separator: Tokens.colon(),
valueQuestion: AstBinaryFlags.hasQuestion(valueFlags)
? Tokens.question()
: null,
value: value,
);
}
MethodInvocation _readMethodInvocation() {
var flags = _readByte();
var target = _readOptionalNode() as ExpressionImpl?;
var methodName = _readNode() as SimpleIdentifierImpl;
var typeArguments = _readOptionalNode() as TypeArgumentListImpl?;
var arguments = _readNode() as ArgumentListImpl;
Token? operator;
if (AstBinaryFlags.hasQuestion(flags)) {
operator = AstBinaryFlags.hasPeriod(flags)
? Tokens.questionPeriod()
: Tokens.questionPeriodPeriod();
} else if (AstBinaryFlags.hasPeriod(flags)) {
operator = Tokens.period();
} else if (AstBinaryFlags.hasPeriod2(flags)) {
operator = Tokens.periodPeriod();
}
var node = MethodInvocationImpl(
target: target,
operator: operator,
methodName: methodName,
typeArguments: typeArguments,
argumentList: arguments,
);
_readInvocationExpression(node);
return node;
}
NamedExpression _readNamedExpression() {
var name = _readStringReference();
var nameNode = LabelImpl(
label: SimpleIdentifierImpl(
token: StringToken(TokenType.STRING, name, -1),
),
colon: Tokens.colon(),
);
var expression = _readNode() as ExpressionImpl;
var node = NamedExpressionImpl(name: nameNode, expression: expression);
node.setPseudoExpressionStaticType(expression.staticType);
return node;
}
NamedType _readNamedType() {
var flags = _readByte();
var importPrefix = _readOptionalNode() as ImportPrefixReferenceImpl?;
var name = _readStringReference();
var typeArguments = _readOptionalNode() as TypeArgumentListImpl?;
var node = NamedTypeImpl(
importPrefix: importPrefix,
name: StringToken(TokenType.STRING, name, -1),
typeArguments: typeArguments,
question: AstBinaryFlags.hasQuestion(flags) ? Tokens.question() : null,
);
node.element = _reader.readElement();
node.type = _reader.readType();
return node;
}
AstNode _readNode() {
var tag = _readByte();
switch (tag) {
case Tag.AdjacentStrings:
return _readAdjacentStrings();
case Tag.Annotation:
return _readAnnotation();
case Tag.ArgumentList:
return _readArgumentList();
case Tag.AsExpression:
return _readAsExpression();
case Tag.AssertInitializer:
return _readAssertInitializer();
case Tag.AssignmentExpression:
return _readAssignmentExpression();
case Tag.AwaitExpression:
return _readAwaitExpression();
case Tag.BinaryExpression:
return _readBinaryExpression();
case Tag.BooleanLiteral:
return _readBooleanLiteral();
case Tag.CascadeExpression:
return _readCascadeExpression();
case Tag.ConditionalExpression:
return _readConditionalExpression();
case Tag.ConstructorFieldInitializer:
return _readConstructorFieldInitializer();
case Tag.ConstructorName:
return _readConstructorName();
case Tag.ConstructorReference:
return _readConstructorReference();
case Tag.DeclaredIdentifier:
return _readDeclaredIdentifier();
case Tag.DefaultFormalParameter:
return _readDefaultFormalParameter();
case Tag.DotShorthandConstructorInvocation:
return _readDotShorthandConstructorInvocation();
case Tag.DotShorthandInvocation:
return _readDotShorthandInvocation();
case Tag.DotShorthandPropertyAccess:
return _readDotShorthandPropertyAccess();
case Tag.DottedName:
return _readDottedName();
case Tag.DoubleLiteral:
return _readDoubleLiteral();
case Tag.ExtensionOverride:
return _readExtensionOverride();
case Tag.ForEachPartsWithDeclaration:
return _readForEachPartsWithDeclaration();
case Tag.ForElement:
return _readForElement();
case Tag.ForPartsWithDeclarations:
return _readForPartsWithDeclarations();
case Tag.ForPartsWithExpression:
return _readForPartsWithExpression();
case Tag.FieldFormalParameter:
return _readFieldFormalParameter();
case Tag.FormalParameterList:
return _readFormalParameterList();
case Tag.FunctionExpressionInvocation:
return _readFunctionExpressionInvocation();
case Tag.FunctionReference:
return _readFunctionReference();
case Tag.FunctionTypedFormalParameter:
return _readFunctionTypedFormalParameter();
case Tag.GenericFunctionType:
return _readGenericFunctionType();
case Tag.IfElement:
return _readIfElement();
case Tag.ImplicitCallReference:
return _readImplicitCallReference();
case Tag.ImportPrefixReference:
return _readImportPrefixReference();
case Tag.IndexExpression:
return _readIndexExpression();
case Tag.IntegerLiteralNegative1:
return _readIntegerLiteralNegative1();
case Tag.IntegerLiteralNull:
return _readIntegerLiteralNull();
case Tag.IntegerLiteralPositive1:
return _readIntegerLiteralPositive1();
case Tag.IntegerLiteralPositive:
return _readIntegerLiteralPositive();
case Tag.IntegerLiteralNegative:
return _readIntegerLiteralNegative();
case Tag.InterpolationExpression:
return _readInterpolationExpression();
case Tag.InterpolationString:
return _readInterpolationString();
case Tag.IsExpression:
return _readIsExpression();
case Tag.ListLiteral:
return _readListLiteral();
case Tag.MapLiteralEntry:
return _readMapLiteralEntry();
case Tag.MethodInvocation:
return _readMethodInvocation();
case Tag.NamedExpression:
return _readNamedExpression();
case Tag.NullAwareElement:
return _readNullAwareElement();
case Tag.NullLiteral:
return _readNullLiteral();
case Tag.InstanceCreationExpression:
return _readInstanceCreationExpression();
case Tag.ParenthesizedExpression:
return _readParenthesizedExpression();
case Tag.PostfixExpression:
return _readPostfixExpression();
case Tag.PrefixExpression:
return _readPrefixExpression();
case Tag.PrefixedIdentifier:
return _readPrefixedIdentifier();
case Tag.PropertyAccess:
return _readPropertyAccess();
case Tag.RecordLiteral:
return _readRecordLiteral();
case Tag.RecordTypeAnnotation:
return _readRecordTypeAnnotation();
case Tag.RecordTypeAnnotationNamedField:
return _readRecordTypeAnnotationNamedField();
case Tag.RecordTypeAnnotationNamedFields:
return _readRecordTypeAnnotationNamedFields();
case Tag.RecordTypeAnnotationPositionalField:
return _readRecordTypeAnnotationPositionalField();
case Tag.RedirectingConstructorInvocation:
return _readRedirectingConstructorInvocation();
case Tag.SetOrMapLiteral:
return _readSetOrMapLiteral();
case Tag.SimpleFormalParameter:
return _readSimpleFormalParameter();
case Tag.SimpleIdentifier:
return _readSimpleIdentifier();
case Tag.SimpleStringLiteral:
return _readSimpleStringLiteral();
case Tag.SpreadElement:
return _readSpreadElement();
case Tag.StringInterpolation:
return _readStringInterpolation();
case Tag.SuperConstructorInvocation:
return _readSuperConstructorInvocation();
case Tag.SuperExpression:
return _readSuperExpression();
case Tag.SymbolLiteral:
return _readSymbolLiteral();
case Tag.ThisExpression:
return _readThisExpression();
case Tag.ThrowExpression:
return _readThrowExpression();
case Tag.TypeArgumentList:
return _readTypeArgumentList();
case Tag.TypeLiteral:
return _readTypeLiteral();
case Tag.NamedType:
return _readNamedType();
case Tag.TypeParameter:
return _readTypeParameter();
case Tag.TypeParameterList:
return _readTypeParameterList();
case Tag.VariableDeclaration:
return _readVariableDeclaration();
case Tag.VariableDeclarationList:
return _readVariableDeclarationList();
default:
throw UnimplementedError('Unexpected tag: $tag');
}
}
List<T> _readNodeList<T>() {
var length = _reader.readUint30();
return List.generate(length, (_) => _readNode() as T);
}
NullAwareElement _readNullAwareElement() {
var value = _readNode() as ExpressionImpl;
return NullAwareElementImpl(question: Tokens.question(), value: value);
}
NullLiteral _readNullLiteral() {
var node = NullLiteralImpl(literal: Tokens.null_());
_readExpressionResolution(node);
return node;
}
AstNode? _readOptionalNode() {
if (_readOptionTag()) {
return _readNode();
} else {
return null;
}
}
bool _readOptionTag() {
var tag = _readByte();
if (tag == Tag.Nothing) {
return false;
} else if (tag == Tag.Something) {
return true;
} else {
throw UnimplementedError('Unexpected option tag: $tag');
}
}
ParenthesizedExpression _readParenthesizedExpression() {
var expression = _readNode() as ExpressionImpl;
var node = ParenthesizedExpressionImpl(
leftParenthesis: Tokens.openParenthesis(),
expression: expression,
rightParenthesis: Tokens.closeParenthesis(),
);
_readExpressionResolution(node);
return node;
}
PostfixExpression _readPostfixExpression() {
var operand = _readNode() as ExpressionImpl;
var operatorType = UnlinkedTokenType.values[_readByte()];
var node = PostfixExpressionImpl(
operand: operand,
operator: Tokens.fromType(operatorType),
);
node.element = _reader.readElement() as MethodElement?;
if (node.operator.type.isIncrementOperator) {
node.readElement = _reader.readElement();
node.readType = _reader.readType();
node.writeElement = _reader.readElement();
node.writeType = _reader.readType();
}
_readExpressionResolution(node);
return node;
}
PrefixedIdentifierImpl _readPrefixedIdentifier() {
var prefix = _readNode() as SimpleIdentifierImpl;
var identifier = _readNode() as SimpleIdentifierImpl;
var node = PrefixedIdentifierImpl(
prefix: prefix,
period: Tokens.period(),
identifier: identifier,
);
_readExpressionResolution(node);
return node;
}
PrefixExpression _readPrefixExpression() {
var operatorType = UnlinkedTokenType.values[_readByte()];
var operand = _readNode() as ExpressionImpl;
var node = PrefixExpressionImpl(
operator: Tokens.fromType(operatorType),
operand: operand,
);
node.element = _reader.readElement() as MethodElement?;
if (node.operator.type.isIncrementOperator) {
node.readElement = _reader.readElement();
node.readType = _reader.readType();
node.writeElement = _reader.readElement();
node.writeType = _reader.readType();
}
_readExpressionResolution(node);
return node;
}
PropertyAccess _readPropertyAccess() {
var flags = _readByte();
var target = _readOptionalNode() as ExpressionImpl?;
var propertyName = _readNode() as SimpleIdentifierImpl;
Token operator;
if (AstBinaryFlags.hasQuestion(flags)) {
operator = AstBinaryFlags.hasPeriod(flags)
? Tokens.questionPeriod()
: Tokens.questionPeriodPeriod();
} else {
operator = AstBinaryFlags.hasPeriod(flags)
? Tokens.period()
: Tokens.periodPeriod();
}
var node = PropertyAccessImpl(
target: target,
operator: operator,
propertyName: propertyName,
);
_readExpressionResolution(node);
return node;
}
RecordLiteralImpl _readRecordLiteral() {
var flags = _readByte();
var fields = _readNodeList<ExpressionImpl>();
var node = RecordLiteralImpl(
constKeyword: AstBinaryFlags.isConst(flags) ? Tokens.const_() : null,
leftParenthesis: Tokens.openParenthesis(),
fields: fields,
rightParenthesis: Tokens.closeParenthesis(),
);
_readExpressionResolution(node);
return node;
}
RecordTypeAnnotationImpl _readRecordTypeAnnotation() {
var flags = _readByte();
var positionalFields =
_readNodeList<RecordTypeAnnotationPositionalFieldImpl>();
var namedFields =
_readOptionalNode() as RecordTypeAnnotationNamedFieldsImpl?;
var node = RecordTypeAnnotationImpl(
leftParenthesis: Tokens.openParenthesis(),
positionalFields: positionalFields,
namedFields: namedFields,
rightParenthesis: Tokens.closeParenthesis(),
question: AstBinaryFlags.hasQuestion(flags) ? Tokens.question() : null,
);
node.type = _reader.readType();
return node;
}
RecordTypeAnnotationNamedFieldImpl _readRecordTypeAnnotationNamedField() {
var metadata = _readNodeList<AnnotationImpl>();
var type = _readNode() as TypeAnnotationImpl;
var lexeme = _reader.readStringReference();
var name = TokenFactory.tokenFromString(lexeme);
return RecordTypeAnnotationNamedFieldImpl(
metadata: metadata,
type: type,
name: name,
);
}
RecordTypeAnnotationNamedFieldsImpl _readRecordTypeAnnotationNamedFields() {
var fields = _readNodeList<RecordTypeAnnotationNamedFieldImpl>();
return RecordTypeAnnotationNamedFieldsImpl(
leftBracket: Tokens.openCurlyBracket(),
fields: fields,
rightBracket: Tokens.closeCurlyBracket(),
);
}
RecordTypeAnnotationPositionalFieldImpl
_readRecordTypeAnnotationPositionalField() {
var metadata = _readNodeList<AnnotationImpl>();
var type = _readNode() as TypeAnnotationImpl;
var name = _reader.readOptionalObject(() {
var lexeme = _reader.readStringReference();
return TokenFactory.tokenFromString(lexeme);
});
return RecordTypeAnnotationPositionalFieldImpl(
metadata: metadata,
type: type,
name: name,
);
}
RedirectingConstructorInvocation _readRedirectingConstructorInvocation() {
var constructorName = _readOptionalNode() as SimpleIdentifierImpl?;
var argumentList = _readNode() as ArgumentListImpl;
var node = RedirectingConstructorInvocationImpl(
thisKeyword: Tokens.this_(),
period: constructorName != null ? Tokens.period() : null,
constructorName: constructorName,
argumentList: argumentList,
);
node.element = _reader.readElement() as ConstructorElementImpl?;
_resolveNamedExpressions(node.element, node.argumentList);
return node;
}
SetOrMapLiteral _readSetOrMapLiteral() {
var flags = _readByte();
var isMapOrSetBits = _readByte();
var typeArguments = _readOptionalNode() as TypeArgumentListImpl?;
var elements = _readNodeList<CollectionElementImpl>();
var node = SetOrMapLiteralImpl(
constKeyword: AstBinaryFlags.isConst(flags) ? Tokens.const_() : null,
elements: elements,
leftBracket: Tokens.openCurlyBracket(),
typeArguments: typeArguments,
rightBracket: Tokens.closeCurlyBracket(),
);
const isMapBit = 1 << 0;
const isSetBit = 1 << 1;
if ((isMapOrSetBits & isMapBit) != 0) {
node.becomeMap();
} else if ((isMapOrSetBits & isSetBit) != 0) {
node.becomeSet();
}
_readExpressionResolution(node);
return node;
}
SimpleFormalParameter _readSimpleFormalParameter() {
var type = _readOptionalNode() as TypeAnnotationImpl?;
var flags = _readByte();
var metadata = _readNodeList<AnnotationImpl>();
var name = AstBinaryFlags.hasName(flags) ? _readDeclarationName() : null;
var node = SimpleFormalParameterImpl(
name: name,
type: type,
covariantKeyword: AstBinaryFlags.isCovariant(flags)
? Tokens.covariant_()
: null,
comment: null,
metadata: metadata,
keyword: Tokens.choose(
AstBinaryFlags.isConst(flags),
Tokens.const_(),
AstBinaryFlags.isFinal(flags),
Tokens.final_(),
AstBinaryFlags.isVar(flags),
Tokens.var_(),
),
requiredKeyword: AstBinaryFlags.isRequired(flags)
? Tokens.required_()
: null,
);
var actualType = _reader.readRequiredType();
var fragment = FormalParameterFragmentImpl(
name: name?.lexeme,
nameOffset: null,
parameterKind: node.kind,
);
fragment.element.type = actualType;
node.declaredFragment = fragment;
return node;
}
SimpleIdentifier _readSimpleIdentifier() {
var name = _readStringReference();
var node = SimpleIdentifierImpl(
token: StringToken(TokenType.STRING, name, -1),
);
node.element = _reader.readElement();
node.tearOffTypeArgumentTypes = _reader.readOptionalTypeList();
_readExpressionResolution(node);
return node;
}
SimpleStringLiteral _readSimpleStringLiteral() {
var lexeme = _readStringReference();
var value = _readStringReference();
var node = SimpleStringLiteralImpl(
literal: TokenFactory.tokenFromString(lexeme),
value: value,
);
_readExpressionResolution(node);
return node;
}
SpreadElement _readSpreadElement() {
var flags = _readByte();
var expression = _readNode() as ExpressionImpl;
return SpreadElementImpl(
spreadOperator: AstBinaryFlags.hasQuestion(flags)
? Tokens.periodPeriodPeriodQuestion()
: Tokens.periodPeriodPeriod(),
expression: expression,
);
}
StringInterpolation _readStringInterpolation() {
var elements = _readNodeList<InterpolationElementImpl>();
var node = StringInterpolationImpl(elements: elements);
_readExpressionResolution(node);
return node;
}
String _readStringReference() {
return _reader.readStringReference();
}
SuperConstructorInvocation _readSuperConstructorInvocation() {
var constructorName = _readOptionalNode() as SimpleIdentifierImpl?;
var argumentList = _readNode() as ArgumentListImpl;
var node = SuperConstructorInvocationImpl(
superKeyword: Tokens.super_(),
period: constructorName != null ? Tokens.period() : null,
constructorName: constructorName,
argumentList: argumentList,
);
node.element = _reader.readElement() as InternalConstructorElement?;
_resolveNamedExpressions(node.element, node.argumentList);
return node;
}
SuperExpression _readSuperExpression() {
var node = SuperExpressionImpl(superKeyword: Tokens.super_());
_readExpressionResolution(node);
return node;
}
SymbolLiteral _readSymbolLiteral() {
var components = _reader
.readStringReferenceList()
.map(TokenFactory.tokenFromString)
.toList();
var node = SymbolLiteralImpl(
poundSign: Tokens.hash(),
components: components,
);
_readExpressionResolution(node);
return node;
}
ThisExpression _readThisExpression() {
var node = ThisExpressionImpl(thisKeyword: Tokens.this_());
_readExpressionResolution(node);
return node;
}
ThrowExpression _readThrowExpression() {
var expression = _readNode() as ExpressionImpl;
var node = ThrowExpressionImpl(
throwKeyword: Tokens.throw_(),
expression: expression,
);
_readExpressionResolution(node);
return node;
}
TypeArgumentListImpl _readTypeArgumentList() {
var arguments = _readNodeList<TypeAnnotationImpl>();
return TypeArgumentListImpl(
leftBracket: Tokens.lt(),
arguments: arguments,
rightBracket: Tokens.gt(),
);
}
TypeLiteral _readTypeLiteral() {
var typeName = _readNode() as NamedTypeImpl;
var node = TypeLiteralImpl(type: typeName);
_readExpressionResolution(node);
return node;
}
TypeParameter _readTypeParameter() {
var name = _readDeclarationName();
var bound = _readOptionalNode() as TypeAnnotationImpl?;
var metadata = _readNodeList<AnnotationImpl>();
var node = TypeParameterImpl(
comment: null,
metadata: metadata,
varianceKeyword: null,
name: name,
extendsKeyword: bound != null ? Tokens.extends_() : null,
bound: bound,
);
return node;
}
TypeParameterList _readTypeParameterList() {
var typeParameters = _readNodeList<TypeParameterImpl>();
return TypeParameterListImpl(
leftBracket: Tokens.lt(),
typeParameters: typeParameters,
rightBracket: Tokens.gt(),
);
}
int _readUint32() {
return _reader.readUint32();
}
VariableDeclaration _readVariableDeclaration() {
var flags = _readByte();
var name = _readDeclarationName();
var initializer = _readOptionalNode() as ExpressionImpl?;
var node = VariableDeclarationImpl(
comment: null,
metadata: [],
name: name,
equals: Tokens.eq(),
initializer: initializer,
);
node.hasInitializer = AstBinaryFlags.hasInitializer(flags);
return node;
}
VariableDeclarationList _readVariableDeclarationList() {
var flags = _readByte();
var type = _readOptionalNode() as TypeAnnotationImpl?;
var variables = _readNodeList<VariableDeclarationImpl>();
var metadata = _readNodeList<AnnotationImpl>();
return VariableDeclarationListImpl(
comment: null,
keyword: Tokens.choose(
AstBinaryFlags.isConst(flags),
Tokens.const_(),
AstBinaryFlags.isFinal(flags),
Tokens.final_(),
AstBinaryFlags.isVar(flags),
Tokens.var_(),
),
lateKeyword: AstBinaryFlags.isLate(flags) ? Tokens.late_() : null,
metadata: metadata,
type: type,
variables: variables,
);
}
void _resolveNamedExpressions(
Element? executable,
ArgumentList argumentList,
) {
for (var argument in argumentList.arguments) {
if (argument is NamedExpressionImpl) {
var nameNode = argument.name.label;
if (executable is ExecutableElement) {
var formalParameters = executable.formalParameters;
var name = nameNode.name;
nameNode.element = formalParameters.firstWhereOrNull((e) {
return e.name == name;
});
}
}
}
}
}