blob: e8fd2a76bc227f4cb00bf131a5cf29d95cdf8509 [file] [log] [blame]
// Copyright (c) 2020, 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 'dart:math';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/ast/ast_factory.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/resolver/variance.dart';
import 'package:analyzer/src/exception/exception.dart';
import 'package:analyzer/src/summary2/ast_binary_flags.dart';
import 'package:analyzer/src/summary2/ast_binary_tag.dart';
import 'package:analyzer/src/summary2/bundle_reader.dart';
import 'package:analyzer/src/summary2/linked_unit_context.dart';
import 'package:analyzer/src/task/inference_error.dart';
import 'package:collection/collection.dart';
class ApplyResolutionVisitor extends ThrowingAstVisitor<void> {
final LinkedUnitContext _unitContext;
final LinkedResolutionReader _resolution;
/// The stack of [TypeParameterElement]s and [ParameterElement] that are
/// available in the scope of [_nextElement] and [_nextType].
///
/// This stack is shared with [_resolution].
final List<Element> _localElements;
final List<ElementImpl> _enclosingElements = [];
ApplyResolutionVisitor(
this._unitContext,
this._localElements,
this._resolution,
) {
_enclosingElements.add(_unitContext.element);
}
/// TODO(scheglov) make private
void addParentTypeParameters(AstNode node) {
var enclosing = node.parent;
if (enclosing is ClassOrMixinDeclaration) {
var typeParameterList = enclosing.typeParameters;
if (typeParameterList == null) return;
for (var typeParameter in typeParameterList.typeParameters) {
var element = typeParameter.declaredElement!;
_localElements.add(element);
}
} else if (enclosing is ExtensionDeclaration) {
var typeParameterList = enclosing.typeParameters;
if (typeParameterList == null) return;
for (var typeParameter in typeParameterList.typeParameters) {
var element = typeParameter.declaredElement!;
_localElements.add(element);
}
} else if (enclosing is VariableDeclarationList) {
var enclosing2 = enclosing.parent;
if (enclosing2 is FieldDeclaration) {
return addParentTypeParameters(enclosing2);
} else if (enclosing2 is TopLevelVariableDeclaration) {
return;
} else {
throw UnimplementedError('${enclosing2.runtimeType}');
}
} else {
throw UnimplementedError('${enclosing.runtimeType}');
}
}
@override
void visitAdjacentStrings(AdjacentStrings node) {
node.strings.accept(this);
// TODO(scheglov) type?
}
@override
void visitAnnotation(covariant AnnotationImpl node) {
_expectMarker(MarkerTag.Annotation_name);
node.name.accept(this);
_expectMarker(MarkerTag.Annotation_typeArguments);
node.typeArguments?.accept(this);
_expectMarker(MarkerTag.Annotation_constructorName);
node.constructorName?.accept(this);
_expectMarker(MarkerTag.Annotation_arguments);
node.arguments?.accept(this);
_expectMarker(MarkerTag.Annotation_element);
node.element = _nextElement();
}
@override
void visitArgumentList(ArgumentList node) {
_expectMarker(MarkerTag.ArgumentList_arguments);
node.arguments.accept(this);
_expectMarker(MarkerTag.ArgumentList_end);
}
@override
void visitAsExpression(covariant AsExpressionImpl node) {
_expectMarker(MarkerTag.AsExpression_expression);
node.expression.accept(this);
_expectMarker(MarkerTag.AsExpression_type);
node.type.accept(this);
_expectMarker(MarkerTag.AsExpression_expression2);
_expression(node);
_expectMarker(MarkerTag.AsExpression_end);
}
@override
void visitAssertInitializer(AssertInitializer node) {
_expectMarker(MarkerTag.AssertInitializer_condition);
node.condition.accept(this);
_expectMarker(MarkerTag.AssertInitializer_message);
node.message?.accept(this);
_expectMarker(MarkerTag.AssertInitializer_end);
}
@override
void visitAssignmentExpression(AssignmentExpression node) {
var nodeImpl = node as AssignmentExpressionImpl;
_expectMarker(MarkerTag.AssignmentExpression_leftHandSide);
node.leftHandSide.accept(this);
_expectMarker(MarkerTag.AssignmentExpression_rightHandSide);
node.rightHandSide.accept(this);
_expectMarker(MarkerTag.AssignmentExpression_staticElement);
node.staticElement = _nextElement() as MethodElement?;
_expectMarker(MarkerTag.AssignmentExpression_readElement);
nodeImpl.readElement = _nextElement();
_expectMarker(MarkerTag.AssignmentExpression_readType);
nodeImpl.readType = _nextType();
_expectMarker(MarkerTag.AssignmentExpression_writeElement);
nodeImpl.writeElement = _nextElement();
_expectMarker(MarkerTag.AssignmentExpression_writeType);
nodeImpl.writeType = _nextType();
_expectMarker(MarkerTag.AssignmentExpression_expression);
_expression(node);
_expectMarker(MarkerTag.AssignmentExpression_end);
}
@override
void visitAwaitExpression(covariant AwaitExpressionImpl node) {
_expectMarker(MarkerTag.AwaitExpression_expression);
node.expression.accept(this);
_expectMarker(MarkerTag.AwaitExpression_expression2);
_expression(node);
_expectMarker(MarkerTag.AwaitExpression_end);
}
@override
void visitBinaryExpression(covariant BinaryExpressionImpl node) {
_expectMarker(MarkerTag.BinaryExpression_leftOperand);
node.leftOperand.accept(this);
_expectMarker(MarkerTag.BinaryExpression_rightOperand);
node.rightOperand.accept(this);
_expectMarker(MarkerTag.BinaryExpression_staticElement);
node.staticElement = _nextElement() as MethodElement?;
_expectMarker(MarkerTag.BinaryExpression_expression);
_expression(node);
_expectMarker(MarkerTag.BinaryExpression_end);
}
@override
void visitBooleanLiteral(covariant BooleanLiteralImpl node) {
_expression(node);
}
@override
void visitCascadeExpression(covariant CascadeExpressionImpl node) {
_expectMarker(MarkerTag.CascadeExpression_target);
node.target.accept(this);
_expectMarker(MarkerTag.CascadeExpression_cascadeSections);
node.cascadeSections.accept(this);
_expectMarker(MarkerTag.CascadeExpression_end);
node.staticType = node.target.staticType;
}
@override
visitClassDeclaration(ClassDeclaration node) {
_assertNoLocalElements();
var element = node.declaredElement as ClassElementImpl;
element.isSimplyBounded = _resolution.readByte() != 0;
_enclosingElements.add(element);
try {
_expectMarker(MarkerTag.ClassDeclaration_typeParameters);
node.typeParameters?.accept(this);
_expectMarker(MarkerTag.ClassDeclaration_extendsClause);
node.extendsClause?.accept(this);
_expectMarker(MarkerTag.ClassDeclaration_withClause);
node.withClause?.accept(this);
_expectMarker(MarkerTag.ClassDeclaration_implementsClause);
node.implementsClause?.accept(this);
_expectMarker(MarkerTag.ClassDeclaration_nativeClause);
node.nativeClause?.accept(this);
_expectMarker(MarkerTag.ClassDeclaration_namedCompilationUnitMember);
_namedCompilationUnitMember(node);
_expectMarker(MarkerTag.ClassDeclaration_end);
} catch (e, stackTrace) {
// TODO(scheglov) Remove after fixing http://dartbug.com/44449
var headerStr = _astCodeBeforeMarkerOrMaxLength(node, '{', 1000);
throw CaughtExceptionWithFiles(e, stackTrace, {
'state': '''
element: ${element.reference}
header: $headerStr
resolution.bytes.length: ${_resolution.bytes.length}
resolution.byteOffset: ${_resolution.byteOffset}
''',
});
}
_enclosingElements.removeLast();
}
@override
void visitClassTypeAlias(ClassTypeAlias node) {
_assertNoLocalElements();
var element = node.declaredElement as ClassElementImpl;
_enclosingElements.add(element);
element.isSimplyBounded = _resolution.readByte() != 0;
_expectMarker(MarkerTag.ClassTypeAlias_typeParameters);
node.typeParameters?.accept(this);
_expectMarker(MarkerTag.ClassTypeAlias_superclass);
node.superclass.accept(this);
_expectMarker(MarkerTag.ClassTypeAlias_withClause);
node.withClause.accept(this);
_expectMarker(MarkerTag.ClassTypeAlias_implementsClause);
node.implementsClause?.accept(this);
_expectMarker(MarkerTag.ClassTypeAlias_typeAlias);
_typeAlias(node);
_expectMarker(MarkerTag.ClassTypeAlias_end);
_enclosingElements.removeLast();
}
@override
void visitConditionalExpression(covariant ConditionalExpressionImpl node) {
_expectMarker(MarkerTag.ConditionalExpression_condition);
node.condition.accept(this);
_expectMarker(MarkerTag.ConditionalExpression_thenExpression);
node.thenExpression.accept(this);
_expectMarker(MarkerTag.ConditionalExpression_elseExpression);
node.elseExpression.accept(this);
_expression(node);
}
@override
void visitConfiguration(Configuration node) {
_expectMarker(MarkerTag.Configuration_name);
node.name.accept(this);
_expectMarker(MarkerTag.Configuration_value);
node.value?.accept(this);
_expectMarker(MarkerTag.Configuration_uri);
node.uri.accept(this);
_expectMarker(MarkerTag.Configuration_end);
}
@override
void visitConstructorDeclaration(ConstructorDeclaration node) {
_assertNoLocalElements();
_pushEnclosingClassTypeParameters(node);
var element = node.declaredElement as ConstructorElementImpl;
_enclosingElements.add(element.enclosingElement);
_enclosingElements.add(element);
_expectMarker(MarkerTag.ConstructorDeclaration_returnType);
node.returnType.accept(this);
_expectMarker(MarkerTag.ConstructorDeclaration_parameters);
node.parameters.accept(this);
for (var parameter in node.parameters.parameters) {
_localElements.add(parameter.declaredElement!);
}
_expectMarker(MarkerTag.ConstructorDeclaration_initializers);
node.initializers.accept(this);
_expectMarker(MarkerTag.ConstructorDeclaration_redirectedConstructor);
node.redirectedConstructor?.accept(this);
_expectMarker(MarkerTag.ConstructorDeclaration_classMember);
_classMember(node);
_expectMarker(MarkerTag.ConstructorDeclaration_end);
_enclosingElements.removeLast();
_enclosingElements.removeLast();
}
@override
void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
_expectMarker(MarkerTag.ConstructorFieldInitializer_fieldName);
node.fieldName.accept(this);
_expectMarker(MarkerTag.ConstructorFieldInitializer_expression);
node.expression.accept(this);
_expectMarker(MarkerTag.ConstructorFieldInitializer_end);
}
@override
void visitConstructorName(covariant ConstructorNameImpl node) {
// Rewrite:
// ConstructorName
// type: TypeName
// name: PrefixedIdentifier
// name: null
// into:
// ConstructorName
// type: TypeName
// name: SimpleIdentifier
// name: SimpleIdentifier
var hasName = _resolution.readByte() != 0;
if (hasName && node.name == null) {
var typeName = node.type.name as PrefixedIdentifier;
NodeReplacer.replace(
node.type,
astFactory.typeName(typeName.prefix, null),
);
node.name = typeName.identifier;
}
_expectMarker(MarkerTag.ConstructorName_type);
node.type.accept(this);
_expectMarker(MarkerTag.ConstructorName_name);
node.name?.accept(this);
_expectMarker(MarkerTag.ConstructorName_staticElement);
node.staticElement = _nextElement() as ConstructorElement?;
_expectMarker(MarkerTag.ConstructorName_end);
}
@override
void visitDeclaredIdentifier(DeclaredIdentifier node) {
_expectMarker(MarkerTag.DeclaredIdentifier_type);
node.type?.accept(this);
_expectMarker(MarkerTag.DeclaredIdentifier_identifier);
// node.identifier.accept(this);
_expectMarker(MarkerTag.DeclaredIdentifier_declaration);
_declaration(node);
_expectMarker(MarkerTag.DeclaredIdentifier_end);
}
@override
visitDefaultFormalParameter(DefaultFormalParameter node) {
var nodeImpl = node as DefaultFormalParameterImpl;
var enclosing = _enclosingElements.last;
var name = node.identifier?.name ?? '';
var enclosingReference = enclosing.reference;
var reference = node.isNamed && enclosingReference != null
? enclosingReference.getChild('@parameter').getChild(name)
: null;
ParameterElementImpl element;
if (node.parameter is FieldFormalParameter) {
element = DefaultFieldFormalParameterElementImpl.forLinkedNode(
enclosing, reference, node);
} else {
element =
DefaultParameterElementImpl.forLinkedNode(enclosing, reference, node);
}
var summaryData = nodeImpl.summaryData as SummaryDataForFormalParameter;
element.setCodeRange(summaryData.codeOffset, summaryData.codeLength);
_expectMarker(MarkerTag.DefaultFormalParameter_parameter);
node.parameter.accept(this);
_expectMarker(MarkerTag.DefaultFormalParameter_defaultValue);
node.defaultValue?.accept(this);
_expectMarker(MarkerTag.DefaultFormalParameter_end);
}
@override
void visitDottedName(DottedName node) {
node.components.accept(this);
}
@override
void visitDoubleLiteral(DoubleLiteral node) {
// TODO(scheglov) type?
}
@override
void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
_expectMarker(MarkerTag.EnumConstantDeclaration_name);
_expectMarker(MarkerTag.EnumConstantDeclaration_declaration);
_declaration(node);
_expectMarker(MarkerTag.EnumConstantDeclaration_end);
}
@override
void visitEnumDeclaration(EnumDeclaration node) {
_expectMarker(MarkerTag.EnumDeclaration_constants);
node.constants.accept(this);
_expectMarker(MarkerTag.EnumDeclaration_namedCompilationUnitMember);
_namedCompilationUnitMember(node);
_expectMarker(MarkerTag.EnumDeclaration_end);
}
@override
void visitExportDirective(ExportDirective node) {
var elementImpl = node.element as ExportElementImpl;
_expectMarker(MarkerTag.ExportDirective_namespaceDirective);
_namespaceDirective(node);
_expectMarker(MarkerTag.ExportDirective_exportedLibrary);
elementImpl.exportedLibrary = _nextElement() as LibraryElement?;
_expectMarker(MarkerTag.ExportDirective_end);
}
@override
void visitExpressionFunctionBody(ExpressionFunctionBody node) {
node.expression.accept(this);
}
@override
visitExtendsClause(ExtendsClause node) {
_expectMarker(MarkerTag.ExtendsClause_superclass);
node.superclass.accept(this);
_expectMarker(MarkerTag.ExtendsClause_end);
}
@override
void visitExtensionDeclaration(ExtensionDeclaration node) {
_assertNoLocalElements();
var element = node.declaredElement as ExtensionElementImpl;
_enclosingElements.add(element);
_expectMarker(MarkerTag.ExtensionDeclaration_typeParameters);
node.typeParameters?.accept(this);
_expectMarker(MarkerTag.ExtensionDeclaration_extendedType);
node.extendedType.accept(this);
_expectMarker(MarkerTag.ExtensionDeclaration_compilationUnitMember);
_compilationUnitMember(node);
_expectMarker(MarkerTag.ExtensionDeclaration_end);
_enclosingElements.removeLast();
}
@override
void visitExtensionOverride(
ExtensionOverride node, {
bool readRewrite = true,
}) {
// Read possible rewrite of `MethodInvocation`.
// If we are here, we don't need it.
if (readRewrite) {
_resolution.readByte();
}
_expectMarker(MarkerTag.ExtensionOverride_extensionName);
node.extensionName.accept(this);
_expectMarker(MarkerTag.ExtensionOverride_typeArguments);
node.typeArguments?.accept(this);
_expectMarker(MarkerTag.ExtensionOverride_argumentList);
node.argumentList.accept(this);
_expectMarker(MarkerTag.ExtensionOverride_extendedType);
(node as ExtensionOverrideImpl).extendedType = _nextType();
_expectMarker(MarkerTag.ExtensionOverride_end);
// TODO(scheglov) typeArgumentTypes?
}
@override
void visitFieldDeclaration(FieldDeclaration node) {
_assertNoLocalElements();
_pushEnclosingClassTypeParameters(node);
_expectMarker(MarkerTag.FieldDeclaration_fields);
node.fields.accept(this);
_expectMarker(MarkerTag.FieldDeclaration_classMember);
_classMember(node);
_expectMarker(MarkerTag.FieldDeclaration_end);
}
@override
void visitFieldFormalParameter(covariant FieldFormalParameterImpl node) {
if (node.declaredElement == null) {
assert(node.parent is! DefaultFormalParameter);
var enclosing = _enclosingElements.last;
var element =
FieldFormalParameterElementImpl.forLinkedNode(enclosing, null, node);
_normalFormalParameterNotDefault(node, element);
}
var localElementsLength = _localElements.length;
_expectMarker(MarkerTag.FieldFormalParameter_typeParameters);
node.typeParameters?.accept(this);
_expectMarker(MarkerTag.FieldFormalParameter_type);
node.type?.accept(this);
_expectMarker(MarkerTag.FieldFormalParameter_parameters);
node.parameters?.accept(this);
_expectMarker(MarkerTag.FieldFormalParameter_normalFormalParameter);
_normalFormalParameter(node);
_expectMarker(MarkerTag.FieldFormalParameter_end);
_localElements.length = localElementsLength;
}
@override
void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
_expectMarker(MarkerTag.ForEachPartsWithDeclaration_loopVariable);
node.loopVariable.accept(this);
_expectMarker(MarkerTag.ForEachPartsWithDeclaration_forEachParts);
_forEachParts(node);
_expectMarker(MarkerTag.ForEachPartsWithDeclaration_end);
}
@override
void visitForElement(ForElement node) {
_expectMarker(MarkerTag.ForElement_forLoopParts);
node.forLoopParts.accept(this);
_expectMarker(MarkerTag.ForElement_body);
node.body.accept(this);
_expectMarker(MarkerTag.ForElement_end);
}
@override
visitFormalParameterList(FormalParameterList node) {
_expectMarker(MarkerTag.FormalParameterList_parameters);
node.parameters.accept(this);
_expectMarker(MarkerTag.FormalParameterList_end);
}
@override
void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
for (var variable in node.variables.variables) {
variable as VariableDeclarationImpl;
var nameNode = variable.name;
nameNode.staticElement = LocalVariableElementImpl(
nameNode.name,
nameNode.offset,
);
}
_expectMarker(MarkerTag.ForPartsWithDeclarations_variables);
node.variables.accept(this);
_expectMarker(MarkerTag.ForPartsWithDeclarations_forParts);
_forParts(node);
_expectMarker(MarkerTag.ForPartsWithDeclarations_end);
}
@override
void visitForPartsWithExpression(ForPartsWithExpression node) {
_expectMarker(MarkerTag.ForPartsWithExpression_initialization);
node.initialization?.accept(this);
_expectMarker(MarkerTag.ForPartsWithExpression_forParts);
_forParts(node);
_expectMarker(MarkerTag.ForPartsWithExpression_end);
}
@override
void visitFunctionDeclaration(FunctionDeclaration node) {
_assertNoLocalElements();
var element = node.declaredElement as ExecutableElementImpl;
_enclosingElements.add(element);
_expectMarker(MarkerTag.FunctionDeclaration_functionExpression);
node.functionExpression.accept(this);
_expectMarker(MarkerTag.FunctionDeclaration_returnType);
node.returnType?.accept(this);
_expectMarker(MarkerTag.FunctionDeclaration_namedCompilationUnitMember);
_namedCompilationUnitMember(node);
_expectMarker(MarkerTag.FunctionDeclaration_returnTypeType);
element.returnType = _nextType()!;
_expectMarker(MarkerTag.FunctionDeclaration_end);
}
@override
void visitFunctionExpression(FunctionExpression node) {
_expectMarker(MarkerTag.FunctionExpression_typeParameters);
node.typeParameters?.accept(this);
_expectMarker(MarkerTag.FunctionExpression_parameters);
node.parameters?.accept(this);
_expectMarker(MarkerTag.FunctionExpression_end);
}
@override
void visitFunctionExpressionInvocation(
covariant FunctionExpressionInvocationImpl node, {
bool readRewrite = true,
}) {
// Read possible rewrite of `MethodInvocation`.
// If we are here, we don't need it.
if (readRewrite) {
_resolution.readByte();
}
_expectMarker(MarkerTag.FunctionExpressionInvocation_function);
node.function.accept(this);
_expectMarker(MarkerTag.FunctionExpressionInvocation_invocationExpression);
_invocationExpression(node);
_expectMarker(MarkerTag.FunctionExpressionInvocation_end);
}
@override
void visitFunctionTypeAlias(FunctionTypeAlias node) {
_assertNoLocalElements();
var element = node.declaredElement as TypeAliasElementImpl;
_enclosingElements.add(element);
_expectMarker(MarkerTag.FunctionTypeAlias_typeParameters);
node.typeParameters?.accept(this);
var function = element.aliasedElement as GenericFunctionTypeElementImpl;
_enclosingElements.add(function);
_expectMarker(MarkerTag.FunctionTypeAlias_returnType);
node.returnType?.accept(this);
_expectMarker(MarkerTag.FunctionTypeAlias_parameters);
node.parameters.accept(this);
_enclosingElements.removeLast();
_expectMarker(MarkerTag.FunctionTypeAlias_typeAlias);
_typeAlias(node);
_expectMarker(MarkerTag.FunctionTypeAlias_returnTypeType);
function.returnType = _nextType()!;
_expectMarker(MarkerTag.FunctionTypeAlias_flags);
element.isSimplyBounded = _resolution.readByte() != 0;
element.hasSelfReference = _resolution.readByte() != 0;
_expectMarker(MarkerTag.FunctionTypeAlias_end);
_enclosingElements.removeLast();
}
@override
void visitFunctionTypedFormalParameter(
covariant FunctionTypedFormalParameterImpl node) {
if (node.declaredElement == null) {
assert(node.parent is! DefaultFormalParameter);
var enclosing = _enclosingElements.last;
var element =
ParameterElementImpl.forLinkedNodeFactory(enclosing, null, node);
_normalFormalParameterNotDefault(node, element);
}
var localElementsLength = _localElements.length;
_expectMarker(MarkerTag.FunctionTypedFormalParameter_typeParameters);
node.typeParameters?.accept(this);
_expectMarker(MarkerTag.FunctionTypedFormalParameter_returnType);
node.returnType?.accept(this);
_expectMarker(MarkerTag.FunctionTypedFormalParameter_parameters);
node.parameters.accept(this);
_expectMarker(MarkerTag.FunctionTypedFormalParameter_normalFormalParameter);
_normalFormalParameter(node);
_expectMarker(MarkerTag.FunctionTypedFormalParameter_end);
_localElements.length = localElementsLength;
}
@override
void visitGenericFunctionType(GenericFunctionType node) {
var nodeImpl = node as GenericFunctionTypeImpl;
var localElementsLength = _localElements.length;
var element = nodeImpl.declaredElement as GenericFunctionTypeElementImpl?;
element ??= GenericFunctionTypeElementImpl.forLinkedNode(
_enclosingElements.last, null, node);
_enclosingElements.add(element);
_expectMarker(MarkerTag.GenericFunctionType_typeParameters);
node.typeParameters?.accept(this);
_expectMarker(MarkerTag.GenericFunctionType_returnType);
node.returnType?.accept(this);
_expectMarker(MarkerTag.GenericFunctionType_parameters);
node.parameters.accept(this);
_expectMarker(MarkerTag.GenericFunctionType_type);
nodeImpl.type = _nextType();
_expectMarker(MarkerTag.GenericFunctionType_end);
_localElements.length = localElementsLength;
_enclosingElements.removeLast();
}
@override
void visitGenericTypeAlias(GenericTypeAlias node) {
_assertNoLocalElements();
var element = node.declaredElement as TypeAliasElementImpl;
_enclosingElements.add(element);
_expectMarker(MarkerTag.GenericTypeAlias_typeParameters);
node.typeParameters?.accept(this);
_expectMarker(MarkerTag.GenericTypeAlias_type);
node.type.accept(this);
_expectMarker(MarkerTag.GenericTypeAlias_typeAlias);
_typeAlias(node);
_expectMarker(MarkerTag.GenericTypeAlias_flags);
element.isSimplyBounded = _resolution.readByte() != 0;
element.hasSelfReference = _resolution.readByte() != 0;
_expectMarker(MarkerTag.GenericTypeAlias_end);
_enclosingElements.removeLast();
}
@override
void visitHideCombinator(HideCombinator node) {
node.hiddenNames.accept(this);
}
@override
void visitIfElement(IfElement node) {
_expectMarker(MarkerTag.IfElement_condition);
node.condition.accept(this);
_expectMarker(MarkerTag.IfElement_thenElement);
node.thenElement.accept(this);
_expectMarker(MarkerTag.IfElement_elseElement);
node.elseElement?.accept(this);
_expectMarker(MarkerTag.IfElement_end);
}
@override
visitImplementsClause(ImplementsClause node) {
_expectMarker(MarkerTag.ImplementsClause_interfaces);
node.interfaces.accept(this);
_expectMarker(MarkerTag.ImplementsClause_end);
}
@override
void visitImportDirective(ImportDirective node) {
_expectMarker(MarkerTag.ImportDirective_namespaceDirective);
_namespaceDirective(node);
var element = node.element as ImportElementImpl;
_expectMarker(MarkerTag.ImportDirective_importedLibrary);
element.importedLibrary = _nextElement() as LibraryElement?;
_expectMarker(MarkerTag.ImportDirective_end);
}
@override
void visitIndexExpression(covariant IndexExpressionImpl node) {
_expectMarker(MarkerTag.IndexExpression_target);
node.target?.accept(this);
_expectMarker(MarkerTag.IndexExpression_index);
node.index.accept(this);
_expectMarker(MarkerTag.IndexExpression_staticElement);
node.staticElement = _nextElement() as MethodElement?;
_expectMarker(MarkerTag.IndexExpression_expression);
_expression(node);
_expectMarker(MarkerTag.IndexExpression_end);
}
@override
void visitInstanceCreationExpression(
covariant InstanceCreationExpressionImpl node, {
bool readRewrite = true,
}) {
// Read possible rewrite of `MethodInvocation`.
// If we are here, we don't need it.
if (readRewrite) {
_resolution.readByte();
}
_expectMarker(MarkerTag.InstanceCreationExpression_constructorName);
node.constructorName.accept(this);
_expectMarker(MarkerTag.InstanceCreationExpression_argumentList);
node.argumentList.accept(this);
_expectMarker(MarkerTag.InstanceCreationExpression_expression);
_expression(node);
_expectMarker(MarkerTag.InstanceCreationExpression_end);
_resolveNamedExpressions(
node.constructorName.staticElement,
node.argumentList,
);
}
@override
void visitIntegerLiteral(covariant IntegerLiteralImpl node) {
_expression(node);
}
@override
void visitInterpolationExpression(InterpolationExpression node) {
node.expression.accept(this);
}
@override
void visitInterpolationString(InterpolationString node) {
// TODO(scheglov) type?
}
@override
void visitIsExpression(covariant IsExpressionImpl node) {
_expectMarker(MarkerTag.IsExpression_expression);
node.expression.accept(this);
_expectMarker(MarkerTag.IsExpression_type);
node.type.accept(this);
_expectMarker(MarkerTag.IsExpression_expression2);
_expression(node);
_expectMarker(MarkerTag.IsExpression_end);
}
@override
void visitLibraryDirective(LibraryDirective node) {
node.name.accept(this);
_directive(node);
}
@override
void visitLibraryIdentifier(LibraryIdentifier node) {
node.components.accept(this);
}
@override
void visitListLiteral(covariant ListLiteralImpl node) {
_expectMarker(MarkerTag.ListLiteral_typeArguments);
node.typeArguments?.accept(this);
_expectMarker(MarkerTag.ListLiteral_elements);
node.elements.accept(this);
_expectMarker(MarkerTag.ListLiteral_expression);
_expression(node);
_expectMarker(MarkerTag.ListLiteral_end);
}
@override
void visitMapLiteralEntry(MapLiteralEntry node) {
_expectMarker(MarkerTag.MapLiteralEntry_key);
node.key.accept(this);
_expectMarker(MarkerTag.MapLiteralEntry_value);
node.value.accept(this);
}
@override
visitMethodDeclaration(MethodDeclaration node) {
_assertNoLocalElements();
_pushEnclosingClassTypeParameters(node);
var element = node.declaredElement as ExecutableElementImpl;
_enclosingElements.add(element.enclosingElement as ElementImpl);
_enclosingElements.add(element);
try {
_expectMarker(MarkerTag.MethodDeclaration_typeParameters);
node.typeParameters?.accept(this);
_expectMarker(MarkerTag.MethodDeclaration_returnType);
node.returnType?.accept(this);
_expectMarker(MarkerTag.MethodDeclaration_parameters);
node.parameters?.accept(this);
_expectMarker(MarkerTag.MethodDeclaration_classMember);
_classMember(node);
_expectMarker(MarkerTag.MethodDeclaration_returnTypeType);
element.returnType = _nextType()!;
_expectMarker(MarkerTag.MethodDeclaration_inferenceError);
_setTopLevelInferenceError(element);
if (element is MethodElementImpl) {
_expectMarker(MarkerTag.MethodDeclaration_flags);
element.isOperatorEqualWithParameterTypeFromObject =
_resolution.readByte() != 0;
}
_expectMarker(MarkerTag.MethodDeclaration_end);
} catch (e, stackTrace) {
// TODO(scheglov) Remove after fixing http://dartbug.com/44449
var headerStr = _astCodeBeforeMarkerOrMaxLength(node, '{', 1000);
throw CaughtExceptionWithFiles(e, stackTrace, {
'state': '''
element: ${element.reference}
header: $headerStr
resolution.bytes.length: ${_resolution.bytes.length}
resolution.byteOffset: ${_resolution.byteOffset}
''',
});
}
_enclosingElements.removeLast();
_enclosingElements.removeLast();
}
@override
void visitMethodInvocation(covariant MethodInvocationImpl node) {
var rewriteTag = _resolution.readByte();
if (rewriteTag == MethodInvocationRewriteTag.none) {
// No rewrite necessary.
} else if (rewriteTag == MethodInvocationRewriteTag.extensionOverride) {
Identifier identifier;
if (node.target == null) {
identifier = node.methodName;
} else {
identifier = astFactory.prefixedIdentifier(
node.target as SimpleIdentifier,
node.operator!,
node.methodName,
);
}
var replacement = astFactory.extensionOverride(
extensionName: identifier,
typeArguments: node.typeArguments,
argumentList: node.argumentList,
);
NodeReplacer.replace(node, replacement);
visitExtensionOverride(replacement, readRewrite: false);
return;
} else if (rewriteTag ==
MethodInvocationRewriteTag.functionExpressionInvocation) {
var target = node.target;
Expression expression;
if (target == null) {
expression = node.methodName;
} else {
expression = astFactory.propertyAccess(
target,
node.operator!,
node.methodName,
);
}
var replacement = astFactory.functionExpressionInvocation(
expression,
node.typeArguments,
node.argumentList,
);
NodeReplacer.replace(node, replacement);
visitFunctionExpressionInvocation(replacement, readRewrite: false);
return;
} else if (rewriteTag ==
MethodInvocationRewriteTag.instanceCreationExpression_withName) {
var replacement = astFactory.instanceCreationExpression(
null,
astFactory.constructorName(
astFactory.typeName(node.target as Identifier, null),
node.operator,
node.methodName,
),
node.argumentList,
);
NodeReplacer.replace(node, replacement);
visitInstanceCreationExpression(replacement, readRewrite: false);
return;
} else if (rewriteTag ==
MethodInvocationRewriteTag.instanceCreationExpression_withoutName) {
var typeNameName = node.target == null
? node.methodName
: astFactory.prefixedIdentifier(
node.target as SimpleIdentifier,
node.operator!,
node.methodName,
);
var replacement = astFactory.instanceCreationExpression(
null,
astFactory.constructorName(
astFactory.typeName(typeNameName, node.typeArguments),
null,
null,
),
node.argumentList,
);
NodeReplacer.replace(node, replacement);
visitInstanceCreationExpression(replacement, readRewrite: false);
return;
} else {
throw StateError('[rewriteTag: $rewriteTag][node: $node]');
}
_expectMarker(MarkerTag.MethodInvocation_target);
node.target?.accept(this);
_expectMarker(MarkerTag.MethodInvocation_methodName);
node.methodName.accept(this);
_expectMarker(MarkerTag.MethodInvocation_invocationExpression);
_invocationExpression(node);
_expectMarker(MarkerTag.MethodInvocation_end);
}
@override
void visitMixinDeclaration(MixinDeclaration node) {
_assertNoLocalElements();
var element = node.declaredElement as MixinElementImpl;
element.isSimplyBounded = _resolution.readByte() != 0;
element.superInvokedNames = _resolution.readStringList();
_enclosingElements.add(element);
_expectMarker(MarkerTag.MixinDeclaration_typeParameters);
node.typeParameters?.accept(this);
_expectMarker(MarkerTag.MixinDeclaration_onClause);
node.onClause?.accept(this);
_expectMarker(MarkerTag.MixinDeclaration_implementsClause);
node.implementsClause?.accept(this);
_expectMarker(MarkerTag.MixinDeclaration_namedCompilationUnitMember);
_namedCompilationUnitMember(node);
_expectMarker(MarkerTag.MixinDeclaration_end);
_enclosingElements.removeLast();
}
@override
void visitNamedExpression(NamedExpression node) {
_expectMarker(MarkerTag.NamedExpression_expression);
node.expression.accept(this);
_expectMarker(MarkerTag.NamedExpression_end);
}
@override
void visitNativeClause(NativeClause node) {
_expectMarker(MarkerTag.NativeClause_name);
node.name?.accept(this);
_expectMarker(MarkerTag.NativeClause_end);
}
@override
void visitNullLiteral(NullLiteral node) {
// TODO(scheglov) type?
}
@override
void visitOnClause(OnClause node) {
_expectMarker(MarkerTag.OnClause_superclassConstraints);
node.superclassConstraints.accept(this);
_expectMarker(MarkerTag.OnClause_end);
}
@override
void visitParenthesizedExpression(
covariant ParenthesizedExpressionImpl node) {
_expectMarker(MarkerTag.ParenthesizedExpression_expression);
node.expression.accept(this);
_expectMarker(MarkerTag.ParenthesizedExpression_expression2);
_expression(node);
_expectMarker(MarkerTag.ParenthesizedExpression_end);
}
@override
void visitPartDirective(PartDirective node) {
_uriBasedDirective(node);
}
@override
void visitPartOfDirective(PartOfDirective node) {
_expectMarker(MarkerTag.PartOfDirective_libraryName);
node.libraryName?.accept(this);
_expectMarker(MarkerTag.PartOfDirective_uri);
node.uri?.accept(this);
_expectMarker(MarkerTag.PartOfDirective_directive);
_directive(node);
_expectMarker(MarkerTag.PartOfDirective_end);
}
@override
void visitPostfixExpression(PostfixExpression node) {
var nodeImpl = node as PostfixExpressionImpl;
_expectMarker(MarkerTag.PostfixExpression_operand);
node.operand.accept(this);
_expectMarker(MarkerTag.PostfixExpression_staticElement);
node.staticElement = _nextElement() as MethodElement?;
if (node.operator.type.isIncrementOperator) {
_expectMarker(MarkerTag.PostfixExpression_readElement);
nodeImpl.readElement = _nextElement();
_expectMarker(MarkerTag.PostfixExpression_readType);
nodeImpl.readType = _nextType();
_expectMarker(MarkerTag.PostfixExpression_writeElement);
nodeImpl.writeElement = _nextElement();
_expectMarker(MarkerTag.PostfixExpression_writeType);
nodeImpl.writeType = _nextType();
}
_expectMarker(MarkerTag.PostfixExpression_expression);
_expression(node);
_expectMarker(MarkerTag.PostfixExpression_end);
}
@override
void visitPrefixedIdentifier(covariant PrefixedIdentifierImpl node) {
_expectMarker(MarkerTag.PrefixedIdentifier_prefix);
node.prefix.accept(this);
_expectMarker(MarkerTag.PrefixedIdentifier_identifier);
node.identifier.accept(this);
_expectMarker(MarkerTag.PrefixedIdentifier_expression);
_expression(node);
_expectMarker(MarkerTag.PrefixedIdentifier_end);
}
@override
void visitPrefixExpression(PrefixExpression node) {
var nodeImpl = node as PrefixExpressionImpl;
_expectMarker(MarkerTag.PrefixExpression_operand);
node.operand.accept(this);
_expectMarker(MarkerTag.PrefixExpression_staticElement);
node.staticElement = _nextElement() as MethodElement?;
if (node.operator.type.isIncrementOperator) {
_expectMarker(MarkerTag.PrefixExpression_readElement);
nodeImpl.readElement = _nextElement();
_expectMarker(MarkerTag.PrefixExpression_readType);
nodeImpl.readType = _nextType();
_expectMarker(MarkerTag.PrefixExpression_writeElement);
nodeImpl.writeElement = _nextElement();
_expectMarker(MarkerTag.PrefixExpression_writeType);
nodeImpl.writeType = _nextType();
}
_expectMarker(MarkerTag.PrefixExpression_expression);
_expression(node);
_expectMarker(MarkerTag.PrefixExpression_end);
}
@override
void visitPropertyAccess(covariant PropertyAccessImpl node) {
_expectMarker(MarkerTag.PropertyAccess_target);
node.target?.accept(this);
_expectMarker(MarkerTag.PropertyAccess_propertyName);
node.propertyName.accept(this);
_expectMarker(MarkerTag.PropertyAccess_expression);
_expression(node);
_expectMarker(MarkerTag.PropertyAccess_end);
}
@override
void visitRedirectingConstructorInvocation(
covariant RedirectingConstructorInvocationImpl node) {
_expectMarker(MarkerTag.RedirectingConstructorInvocation_constructorName);
node.constructorName?.accept(this);
_expectMarker(MarkerTag.RedirectingConstructorInvocation_argumentList);
node.argumentList.accept(this);
_expectMarker(MarkerTag.RedirectingConstructorInvocation_staticElement);
node.staticElement = _nextElement() as ConstructorElement?;
_resolveNamedExpressions(node.staticElement, node.argumentList);
_expectMarker(MarkerTag.RedirectingConstructorInvocation_end);
}
@override
void visitSetOrMapLiteral(covariant SetOrMapLiteralImpl node) {
_expectMarker(MarkerTag.SetOrMapLiteral_flags);
var mapOrSetBits = _resolution.readByte();
if ((mapOrSetBits & 0x01) != 0) {
node.becomeMap();
} else if ((mapOrSetBits & 0x02) != 0) {
node.becomeSet();
}
_expectMarker(MarkerTag.SetOrMapLiteral_typeArguments);
node.typeArguments?.accept(this);
_expectMarker(MarkerTag.SetOrMapLiteral_elements);
node.elements.accept(this);
_expectMarker(MarkerTag.SetOrMapLiteral_expression);
_expression(node);
_expectMarker(MarkerTag.SetOrMapLiteral_end);
}
@override
void visitShowCombinator(ShowCombinator node) {
node.shownNames.accept(this);
}
@override
visitSimpleFormalParameter(covariant SimpleFormalParameterImpl node) {
var element = node.declaredElement as ParameterElementImpl?;
if (element == null) {
assert(node.parent is! DefaultFormalParameter);
var enclosing = _enclosingElements.last;
element =
ParameterElementImpl.forLinkedNodeFactory(enclosing, null, node);
_normalFormalParameterNotDefault(node, element);
}
_expectMarker(MarkerTag.SimpleFormalParameter_type);
node.type?.accept(this);
_expectMarker(MarkerTag.SimpleFormalParameter_normalFormalParameter);
_normalFormalParameter(node);
_expectMarker(MarkerTag.SimpleFormalParameter_flags);
element.inheritsCovariant = _resolution.readByte() != 0;
_expectMarker(MarkerTag.SimpleFormalParameter_end);
}
@override
visitSimpleIdentifier(covariant SimpleIdentifierImpl node) {
_expectMarker(MarkerTag.SimpleIdentifier_staticElement);
node.staticElement = _nextElement();
_expectMarker(MarkerTag.SimpleIdentifier_expression);
_expression(node);
_expectMarker(MarkerTag.SimpleIdentifier_end);
}
@override
void visitSimpleStringLiteral(SimpleStringLiteral node) {
// TODO(scheglov) type?
}
@override
void visitSpreadElement(SpreadElement node) {
_expectMarker(MarkerTag.SpreadElement_expression);
node.expression.accept(this);
_expectMarker(MarkerTag.SpreadElement_end);
}
@override
void visitStringInterpolation(StringInterpolation node) {
_expectMarker(MarkerTag.StringInterpolation_elements);
node.elements.accept(this);
_expectMarker(MarkerTag.StringInterpolation_end);
// TODO(scheglov) type?
}
@override
void visitSuperConstructorInvocation(
covariant SuperConstructorInvocationImpl node) {
_expectMarker(MarkerTag.SuperConstructorInvocation_constructorName);
node.constructorName?.accept(this);
_expectMarker(MarkerTag.SuperConstructorInvocation_argumentList);
node.argumentList.accept(this);
_expectMarker(MarkerTag.SuperConstructorInvocation_staticElement);
node.staticElement = _nextElement() as ConstructorElement?;
_resolveNamedExpressions(node.staticElement, node.argumentList);
_expectMarker(MarkerTag.SuperConstructorInvocation_end);
}
@override
void visitSuperExpression(covariant SuperExpressionImpl node) {
_expectMarker(MarkerTag.SuperExpression_expression);
_expression(node);
_expectMarker(MarkerTag.SuperExpression_end);
}
@override
void visitSymbolLiteral(covariant SymbolLiteralImpl node) {
_expression(node);
}
@override
void visitThisExpression(covariant ThisExpressionImpl node) {
_expectMarker(MarkerTag.ThisExpression_expression);
_expression(node);
_expectMarker(MarkerTag.ThisExpression_end);
}
@override
void visitThrowExpression(covariant ThrowExpressionImpl node) {
_expectMarker(MarkerTag.ThrowExpression_expression);
node.expression.accept(this);
_expectMarker(MarkerTag.ThrowExpression_expression2);
_expression(node);
_expectMarker(MarkerTag.ThrowExpression_end);
}
@override
void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
_expectMarker(MarkerTag.TopLevelVariableDeclaration_variables);
node.variables.accept(this);
_expectMarker(MarkerTag.TopLevelVariableDeclaration_compilationUnitMember);
_compilationUnitMember(node);
_expectMarker(MarkerTag.TopLevelVariableDeclaration_end);
}
@override
visitTypeArgumentList(TypeArgumentList node) {
_expectMarker(MarkerTag.TypeArgumentList_arguments);
node.arguments.accept(this);
_expectMarker(MarkerTag.TypeArgumentList_end);
}
@override
visitTypeName(covariant TypeNameImpl node) {
_expectMarker(MarkerTag.TypeName_name);
node.name.accept(this);
_expectMarker(MarkerTag.TypeName_typeArguments);
node.typeArguments?.accept(this);
_expectMarker(MarkerTag.TypeName_type);
node.type = _nextType();
_expectMarker(MarkerTag.TypeName_end);
}
@override
visitTypeParameterList(TypeParameterList node) {
for (var typeParameter in node.typeParameters) {
typeParameter as TypeParameterImpl;
var element = TypeParameterElementImpl.forLinkedNode(
_enclosingElements.last,
typeParameter,
);
_localElements.add(element);
}
_expectMarker(MarkerTag.TypeParameterList_typeParameters);
for (var node in node.typeParameters) {
var nodeImpl = node as TypeParameterImpl;
var element = node.declaredElement as TypeParameterElementImpl;
var summaryData = nodeImpl.summaryData as SummaryDataForTypeParameter;
element.setCodeRange(summaryData.codeOffset, summaryData.codeLength);
_expectMarker(MarkerTag.TypeParameter_bound);
node.bound?.accept(this);
element.bound = node.bound?.type;
_expectMarker(MarkerTag.TypeParameter_declaration);
_declaration(node);
element.metadata = _buildAnnotations(
_unitContext.element,
node.metadata,
);
_expectMarker(MarkerTag.TypeParameter_variance);
element.variance = _decodeVariance(_resolution.readByte());
_expectMarker(MarkerTag.TypeParameter_defaultType);
element.defaultType = _nextType();
_expectMarker(MarkerTag.TypeParameter_end);
// TODO(scheglov) We used to do this with the previous elements impl.
// We probably still do this.
// But the code below is bad and incomplete.
// And why does this affect MethodMember(s)?
{
var parent = node.parent;
if (parent is ClassDeclaration) {
(parent.declaredElement as ElementImpl).encloseElement(element);
} else if (parent is ClassTypeAlias) {
(parent.declaredElement as ElementImpl).encloseElement(element);
} else if (parent is ExtensionDeclaration) {
(parent.declaredElement as ElementImpl).encloseElement(element);
} else if (parent is FunctionExpression) {
var parent2 = parent.parent;
if (parent2 is FunctionDeclaration) {
(parent2.declaredElement as ElementImpl).encloseElement(element);
}
} else if (parent is FunctionTypeAlias) {
(parent.declaredElement as ElementImpl).encloseElement(element);
} else if (parent is GenericTypeAlias) {
(parent.declaredElement as ElementImpl).encloseElement(element);
} else if (parent is MethodDeclaration) {
(parent.declaredElement as ElementImpl).encloseElement(element);
} else if (parent is MixinDeclaration) {
(parent.declaredElement as ElementImpl).encloseElement(element);
}
}
}
_expectMarker(MarkerTag.TypeParameterList_end);
}
@override
void visitVariableDeclaration(VariableDeclaration node) {
var element = node.declaredElement as VariableElementImpl;
_expectMarker(MarkerTag.VariableDeclaration_type);
element.type = _nextType()!;
_expectMarker(MarkerTag.VariableDeclaration_inferenceError);
_setTopLevelInferenceError(element);
if (element is FieldElementImpl) {
_expectMarker(MarkerTag.VariableDeclaration_inheritsCovariant);
element.inheritsCovariant = _resolution.readByte() != 0;
}
_expectMarker(MarkerTag.VariableDeclaration_initializer);
node.initializer?.accept(this);
_expectMarker(MarkerTag.VariableDeclaration_end);
}
@override
void visitVariableDeclarationList(VariableDeclarationList node) {
_expectMarker(MarkerTag.VariableDeclarationList_type);
node.type?.accept(this);
_expectMarker(MarkerTag.VariableDeclarationList_variables);
node.variables.accept(this);
_expectMarker(MarkerTag.VariableDeclarationList_annotatedNode);
_annotatedNode(node);
_expectMarker(MarkerTag.VariableDeclarationList_end);
}
@override
void visitWithClause(WithClause node) {
_expectMarker(MarkerTag.WithClause_mixinTypes);
node.mixinTypes.accept(this);
_expectMarker(MarkerTag.WithClause_end);
}
void _annotatedNode(AnnotatedNode node) {
_expectMarker(MarkerTag.AnnotatedNode_metadata);
node.metadata.accept(this);
_expectMarker(MarkerTag.AnnotatedNode_end);
}
void _assertNoLocalElements() {
assert(_localElements.isEmpty);
assert(_enclosingElements.length == 1 &&
_enclosingElements.first is CompilationUnitElement);
}
/// Return annotations for the given [nodeList] in the [unit].
List<ElementAnnotation> _buildAnnotations(
CompilationUnitElementImpl unit, List<Annotation> nodeList) {
var length = nodeList.length;
if (length == 0) {
return const <ElementAnnotation>[];
}
return List.generate(length, (index) {
var ast = nodeList[index];
return ElementAnnotationImpl(unit)
..annotationAst = ast
..element = ast.element;
});
}
void _classMember(ClassMember node) {
_expectMarker(MarkerTag.ClassMember_declaration);
_declaration(node);
}
void _compilationUnitMember(CompilationUnitMember node) {
_declaration(node);
}
void _declaration(Declaration node) {
_annotatedNode(node);
}
void _directive(Directive node) {
_annotatedNode(node);
}
void _expectMarker(MarkerTag tag) {
if (enableDebugResolutionMarkers) {
var actualIndex = _resolution.readUInt30();
if (actualIndex != tag.index) {
if (actualIndex < MarkerTag.values.length) {
var actualTag = MarkerTag.values[actualIndex];
throw StateError('Expected $tag, found $actualIndex = $actualTag');
} else {
throw StateError('Expected $tag, found $actualIndex');
}
}
}
}
void _expression(ExpressionImpl node) {
_expectMarker(MarkerTag.Expression_staticType);
node.staticType = _nextType();
}
void _forEachParts(ForEachParts node) {
_expectMarker(MarkerTag.ForEachParts_iterable);
node.iterable.accept(this);
_expectMarker(MarkerTag.ForEachParts_forLoopParts);
_forLoopParts(node);
_expectMarker(MarkerTag.ForEachParts_end);
}
void _forLoopParts(ForLoopParts node) {}
void _formalParameter(FormalParameter node) {
_expectMarker(MarkerTag.FormalParameter_type);
(node.declaredElement as ParameterElementImpl).type = _nextType()!;
}
void _forParts(ForParts node) {
_expectMarker(MarkerTag.ForParts_condition);
node.condition?.accept(this);
_expectMarker(MarkerTag.ForParts_updaters);
node.updaters.accept(this);
_expectMarker(MarkerTag.ForParts_forLoopParts);
_forLoopParts(node);
_expectMarker(MarkerTag.ForParts_end);
}
void _invocationExpression(covariant InvocationExpressionImpl node) {
_expectMarker(MarkerTag.InvocationExpression_typeArguments);
node.typeArguments?.accept(this);
_expectMarker(MarkerTag.InvocationExpression_argumentList);
node.argumentList.accept(this);
_expectMarker(MarkerTag.InvocationExpression_expression);
_expression(node);
_expectMarker(MarkerTag.InvocationExpression_end);
// TODO(scheglov) typeArgumentTypes and staticInvokeType?
var nodeImpl = node;
nodeImpl.typeArgumentTypes = [];
}
void _namedCompilationUnitMember(NamedCompilationUnitMember node) {
_compilationUnitMember(node);
}
void _namespaceDirective(NamespaceDirective node) {
_expectMarker(MarkerTag.NamespaceDirective_combinators);
node.combinators.accept(this);
_expectMarker(MarkerTag.NamespaceDirective_configurations);
node.configurations.accept(this);
_expectMarker(MarkerTag.NamespaceDirective_uriBasedDirective);
_uriBasedDirective(node);
_expectMarker(MarkerTag.NamespaceDirective_end);
}
Element? _nextElement() {
return _resolution.nextElement();
}
DartType? _nextType() {
return _resolution.nextType();
}
void _normalFormalParameter(NormalFormalParameter node) {
_expectMarker(MarkerTag.NormalFormalParameter_metadata);
node.metadata.accept(this);
_expectMarker(MarkerTag.NormalFormalParameter_formalParameter);
_formalParameter(node);
_expectMarker(MarkerTag.NormalFormalParameter_end);
}
void _normalFormalParameterNotDefault(
NormalFormalParameter node, ParameterElementImpl element) {
var nodeImpl = node as NormalFormalParameterImpl;
var summaryData = nodeImpl.summaryData as SummaryDataForFormalParameter;
element.setCodeRange(summaryData.codeOffset, summaryData.codeLength);
}
/// TODO(scheglov) also enclosing elements
void _pushEnclosingClassTypeParameters(ClassMember node) {
var parent = node.parent;
if (parent is ClassOrMixinDeclaration) {
var classElement = parent.declaredElement!;
_localElements.addAll(classElement.typeParameters);
} else {
var extension = parent as ExtensionDeclaration;
var classElement = extension.declaredElement!;
_localElements.addAll(classElement.typeParameters);
}
}
TopLevelInferenceError? _readTopLevelInferenceError() {
var kindIndex = _resolution.readByte();
var kind = TopLevelInferenceErrorKind.values[kindIndex];
if (kind == TopLevelInferenceErrorKind.none) {
return null;
}
return TopLevelInferenceError(
kind: kind,
arguments: _resolution.readStringList(),
);
}
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 parameters = executable.parameters;
var name = nameNode.name;
nameNode.staticElement = parameters.firstWhereOrNull((e) {
return e.name == name;
});
}
}
}
}
void _setTopLevelInferenceError(ElementImpl element) {
if (element is MethodElementImpl) {
element.typeInferenceError = _readTopLevelInferenceError();
} else if (element is PropertyInducingElementImpl) {
element.typeInferenceError = _readTopLevelInferenceError();
}
}
void _typeAlias(TypeAlias node) {
_namedCompilationUnitMember(node);
}
void _uriBasedDirective(UriBasedDirective node) {
_expectMarker(MarkerTag.UriBasedDirective_uri);
node.uri.accept(this);
_expectMarker(MarkerTag.UriBasedDirective_directive);
_directive(node);
_expectMarker(MarkerTag.UriBasedDirective_end);
}
/// TODO(scheglov) Remove after fixing http://dartbug.com/44449
static String _astCodeBeforeMarkerOrMaxLength(
AstNode node, String marker, int maxLength) {
var nodeStr = '$node';
var indexOfBody = nodeStr.indexOf(marker);
if (indexOfBody == -1) {
indexOfBody = min(maxLength, nodeStr.length);
}
return nodeStr.substring(0, indexOfBody);
}
static Variance? _decodeVariance(int encoding) {
if (encoding == 0) {
return null;
} else if (encoding == 1) {
return Variance.unrelated;
} else if (encoding == 2) {
return Variance.covariant;
} else if (encoding == 3) {
return Variance.contravariant;
} else if (encoding == 4) {
return Variance.invariant;
} else {
throw UnimplementedError('encoding: $encoding');
}
}
}