|  | // Copyright (c) 2014, 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. | 
|  |  | 
|  | // ignore_for_file: analyzer_use_new_elements | 
|  |  | 
|  | import 'dart:collection'; | 
|  |  | 
|  | import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart'; | 
|  | import 'package:_fe_analyzer_shared/src/parser/util.dart' as shared; | 
|  | import 'package:_fe_analyzer_shared/src/type_inference/type_analyzer_operations.dart' | 
|  | show Variance; | 
|  | import 'package:_fe_analyzer_shared/src/types/shared_type.dart'; | 
|  | import 'package:analyzer/dart/analysis/analysis_options.dart'; | 
|  | import 'package:analyzer/dart/analysis/features.dart'; | 
|  | import 'package:analyzer/dart/ast/syntactic_entity.dart'; | 
|  | import 'package:analyzer/dart/ast/token.dart'; | 
|  | import 'package:analyzer/dart/ast/visitor.dart'; | 
|  | import 'package:analyzer/dart/element/element.dart'; | 
|  | import 'package:analyzer/dart/element/element2.dart'; | 
|  | import 'package:analyzer/dart/element/type.dart'; | 
|  | import 'package:analyzer/diagnostic/diagnostic.dart'; | 
|  | import 'package:analyzer/error/error.dart'; | 
|  | import 'package:analyzer/error/listener.dart'; | 
|  | import 'package:analyzer/src/dart/analysis/analysis_options.dart'; | 
|  | import 'package:analyzer/src/dart/analysis/file_analysis.dart'; | 
|  | import 'package:analyzer/src/dart/analysis/file_state.dart'; | 
|  | import 'package:analyzer/src/dart/ast/ast.dart'; | 
|  | import 'package:analyzer/src/dart/ast/extensions.dart'; | 
|  | import 'package:analyzer/src/dart/element/class_hierarchy.dart'; | 
|  | import 'package:analyzer/src/dart/element/element.dart'; | 
|  | import 'package:analyzer/src/dart/element/extensions.dart'; | 
|  | import 'package:analyzer/src/dart/element/inheritance_manager3.dart'; | 
|  | import 'package:analyzer/src/dart/element/non_covariant_type_parameter_position.dart'; | 
|  | import 'package:analyzer/src/dart/element/type.dart'; | 
|  | import 'package:analyzer/src/dart/element/type_provider.dart'; | 
|  | import 'package:analyzer/src/dart/element/type_system.dart'; | 
|  | import 'package:analyzer/src/dart/element/well_bounded.dart'; | 
|  | import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart'; | 
|  | import 'package:analyzer/src/dart/resolver/scope.dart'; | 
|  | import 'package:analyzer/src/diagnostic/diagnostic.dart'; | 
|  | import 'package:analyzer/src/diagnostic/diagnostic_factory.dart'; | 
|  | import 'package:analyzer/src/error/codes.dart'; | 
|  | import 'package:analyzer/src/error/const_argument_verifier.dart'; | 
|  | import 'package:analyzer/src/error/constructor_fields_verifier.dart'; | 
|  | import 'package:analyzer/src/error/correct_override.dart'; | 
|  | import 'package:analyzer/src/error/duplicate_definition_verifier.dart'; | 
|  | import 'package:analyzer/src/error/getter_setter_types_verifier.dart'; | 
|  | import 'package:analyzer/src/error/literal_element_verifier.dart'; | 
|  | import 'package:analyzer/src/error/required_parameters_verifier.dart'; | 
|  | import 'package:analyzer/src/error/return_type_verifier.dart'; | 
|  | import 'package:analyzer/src/error/super_formal_parameters_verifier.dart'; | 
|  | import 'package:analyzer/src/error/type_arguments_verifier.dart'; | 
|  | import 'package:analyzer/src/error/use_result_verifier.dart'; | 
|  | import 'package:analyzer/src/generated/error_detection_helpers.dart'; | 
|  | import 'package:analyzer/src/generated/java_core.dart'; | 
|  | import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode; | 
|  | import 'package:analyzer/src/utilities/extensions/element.dart'; | 
|  | import 'package:analyzer/src/utilities/extensions/object.dart'; | 
|  | import 'package:analyzer/src/utilities/extensions/string.dart'; | 
|  | import 'package:collection/collection.dart'; | 
|  |  | 
|  | class EnclosingExecutableContext { | 
|  | final ExecutableElement2OrMember? element; | 
|  | final bool isAsynchronous; | 
|  | final bool isConstConstructor; | 
|  | final bool isGenerativeConstructor; | 
|  | final bool isGenerator; | 
|  | final bool inFactoryConstructor; | 
|  | final bool inStaticMethod; | 
|  |  | 
|  | /// If this [EnclosingExecutableContext] is the first argument in a method | 
|  | /// invocation of [Future.catchError], returns the return type expected for | 
|  | /// `Future<T>.catchError`'s `onError` parameter, which is `FutureOr<T>`, | 
|  | /// otherwise `null`. | 
|  | final InterfaceTypeImpl? catchErrorOnErrorReturnType; | 
|  |  | 
|  | /// The return statements that have a value. | 
|  | final List<ReturnStatement> _returnsWith = []; | 
|  |  | 
|  | /// The return statements that do not have a value. | 
|  | final List<ReturnStatement> _returnsWithout = []; | 
|  |  | 
|  | /// This flag is set to `false` when the declared return type is not legal | 
|  | /// for the kind of the function body, e.g. not `Future` for `async`. | 
|  | bool hasLegalReturnType = true; | 
|  |  | 
|  | /// The number of enclosing [CatchClause] in this executable. | 
|  | int catchClauseLevel = 0; | 
|  |  | 
|  | EnclosingExecutableContext(this.element, | 
|  | {required this.isAsynchronous, | 
|  | required this.isGenerator, | 
|  | this.catchErrorOnErrorReturnType}) | 
|  | : isConstConstructor = | 
|  | element is ConstructorElementMixin2 && element.isConst, | 
|  | isGenerativeConstructor = | 
|  | element is ConstructorElementMixin2 && !element.isFactory, | 
|  | inFactoryConstructor = _inFactoryConstructor(element), | 
|  | inStaticMethod = _inStaticMethod(element); | 
|  |  | 
|  | EnclosingExecutableContext.empty() | 
|  | : this(null, isAsynchronous: false, isGenerator: false); | 
|  |  | 
|  | String? get displayName { | 
|  | return element?.displayName; | 
|  | } | 
|  |  | 
|  | bool get isClosure => switch (element) { | 
|  | LocalFunctionElement(:var displayName) => displayName.isEmpty, | 
|  | _ => false, | 
|  | }; | 
|  |  | 
|  | bool get isConstructor => element is ConstructorElement2; | 
|  |  | 
|  | bool get isFunction => switch (element) { | 
|  | LocalFunctionElement(:var displayName) => displayName.isNotEmpty, | 
|  | TopLevelFunctionElement(:var displayName) => displayName.isNotEmpty, | 
|  | PropertyAccessorElement2() => true, | 
|  | _ => false, | 
|  | }; | 
|  |  | 
|  | bool get isMethod => element is MethodElement2; | 
|  |  | 
|  | bool get isSynchronous => !isAsynchronous; | 
|  |  | 
|  | TypeImpl get returnType { | 
|  | return catchErrorOnErrorReturnType ?? element!.returnType; | 
|  | } | 
|  |  | 
|  | static bool _inFactoryConstructor(Element2? element) { | 
|  | var enclosing = element?.firstFragment.enclosingFragment; | 
|  | if (enclosing == null) { | 
|  | return false; | 
|  | } | 
|  | if (element is ConstructorElement2) { | 
|  | return element.isFactory; | 
|  | } | 
|  | return _inFactoryConstructor(enclosing.element); | 
|  | } | 
|  |  | 
|  | static bool _inStaticMethod(Element2? element) { | 
|  | var enclosing = element?.firstFragment.enclosingFragment; | 
|  | if (enclosing == null) { | 
|  | return false; | 
|  | } | 
|  | if (enclosing is InterfaceFragment || enclosing is ExtensionFragment) { | 
|  | if (element is ExecutableElement2) { | 
|  | return element.isStatic; | 
|  | } | 
|  | } | 
|  | return _inStaticMethod(enclosing.element); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// A visitor used to traverse an AST structure looking for additional errors | 
|  | /// and warnings not covered by the parser and resolver. | 
|  | class ErrorVerifier extends RecursiveAstVisitor<void> | 
|  | with ErrorDetectionHelpers { | 
|  | /// The factory used to create diagnostic messages. | 
|  | static final _diagnosticFactory = DiagnosticFactory(); | 
|  |  | 
|  | /// The error reporter by which errors will be reported. | 
|  | @override | 
|  | final ErrorReporter errorReporter; | 
|  |  | 
|  | /// The current library that is being analyzed. | 
|  | final LibraryElementImpl _currentLibrary; | 
|  |  | 
|  | /// The current unit that is being analyzed. | 
|  | final CompilationUnitElementImpl _currentUnit; | 
|  |  | 
|  | /// The type representing the type 'int'. | 
|  | late final InterfaceTypeImpl _intType; | 
|  |  | 
|  | /// The options for verification. | 
|  | final AnalysisOptions options; | 
|  |  | 
|  | /// The object providing access to the types defined by the language. | 
|  | final TypeProviderImpl _typeProvider; | 
|  |  | 
|  | /// The type system primitives | 
|  | @override | 
|  | late final TypeSystemImpl typeSystem; | 
|  |  | 
|  | /// The manager for the inheritance mappings. | 
|  | final InheritanceManager3 _inheritanceManager; | 
|  |  | 
|  | /// A flag indicating whether the visitor is currently within a comment. | 
|  | bool _isInComment = false; | 
|  |  | 
|  | /// The stack of flags, where `true` at the top (last) of the stack indicates | 
|  | /// that the visitor is in the initializer of a lazy local variable. When the | 
|  | /// top is `false`, we might be not in a local variable, or it is not `lazy`, | 
|  | /// etc. | 
|  | final List<bool> _isInLateLocalVariable = [false]; | 
|  |  | 
|  | /// A flag indicating whether the visitor is currently within a native class | 
|  | /// declaration. | 
|  | bool _isInNativeClass = false; | 
|  |  | 
|  | /// A flag indicating whether the visitor is currently within a static | 
|  | /// variable declaration. | 
|  | bool _isInStaticVariableDeclaration = false; | 
|  |  | 
|  | /// A flag indicating whether the visitor is currently within an instance | 
|  | /// variable declaration, which is not `late`. | 
|  | bool _isInInstanceNotLateVariableDeclaration = false; | 
|  |  | 
|  | /// A flag indicating whether the visitor is currently within a constructor | 
|  | /// initializer. | 
|  | bool _isInConstructorInitializer = false; | 
|  |  | 
|  | /// This is set to `true` iff the visitor is currently within a function typed | 
|  | /// formal parameter. | 
|  | bool _isInFunctionTypedFormalParameter = false; | 
|  |  | 
|  | /// A flag indicating whether the visitor is currently within code in the SDK. | 
|  | bool _isInSystemLibrary = false; | 
|  |  | 
|  | /// The class containing the AST nodes being visited, or `null` if we are not | 
|  | /// in the scope of a class. | 
|  | InterfaceElementImpl2? _enclosingClass; | 
|  |  | 
|  | /// The element of the extension being visited, or `null` if we are not | 
|  | /// in the scope of an extension. | 
|  | ExtensionElement2? _enclosingExtension; | 
|  |  | 
|  | /// Whether the current location has access to `this`. | 
|  | bool _hasAccessToThis = false; | 
|  |  | 
|  | /// The context of the method or function that we are currently visiting, or | 
|  | /// `null` if we are not inside a method or function. | 
|  | EnclosingExecutableContext _enclosingExecutable = | 
|  | EnclosingExecutableContext.empty(); | 
|  |  | 
|  | /// A set of the names of the variable initializers we are visiting now. | 
|  | final HashSet<String> _namesForReferenceToDeclaredVariableInInitializer = | 
|  | HashSet<String>(); | 
|  |  | 
|  | /// The elements that will be defined later in the current scope, but right | 
|  | /// now are not declared. | 
|  | HiddenElements? _hiddenElements; | 
|  |  | 
|  | final _UninstantiatedBoundChecker _uninstantiatedBoundChecker; | 
|  |  | 
|  | /// The features enabled in the unit currently being checked for errors. | 
|  | FeatureSet? _featureSet; | 
|  |  | 
|  | final LibraryVerificationContext libraryContext; | 
|  | final RequiredParametersVerifier _requiredParametersVerifier; | 
|  | final ConstArgumentsVerifier _constArgumentsVerifier; | 
|  | final DuplicateDefinitionVerifier _duplicateDefinitionVerifier; | 
|  | final UseResultVerifier _checkUseVerifier; | 
|  | late final TypeArgumentsVerifier _typeArgumentsVerifier; | 
|  | late final ReturnTypeVerifier _returnTypeVerifier; | 
|  | final TypeSystemOperations typeSystemOperations; | 
|  |  | 
|  | /// Initialize a newly created error verifier. | 
|  | ErrorVerifier( | 
|  | this.errorReporter, | 
|  | this._currentLibrary, | 
|  | this._currentUnit, | 
|  | this._typeProvider, | 
|  | this._inheritanceManager, | 
|  | this.libraryContext, | 
|  | this.options, { | 
|  | required this.typeSystemOperations, | 
|  | })  : _uninstantiatedBoundChecker = | 
|  | _UninstantiatedBoundChecker(errorReporter), | 
|  | _checkUseVerifier = UseResultVerifier(errorReporter), | 
|  | _requiredParametersVerifier = RequiredParametersVerifier(errorReporter), | 
|  | _constArgumentsVerifier = ConstArgumentsVerifier(errorReporter), | 
|  | _duplicateDefinitionVerifier = DuplicateDefinitionVerifier( | 
|  | _currentLibrary, | 
|  | errorReporter, | 
|  | libraryContext.duplicationDefinitionContext, | 
|  | ) { | 
|  | _isInSystemLibrary = _currentLibrary.source.uri.isScheme('dart'); | 
|  | _isInStaticVariableDeclaration = false; | 
|  | _isInConstructorInitializer = false; | 
|  | _intType = _typeProvider.intType; | 
|  | typeSystem = _currentLibrary.typeSystem; | 
|  | _typeArgumentsVerifier = | 
|  | TypeArgumentsVerifier(options, _currentLibrary, errorReporter); | 
|  | _returnTypeVerifier = ReturnTypeVerifier( | 
|  | typeProvider: _typeProvider, | 
|  | typeSystem: typeSystem, | 
|  | errorReporter: errorReporter, | 
|  | strictCasts: strictCasts, | 
|  | ); | 
|  | } | 
|  |  | 
|  | @override | 
|  | InheritanceManager3 get inheritance => _inheritanceManager; | 
|  |  | 
|  | @override | 
|  | bool get strictCasts => options.strictCasts; | 
|  |  | 
|  | /// The language team is thinking about adding abstract fields, or external | 
|  | /// fields. But for now we will ignore such fields in `Struct` subtypes. | 
|  | bool get _isEnclosingClassFfiStruct { | 
|  | var superClass = _enclosingClass?.supertype?.element3; | 
|  | return superClass != null && | 
|  | _isDartFfiLibrary(superClass.library2) && | 
|  | superClass.name3 == 'Struct'; | 
|  | } | 
|  |  | 
|  | /// The language team is thinking about adding abstract fields, or external | 
|  | /// fields. But for now we will ignore such fields in `Struct` subtypes. | 
|  | bool get _isEnclosingClassFfiUnion { | 
|  | var superClass = _enclosingClass?.supertype?.element3; | 
|  | return superClass != null && | 
|  | _isDartFfiLibrary(superClass.library2) && | 
|  | superClass.name3 == 'Union'; | 
|  | } | 
|  |  | 
|  | @override | 
|  | List<DiagnosticMessage> computeWhyNotPromotedMessages( | 
|  | SyntacticEntity errorEntity, | 
|  | Map<SharedTypeView, NonPromotionReason>? whyNotPromoted) { | 
|  | return []; | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitAnnotation(Annotation node) { | 
|  | _checkForInvalidAnnotationFromDeferredLibrary(node); | 
|  | _requiredParametersVerifier.visitAnnotation(node); | 
|  | super.visitAnnotation(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitAsExpression(AsExpression node) { | 
|  | _checkForTypeAnnotationDeferredClass(node.type); | 
|  | super.visitAsExpression(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitAssertInitializer(AssertInitializer node) { | 
|  | _isInConstructorInitializer = true; | 
|  | try { | 
|  | super.visitAssertInitializer(node); | 
|  | } finally { | 
|  | _isInConstructorInitializer = false; | 
|  | } | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitAssignmentExpression(covariant AssignmentExpressionImpl node) { | 
|  | TokenType operatorType = node.operator.type; | 
|  | Expression lhs = node.leftHandSide; | 
|  | if (operatorType == TokenType.QUESTION_QUESTION_EQ) { | 
|  | _checkForDeadNullCoalesce(node.readType!, node.rightHandSide); | 
|  | } | 
|  | _checkForAssignmentToFinal(lhs); | 
|  |  | 
|  | _constArgumentsVerifier.visitAssignmentExpression(node); | 
|  | super.visitAssignmentExpression(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitAwaitExpression(AwaitExpression node) { | 
|  | if (!_enclosingExecutable.isAsynchronous) { | 
|  | errorReporter.atToken( | 
|  | node.awaitKeyword, | 
|  | CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT, | 
|  | ); | 
|  | } | 
|  | checkForUseOfVoidResult(node.expression); | 
|  | _checkForAwaitInLateLocalVariableInitializer(node); | 
|  | _checkForAwaitOfIncompatibleType(node); | 
|  | super.visitAwaitExpression(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitBinaryExpression(covariant BinaryExpressionImpl node) { | 
|  | Token operator = node.operator; | 
|  | TokenType type = operator.type; | 
|  | if (type == TokenType.AMPERSAND_AMPERSAND || type == TokenType.BAR_BAR) { | 
|  | checkForUseOfVoidResult(node.rightOperand); | 
|  | } else { | 
|  | // Assignability checking is done by the resolver. | 
|  | } | 
|  |  | 
|  | if (type == TokenType.QUESTION_QUESTION) { | 
|  | _checkForDeadNullCoalesce( | 
|  | node.leftOperand.staticType!, node.rightOperand); | 
|  | } | 
|  |  | 
|  | checkForUseOfVoidResult(node.leftOperand); | 
|  | _constArgumentsVerifier.visitBinaryExpression(node); | 
|  |  | 
|  | super.visitBinaryExpression(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitBlock(covariant BlockImpl node) { | 
|  | _withHiddenElements(node.statements, () { | 
|  | _duplicateDefinitionVerifier.checkStatements(node.statements); | 
|  | super.visitBlock(node); | 
|  | }); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitBlockFunctionBody(BlockFunctionBody node) { | 
|  | var oldHasAccessToThis = _hasAccessToThis; | 
|  | try { | 
|  | _hasAccessToThis = _computeThisAccessForFunctionBody(node); | 
|  | super.visitBlockFunctionBody(node); | 
|  | } finally { | 
|  | _hasAccessToThis = oldHasAccessToThis; | 
|  | } | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitBreakStatement(BreakStatement node) { | 
|  | var labelNode = node.label; | 
|  | if (labelNode != null) { | 
|  | var labelElement = labelNode.element; | 
|  | if (labelElement is LabelElementImpl2 && labelElement.isOnSwitchMember) { | 
|  | errorReporter.atNode( | 
|  | labelNode, | 
|  | CompileTimeErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitCatchClause(CatchClause node) { | 
|  | _duplicateDefinitionVerifier.checkCatchClause(node); | 
|  | try { | 
|  | _enclosingExecutable.catchClauseLevel++; | 
|  | _checkForTypeAnnotationDeferredClass(node.exceptionType); | 
|  | super.visitCatchClause(node); | 
|  | } finally { | 
|  | _enclosingExecutable.catchClauseLevel--; | 
|  | } | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitClassDeclaration(covariant ClassDeclarationImpl node) { | 
|  | try { | 
|  | var declaredFragment = node.declaredFragment!; | 
|  |  | 
|  | _isInNativeClass = node.nativeClause != null; | 
|  |  | 
|  | var augmented = declaredFragment.element; | 
|  | var declarationElement = augmented.firstFragment; | 
|  | _enclosingClass = declarationElement.asElement2; | 
|  |  | 
|  | List<ClassMember> members = node.members; | 
|  | if (!declarationElement.isDartCoreFunctionImpl) { | 
|  | _checkForBuiltInIdentifierAsName( | 
|  | node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME); | 
|  | } | 
|  | _checkForConflictingClassTypeVariableErrorCodes(); | 
|  | var superclass = node.extendsClause?.superclass; | 
|  | var implementsClause = node.implementsClause; | 
|  | var withClause = node.withClause; | 
|  |  | 
|  | // Only do error checks on the clause nodes if there is a non-null clause | 
|  | if (implementsClause != null || | 
|  | superclass != null || | 
|  | withClause != null) { | 
|  | var moreChecks = _checkClassInheritance( | 
|  | declarationElement, node, superclass, withClause, implementsClause); | 
|  | if (moreChecks) { | 
|  | _checkForNoDefaultSuperConstructorImplicit(declaredFragment); | 
|  | } | 
|  | } | 
|  |  | 
|  | if (node.nativeClause == null) { | 
|  | libraryContext.constructorFieldsVerifier | 
|  | .addConstructors(errorReporter, augmented, members); | 
|  | } | 
|  |  | 
|  | _checkForConflictingClassMembers(declaredFragment); | 
|  | _checkForFinalNotInitializedInClass(declaredFragment, members); | 
|  | _checkForBadFunctionUse( | 
|  | superclass: node.extendsClause?.superclass, | 
|  | withClause: node.withClause, | 
|  | implementsClause: node.implementsClause, | 
|  | ); | 
|  | _checkForWrongTypeParameterVarianceInSuperinterfaces(); | 
|  | _checkForMainFunction1(node.name, node.declaredFragment!); | 
|  | _checkForMixinClassErrorCodes(node, members, superclass, withClause); | 
|  |  | 
|  | GetterSetterTypesVerifier( | 
|  | typeSystem: typeSystem, | 
|  | errorReporter: errorReporter, | 
|  | ).checkStaticGetters(augmented.getters2); | 
|  |  | 
|  | super.visitClassDeclaration(node); | 
|  | } finally { | 
|  | _isInNativeClass = false; | 
|  | _enclosingClass = null; | 
|  | } | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitClassTypeAlias(covariant ClassTypeAliasImpl node) { | 
|  | var fragment = node.declaredFragment!; | 
|  | var element = fragment.element; | 
|  | var firstFragment = element.firstFragment; | 
|  |  | 
|  | _checkForBuiltInIdentifierAsName( | 
|  | node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME); | 
|  | try { | 
|  | _enclosingClass = firstFragment.asElement2; | 
|  | _checkClassInheritance(firstFragment, node, node.superclass, | 
|  | node.withClause, node.implementsClause); | 
|  | _checkForMainFunction1(node.name, node.declaredFragment!); | 
|  | _checkForMixinClassErrorCodes( | 
|  | node, List.empty(), node.superclass, node.withClause); | 
|  | _checkForBadFunctionUse( | 
|  | superclass: node.superclass, | 
|  | withClause: node.withClause, | 
|  | implementsClause: node.implementsClause, | 
|  | ); | 
|  | _checkForWrongTypeParameterVarianceInSuperinterfaces(); | 
|  | } finally { | 
|  | _enclosingClass = null; | 
|  | } | 
|  | super.visitClassTypeAlias(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitComment(Comment node) { | 
|  | _isInComment = true; | 
|  | try { | 
|  | super.visitComment(node); | 
|  | } finally { | 
|  | _isInComment = false; | 
|  | } | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitCompilationUnit(covariant CompilationUnitImpl node) { | 
|  | var fragment = node.declaredFragment!; | 
|  | _featureSet = node.featureSet; | 
|  | _duplicateDefinitionVerifier.checkUnit(node); | 
|  | _checkForDeferredPrefixCollisions(node); | 
|  | _checkForIllegalLanguageOverride(node); | 
|  |  | 
|  | GetterSetterTypesVerifier( | 
|  | typeSystem: typeSystem, | 
|  | errorReporter: errorReporter, | 
|  | ).checkStaticGetters(fragment.element.getters); | 
|  |  | 
|  | super.visitCompilationUnit(node); | 
|  | _featureSet = null; | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitConstructorDeclaration( | 
|  | covariant ConstructorDeclarationImpl node, | 
|  | ) { | 
|  | var fragment = node.declaredFragment!; | 
|  | var element = fragment.element; | 
|  | _withEnclosingExecutable( | 
|  | element, | 
|  | () { | 
|  | _checkForNonConstGenerativeEnumConstructor(node); | 
|  | _checkForInvalidModifierOnBody( | 
|  | node.body, CompileTimeErrorCode.INVALID_MODIFIER_ON_CONSTRUCTOR); | 
|  | if (!_checkForConstConstructorWithNonConstSuper(node)) { | 
|  | _checkForConstConstructorWithNonFinalField(node, element); | 
|  | } | 
|  | _checkForRedirectingConstructorErrorCodes(node); | 
|  | _checkForConflictingInitializerErrorCodes(node); | 
|  | _checkForRecursiveConstructorRedirect(node, element); | 
|  | if (!_checkForRecursiveFactoryRedirect(node, element)) { | 
|  | _checkForAllRedirectConstructorErrorCodes(node); | 
|  | } | 
|  | _checkForUndefinedConstructorInInitializerImplicit(node); | 
|  | _checkForReturnInGenerativeConstructor(node); | 
|  | super.visitConstructorDeclaration(node); | 
|  | }, | 
|  | isAsynchronous: fragment.isAsynchronous, | 
|  | isGenerator: fragment.isGenerator, | 
|  | ); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitConstructorFieldInitializer(ConstructorFieldInitializer node) { | 
|  | _isInConstructorInitializer = true; | 
|  | try { | 
|  | SimpleIdentifier fieldName = node.fieldName; | 
|  | var element = fieldName.element; | 
|  | _checkForInvalidField(node, fieldName, element); | 
|  | if (element is FieldElement2) { | 
|  | _checkForAbstractOrExternalFieldConstructorInitializer( | 
|  | node.fieldName.token, element); | 
|  | } | 
|  | super.visitConstructorFieldInitializer(node); | 
|  | } finally { | 
|  | _isInConstructorInitializer = false; | 
|  | } | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitConstructorReference(covariant ConstructorReferenceImpl node) { | 
|  | _typeArgumentsVerifier.checkConstructorReference(node); | 
|  | _checkForInvalidGenerativeConstructorReference(node.constructorName); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitDefaultFormalParameter(covariant DefaultFormalParameterImpl node) { | 
|  | var defaultValue = node.defaultValue; | 
|  | if (defaultValue != null) { | 
|  | checkForAssignableExpressionAtType( | 
|  | defaultValue, | 
|  | defaultValue.typeOrThrow, | 
|  | node.declaredFragment!.element.type, | 
|  | CompileTimeErrorCode.INVALID_ASSIGNMENT, | 
|  | ); | 
|  | } | 
|  |  | 
|  | super.visitDefaultFormalParameter(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitEnumConstantDeclaration( | 
|  | covariant EnumConstantDeclarationImpl node, | 
|  | ) { | 
|  | _requiredParametersVerifier.visitEnumConstantDeclaration(node); | 
|  | _typeArgumentsVerifier.checkEnumConstantDeclaration(node); | 
|  | super.visitEnumConstantDeclaration(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitEnumDeclaration(covariant EnumDeclarationImpl node) { | 
|  | try { | 
|  | var declaredFragment = node.declaredFragment!; | 
|  | var declaredElement = declaredFragment.element; | 
|  | var firstFragment = declaredElement.firstFragment; | 
|  |  | 
|  | var element = declaredFragment.element; | 
|  | _enclosingClass = element; | 
|  |  | 
|  | _checkForBuiltInIdentifierAsName( | 
|  | node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME); | 
|  | _checkForConflictingEnumTypeVariableErrorCodes(declaredFragment); | 
|  | var implementsClause = node.implementsClause; | 
|  | var withClause = node.withClause; | 
|  |  | 
|  | if (implementsClause != null || withClause != null) { | 
|  | _checkClassInheritance( | 
|  | firstFragment, node, null, withClause, implementsClause); | 
|  | } | 
|  |  | 
|  | if (!declaredFragment.isAugmentation) { | 
|  | if (element.constants2.isEmpty) { | 
|  | errorReporter.atToken( | 
|  | node.name, | 
|  | CompileTimeErrorCode.ENUM_WITHOUT_CONSTANTS, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | var members = node.members; | 
|  | libraryContext.constructorFieldsVerifier | 
|  | .addConstructors(errorReporter, element, members); | 
|  | _checkForFinalNotInitializedInClass(declaredFragment, members); | 
|  | _checkForWrongTypeParameterVarianceInSuperinterfaces(); | 
|  | _checkForMainFunction1(node.name, node.declaredFragment!); | 
|  | _checkForEnumInstantiatedToBoundsIsNotWellBounded(node, declaredFragment); | 
|  |  | 
|  | GetterSetterTypesVerifier( | 
|  | typeSystem: typeSystem, | 
|  | errorReporter: errorReporter, | 
|  | ).checkStaticGetters(declaredElement.getters2); | 
|  |  | 
|  | super.visitEnumDeclaration(node); | 
|  | } finally { | 
|  | _enclosingClass = null; | 
|  | } | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitExportDirective(covariant ExportDirectiveImpl node) { | 
|  | var libraryExport = node.libraryExport; | 
|  | if (libraryExport != null) { | 
|  | var exportedLibrary = libraryExport.exportedLibrary2; | 
|  | _checkForAmbiguousExport(node, libraryExport, exportedLibrary); | 
|  | _checkForExportInternalLibrary(node, libraryExport); | 
|  | } | 
|  | _reportForMultipleCombinators(node); | 
|  | super.visitExportDirective(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitExpressionFunctionBody(ExpressionFunctionBody node) { | 
|  | var oldHasAccessToThis = _hasAccessToThis; | 
|  | try { | 
|  | _hasAccessToThis = _computeThisAccessForFunctionBody(node); | 
|  | _returnTypeVerifier.verifyExpressionFunctionBody(node); | 
|  | super.visitExpressionFunctionBody(node); | 
|  | } finally { | 
|  | _hasAccessToThis = oldHasAccessToThis; | 
|  | } | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitExtensionDeclaration(covariant ExtensionDeclarationImpl node) { | 
|  | var declaredFragment = node.declaredFragment!; | 
|  | var declaredElement = declaredFragment.element; | 
|  |  | 
|  | _enclosingExtension = declaredFragment.asElement2; | 
|  | _checkForConflictingExtensionTypeVariableErrorCodes(); | 
|  | _checkForFinalNotInitializedInClass(declaredFragment, node.members); | 
|  |  | 
|  | GetterSetterTypesVerifier( | 
|  | typeSystem: typeSystem, | 
|  | errorReporter: errorReporter, | 
|  | ).checkExtension(declaredElement); | 
|  |  | 
|  | var name = node.name; | 
|  | if (name != null) { | 
|  | _checkForBuiltInIdentifierAsName( | 
|  | name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_EXTENSION_NAME); | 
|  | } | 
|  | super.visitExtensionDeclaration(node); | 
|  | _enclosingExtension = null; | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitExtensionTypeDeclaration( | 
|  | covariant ExtensionTypeDeclarationImpl node, | 
|  | ) { | 
|  | try { | 
|  | var declaredFragment = node.declaredFragment!; | 
|  | var declaredElement = declaredFragment.element; | 
|  | var firstFragment = declaredElement.firstFragment; | 
|  |  | 
|  | _enclosingClass = firstFragment.asElement2; | 
|  |  | 
|  | _checkForBuiltInIdentifierAsName(node.name, | 
|  | CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_EXTENSION_TYPE_NAME); | 
|  | _checkForConflictingExtensionTypeTypeVariableErrorCodes(declaredFragment); | 
|  |  | 
|  | var members = node.members; | 
|  | _checkForRepeatedType( | 
|  | libraryContext.setOfImplements(firstFragment.asElement2), | 
|  | node.implementsClause?.interfaces, | 
|  | CompileTimeErrorCode.IMPLEMENTS_REPEATED, | 
|  | ); | 
|  | _checkForConflictingClassMembers(declaredFragment); | 
|  | _checkForConflictingGenerics(node); | 
|  | libraryContext.constructorFieldsVerifier | 
|  | .addConstructors(errorReporter, declaredElement, members); | 
|  | _checkForNonCovariantTypeParameterPositionInRepresentationType( | 
|  | node, declaredFragment); | 
|  | _checkForExtensionTypeRepresentationDependsOnItself( | 
|  | node, declaredFragment); | 
|  | _checkForExtensionTypeRepresentationTypeBottom(node, declaredFragment); | 
|  | _checkForExtensionTypeImplementsDeferred(node); | 
|  | _checkForExtensionTypeImplementsItself(node, declaredFragment); | 
|  | _checkForExtensionTypeMemberConflicts( | 
|  | node: node, | 
|  | element: firstFragment, | 
|  | ); | 
|  | _checkForExtensionTypeWithAbstractMember(node); | 
|  | _checkForWrongTypeParameterVarianceInSuperinterfaces(); | 
|  |  | 
|  | var interface = _inheritanceManager.getInterface(firstFragment); | 
|  | GetterSetterTypesVerifier( | 
|  | typeSystem: typeSystem, | 
|  | errorReporter: errorReporter, | 
|  | ).checkExtensionType(declaredElement, interface); | 
|  |  | 
|  | super.visitExtensionTypeDeclaration(node); | 
|  | } finally { | 
|  | _enclosingClass = null; | 
|  | } | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitFieldDeclaration(covariant FieldDeclarationImpl node) { | 
|  | var fields = node.fields; | 
|  | _isInStaticVariableDeclaration = node.isStatic; | 
|  | _isInInstanceNotLateVariableDeclaration = | 
|  | !node.isStatic && !node.fields.isLate; | 
|  | if (!_isInStaticVariableDeclaration) { | 
|  | if (fields.isConst) { | 
|  | errorReporter.atToken( | 
|  | fields.keyword!, | 
|  | CompileTimeErrorCode.CONST_INSTANCE_FIELD, | 
|  | ); | 
|  | } | 
|  | } | 
|  | var oldHasAccessToThis = _hasAccessToThis; | 
|  | try { | 
|  | _hasAccessToThis = !node.isStatic && node.fields.isLate; | 
|  | _checkForExtensionDeclaresInstanceField(node); | 
|  | _checkForExtensionTypeDeclaresInstanceField(node); | 
|  | _checkForNotInitializedNonNullableStaticField(node); | 
|  | _checkForWrongTypeParameterVarianceInField(node); | 
|  | _checkForLateFinalFieldWithConstConstructor(node); | 
|  | _checkForNonFinalFieldInEnum(node); | 
|  |  | 
|  | super.visitFieldDeclaration(node); | 
|  | } finally { | 
|  | _isInStaticVariableDeclaration = false; | 
|  | _isInInstanceNotLateVariableDeclaration = false; | 
|  | _hasAccessToThis = oldHasAccessToThis; | 
|  | } | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitFieldFormalParameter(FieldFormalParameter node) { | 
|  | _checkForValidField(node); | 
|  | _checkForPrivateOptionalParameter(node); | 
|  | _checkForFieldInitializingFormalRedirectingConstructor(node); | 
|  | _checkForTypeAnnotationDeferredClass(node.type); | 
|  | var fieldElement = node.declaredFragment?.element.field2; | 
|  | if (fieldElement != null) { | 
|  | _checkForAbstractOrExternalFieldConstructorInitializer( | 
|  | node.name, fieldElement); | 
|  | } | 
|  | super.visitFieldFormalParameter(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) { | 
|  | DeclaredIdentifier loopVariable = node.loopVariable; | 
|  | if (_checkForEachParts(node, loopVariable.declaredFragment?.element)) { | 
|  | if (loopVariable.isConst) { | 
|  | errorReporter.atToken( | 
|  | loopVariable.keyword!, | 
|  | CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE, | 
|  | ); | 
|  | } | 
|  | } | 
|  | super.visitForEachPartsWithDeclaration(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) { | 
|  | SimpleIdentifier identifier = node.identifier; | 
|  | if (_checkForEachParts(node, identifier.element)) { | 
|  | _checkForAssignmentToFinal(identifier); | 
|  | } | 
|  | super.visitForEachPartsWithIdentifier(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitFormalParameterList(covariant FormalParameterListImpl node) { | 
|  | _duplicateDefinitionVerifier.checkParameters(node); | 
|  | _checkUseOfCovariantInParameters(node); | 
|  | _checkUseOfDefaultValuesInParameters(node); | 
|  | super.visitFormalParameterList(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitForPartsWithDeclarations( | 
|  | covariant ForPartsWithDeclarationsImpl node) { | 
|  | _duplicateDefinitionVerifier.checkForVariables(node.variables); | 
|  | super.visitForPartsWithDeclarations(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitFunctionDeclaration(covariant FunctionDeclarationImpl node) { | 
|  | var fragment = node.declaredFragment!; | 
|  | var element = fragment.element; | 
|  | if (element.enclosingElement2 is! LibraryElement2) { | 
|  | _hiddenElements!.declare(element); | 
|  | } | 
|  |  | 
|  | _withEnclosingExecutable( | 
|  | element, | 
|  | () { | 
|  | TypeAnnotation? returnType = node.returnType; | 
|  | if (node.isSetter) { | 
|  | FunctionExpression functionExpression = node.functionExpression; | 
|  | _checkForWrongNumberOfParametersForSetter( | 
|  | node.name, functionExpression.parameters); | 
|  | _checkForNonVoidReturnTypeForSetter(returnType); | 
|  | } | 
|  | _checkForTypeAnnotationDeferredClass(returnType); | 
|  | _returnTypeVerifier.verifyReturnType(returnType); | 
|  | _checkForMainFunction1(node.name, fragment); | 
|  | _checkForMainFunction2(node); | 
|  | super.visitFunctionDeclaration(node); | 
|  | }, | 
|  | isAsynchronous: fragment.isAsynchronous, | 
|  | isGenerator: fragment.isGenerator, | 
|  | ); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitFunctionExpression(covariant FunctionExpressionImpl node) { | 
|  | _isInLateLocalVariable.add(false); | 
|  |  | 
|  | if (node.parent is FunctionDeclarationImpl) { | 
|  | super.visitFunctionExpression(node); | 
|  | } else { | 
|  | var fragment = node.declaredFragment!; | 
|  | _withEnclosingExecutable( | 
|  | fragment.element, | 
|  | () { | 
|  | super.visitFunctionExpression(node); | 
|  | }, | 
|  | isAsynchronous: fragment.isAsynchronous, | 
|  | isGenerator: fragment.isGenerator, | 
|  | ); | 
|  | } | 
|  |  | 
|  | _isInLateLocalVariable.removeLast(); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { | 
|  | var functionExpression = node.function; | 
|  |  | 
|  | if (functionExpression is ExtensionOverride) { | 
|  | return super.visitFunctionExpressionInvocation(node); | 
|  | } | 
|  |  | 
|  | _typeArgumentsVerifier.checkFunctionExpressionInvocation(node); | 
|  | _requiredParametersVerifier.visitFunctionExpressionInvocation(node); | 
|  | _constArgumentsVerifier.visitFunctionExpressionInvocation(node); | 
|  | _checkUseVerifier.checkFunctionExpressionInvocation(node); | 
|  | super.visitFunctionExpressionInvocation(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitFunctionReference(FunctionReference node) { | 
|  | _typeArgumentsVerifier.checkFunctionReference(node); | 
|  | super.visitFunctionReference(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitFunctionTypeAlias(covariant FunctionTypeAliasImpl node) { | 
|  | _checkForBuiltInIdentifierAsName( | 
|  | node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME); | 
|  | _checkForMainFunction1(node.name, node.declaredFragment!); | 
|  | _checkForTypeAliasCannotReferenceItself( | 
|  | node.name, node.declaredFragment as TypeAliasElementImpl); | 
|  | super.visitFunctionTypeAlias(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { | 
|  | bool old = _isInFunctionTypedFormalParameter; | 
|  | _isInFunctionTypedFormalParameter = true; | 
|  | try { | 
|  | _checkForTypeAnnotationDeferredClass(node.returnType); | 
|  |  | 
|  | super.visitFunctionTypedFormalParameter(node); | 
|  | } finally { | 
|  | _isInFunctionTypedFormalParameter = old; | 
|  | } | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitGenericTypeAlias(covariant GenericTypeAliasImpl node) { | 
|  | var fragment = node.declaredFragment!; | 
|  |  | 
|  | _checkForBuiltInIdentifierAsName( | 
|  | node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME); | 
|  | _checkForMainFunction1(node.name, node.declaredFragment!); | 
|  | _checkForTypeAliasCannotReferenceItself(node.name, fragment); | 
|  | super.visitGenericTypeAlias(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitGuardedPattern(covariant GuardedPatternImpl node) { | 
|  | _withHiddenElementsGuardedPattern(node, () { | 
|  | node.pattern.accept(this); | 
|  | }); | 
|  | node.whenClause?.accept(this); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitImportDirective(ImportDirective node) { | 
|  | var importElement = node.libraryImport; | 
|  | if (node.prefix != null) { | 
|  | _checkForBuiltInIdentifierAsName(node.prefix!.token, | 
|  | CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_PREFIX_NAME); | 
|  | } | 
|  | if (importElement != null) { | 
|  | _checkForImportInternalLibrary(node, importElement); | 
|  | if (importElement.prefix2?.isDeferred ?? false) { | 
|  | _checkForDeferredImportOfExtensions(node, importElement); | 
|  | } | 
|  | } | 
|  |  | 
|  | _reportForMultipleCombinators(node); | 
|  | super.visitImportDirective(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitImportPrefixReference(ImportPrefixReference node) { | 
|  | _checkForReferenceBeforeDeclaration( | 
|  | nameToken: node.name, | 
|  | element: node.element2, | 
|  | ); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitIndexExpression(IndexExpression node) { | 
|  | if (node.isNullAware) { | 
|  | _checkForUnnecessaryNullAware( | 
|  | node.realTarget, | 
|  | node.question ?? node.period ?? node.leftBracket, | 
|  | ); | 
|  | } | 
|  |  | 
|  | super.visitIndexExpression(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitInstanceCreationExpression(InstanceCreationExpression node) { | 
|  | ConstructorName constructorName = node.constructorName; | 
|  | NamedType namedType = constructorName.type; | 
|  | DartType type = namedType.typeOrThrow; | 
|  | if (type is InterfaceType) { | 
|  | _checkForConstOrNewWithAbstractClass(node, namedType, type); | 
|  | _checkForInvalidGenerativeConstructorReference(constructorName); | 
|  | _checkForConstOrNewWithMixin(node, namedType, type); | 
|  | _requiredParametersVerifier.visitInstanceCreationExpression(node); | 
|  | _constArgumentsVerifier.visitInstanceCreationExpression(node); | 
|  | _checkUseVerifier.checkInstanceCreationExpression(node); | 
|  | if (node.isConst) { | 
|  | _checkForConstWithNonConst(node); | 
|  | _checkForConstWithUndefinedConstructor( | 
|  | node, constructorName, namedType); | 
|  | _checkForConstDeferredClass(node, constructorName, namedType); | 
|  | } else { | 
|  | _checkForNewWithUndefinedConstructor(node, constructorName, namedType); | 
|  | } | 
|  | } | 
|  | super.visitInstanceCreationExpression(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitIntegerLiteral(covariant IntegerLiteralImpl node) { | 
|  | _checkForOutOfRange(node); | 
|  | super.visitIntegerLiteral(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitInterpolationExpression(InterpolationExpression node) { | 
|  | checkForUseOfVoidResult(node.expression); | 
|  | super.visitInterpolationExpression(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitIsExpression(IsExpression node) { | 
|  | _checkForTypeAnnotationDeferredClass(node.type); | 
|  | checkForUseOfVoidResult(node.expression); | 
|  | super.visitIsExpression(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitListLiteral(ListLiteral node) { | 
|  | _typeArgumentsVerifier.checkListLiteral(node); | 
|  | _checkForListElementTypeNotAssignable(node); | 
|  |  | 
|  | super.visitListLiteral(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitMapLiteralEntry(MapLiteralEntry node) { | 
|  | if (node.keyQuestion != null) { | 
|  | _checkForUnnecessaryNullAware(node.key, node.keyQuestion!, | 
|  | nullAwareElementOrMapEntryKind: | 
|  | _NullAwareElementOrMapEntryKind.mapEntryKey); | 
|  | } | 
|  | if (node.valueQuestion != null) { | 
|  | _checkForUnnecessaryNullAware(node.value, node.valueQuestion!, | 
|  | nullAwareElementOrMapEntryKind: | 
|  | _NullAwareElementOrMapEntryKind.mapEntryValue); | 
|  | } | 
|  | super.visitMapLiteralEntry(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitMethodDeclaration(covariant MethodDeclarationImpl node) { | 
|  | var fragment = node.declaredFragment!; | 
|  | _withEnclosingExecutable( | 
|  | fragment.element, | 
|  | () { | 
|  | var returnType = node.returnType; | 
|  | if (node.isSetter) { | 
|  | _checkForWrongNumberOfParametersForSetter(node.name, node.parameters); | 
|  | _checkForNonVoidReturnTypeForSetter(returnType); | 
|  | } else if (node.isOperator) { | 
|  | var hasWrongNumberOfParameters = | 
|  | _checkForWrongNumberOfParametersForOperator(node); | 
|  | if (!hasWrongNumberOfParameters) { | 
|  | // If the operator has too many parameters including one or more | 
|  | // optional parameters, only report one error. | 
|  | _checkForOptionalParameterInOperator(node); | 
|  | } | 
|  | _checkForNonVoidReturnTypeForOperator(node); | 
|  | } | 
|  | _checkForExtensionDeclaresMemberOfObject(node); | 
|  | _checkForTypeAnnotationDeferredClass(returnType); | 
|  | _returnTypeVerifier.verifyReturnType(returnType); | 
|  | _checkForWrongTypeParameterVarianceInMethod(node); | 
|  | super.visitMethodDeclaration(node); | 
|  | }, | 
|  | isAsynchronous: fragment.isAsynchronous, | 
|  | isGenerator: fragment.isGenerator, | 
|  | ); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitMethodInvocation(MethodInvocation node) { | 
|  | var target = node.realTarget; | 
|  | SimpleIdentifier methodName = node.methodName; | 
|  | if (target != null) { | 
|  | var typeReference = getTypeReference(target); | 
|  | _checkForStaticAccessToInstanceMember(typeReference, methodName); | 
|  | _checkForInstanceAccessToStaticMember( | 
|  | typeReference, node.target, methodName); | 
|  | _checkForUnnecessaryNullAware(target, node.operator!); | 
|  | } else { | 
|  | _checkForUnqualifiedReferenceToNonLocalStaticMember(methodName); | 
|  | } | 
|  | _typeArgumentsVerifier.checkMethodInvocation(node); | 
|  | _requiredParametersVerifier.visitMethodInvocation(node); | 
|  | _constArgumentsVerifier.visitMethodInvocation(node); | 
|  | _checkUseVerifier.checkMethodInvocation(node); | 
|  | super.visitMethodInvocation(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitMixinDeclaration(covariant MixinDeclarationImpl node) { | 
|  | // TODO(scheglov): Verify for all mixin errors. | 
|  | try { | 
|  | var declaredFragment = node.declaredFragment!; | 
|  | var declaredElement = declaredFragment.element; | 
|  | var firstFragment = declaredElement.firstFragment; | 
|  |  | 
|  | _enclosingClass = declaredElement; | 
|  |  | 
|  | List<ClassMember> members = node.members; | 
|  | _checkForBuiltInIdentifierAsName( | 
|  | node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME); | 
|  | _checkForConflictingClassTypeVariableErrorCodes(); | 
|  |  | 
|  | var onClause = node.onClause; | 
|  | var implementsClause = node.implementsClause; | 
|  |  | 
|  | // Only do error checks only if there is a non-null clause. | 
|  | if (onClause != null || implementsClause != null) { | 
|  | _checkMixinInheritance(firstFragment, node, onClause, implementsClause); | 
|  | } | 
|  |  | 
|  | _checkForConflictingClassMembers(declaredFragment); | 
|  | _checkForFinalNotInitializedInClass(declaredFragment, members); | 
|  | _checkForMainFunction1(node.name, firstFragment); | 
|  | _checkForWrongTypeParameterVarianceInSuperinterfaces(); | 
|  | //      _checkForBadFunctionUse(node); | 
|  | super.visitMixinDeclaration(node); | 
|  | } finally { | 
|  | _enclosingClass = null; | 
|  | } | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitNamedType(covariant NamedTypeImpl node) { | 
|  | _checkForAmbiguousImport( | 
|  | name: node.name2, | 
|  | element: node.element2, | 
|  | ); | 
|  | _checkForTypeParameterReferencedByStatic( | 
|  | name: node.name2, | 
|  | element: node.element2, | 
|  | ); | 
|  | _typeArgumentsVerifier.checkNamedType(node); | 
|  | super.visitNamedType(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitNativeClause(NativeClause node) { | 
|  | // TODO(brianwilkerson): Figure out the right rule for when 'native' is | 
|  | // allowed. | 
|  | if (!_isInSystemLibrary) { | 
|  | errorReporter.atNode( | 
|  | node, | 
|  | ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE, | 
|  | ); | 
|  | } | 
|  | super.visitNativeClause(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitNativeFunctionBody(NativeFunctionBody node) { | 
|  | _checkForNativeFunctionBodyInNonSdkCode(node); | 
|  | super.visitNativeFunctionBody(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitNullAwareElement(NullAwareElement node) { | 
|  | _checkForUnnecessaryNullAware(node.value, node.question, | 
|  | nullAwareElementOrMapEntryKind: | 
|  | _NullAwareElementOrMapEntryKind.element); | 
|  | super.visitNullAwareElement(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitPatternVariableDeclarationStatement( | 
|  | covariant PatternVariableDeclarationStatementImpl node, | 
|  | ) { | 
|  | super.visitPatternVariableDeclarationStatement(node); | 
|  | for (var variable in node.declaration.elements) { | 
|  | _hiddenElements?.declare(variable); | 
|  | } | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitPostfixExpression(covariant PostfixExpressionImpl node) { | 
|  | var operand = node.operand; | 
|  | if (node.operator.type == TokenType.BANG) { | 
|  | checkForUseOfVoidResult(node); | 
|  | _checkForUnnecessaryNullAware(operand, node.operator); | 
|  | } else { | 
|  | _checkForAssignmentToFinal(operand); | 
|  | _checkForIntNotAssignable(operand); | 
|  | } | 
|  | super.visitPostfixExpression(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitPrefixedIdentifier(PrefixedIdentifier node) { | 
|  | if (node.parent is! Annotation) { | 
|  | var typeReference = getTypeReference(node.prefix); | 
|  | SimpleIdentifier name = node.identifier; | 
|  | _checkForStaticAccessToInstanceMember(typeReference, name); | 
|  | _checkForInstanceAccessToStaticMember(typeReference, node.prefix, name); | 
|  | } | 
|  | super.visitPrefixedIdentifier(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitPrefixExpression(covariant PrefixExpressionImpl node) { | 
|  | var operatorType = node.operator.type; | 
|  | var operand = node.operand; | 
|  | if (operatorType != TokenType.BANG) { | 
|  | if (operatorType.isIncrementOperator) { | 
|  | _checkForAssignmentToFinal(operand); | 
|  | } | 
|  | checkForUseOfVoidResult(operand); | 
|  | _checkForIntNotAssignable(operand); | 
|  | } | 
|  | super.visitPrefixExpression(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitPropertyAccess(PropertyAccess node) { | 
|  | var target = node.realTarget; | 
|  | var typeReference = getTypeReference(target); | 
|  | SimpleIdentifier propertyName = node.propertyName; | 
|  | _checkForStaticAccessToInstanceMember(typeReference, propertyName); | 
|  | _checkForInstanceAccessToStaticMember( | 
|  | typeReference, node.target, propertyName); | 
|  | _checkForUnnecessaryNullAware(target, node.operator); | 
|  | _checkUseVerifier.checkPropertyAccess(node); | 
|  | super.visitPropertyAccess(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitRedirectingConstructorInvocation( | 
|  | RedirectingConstructorInvocation node) { | 
|  | _requiredParametersVerifier.visitRedirectingConstructorInvocation(node); | 
|  | _constArgumentsVerifier.visitRedirectingConstructorInvocation(node); | 
|  | _isInConstructorInitializer = true; | 
|  | try { | 
|  | super.visitRedirectingConstructorInvocation(node); | 
|  | } finally { | 
|  | _isInConstructorInitializer = false; | 
|  | } | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitRethrowExpression(RethrowExpression node) { | 
|  | _checkForRethrowOutsideCatch(node); | 
|  | super.visitRethrowExpression(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitReturnStatement(ReturnStatement node) { | 
|  | if (node.expression == null) { | 
|  | _enclosingExecutable._returnsWithout.add(node); | 
|  | } else { | 
|  | _enclosingExecutable._returnsWith.add(node); | 
|  | } | 
|  | _returnTypeVerifier.verifyReturnStatement(node); | 
|  | super.visitReturnStatement(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitSetOrMapLiteral(SetOrMapLiteral node) { | 
|  | if (node.isMap) { | 
|  | _typeArgumentsVerifier.checkMapLiteral(node); | 
|  | _checkForMapTypeNotAssignable(node); | 
|  | _checkForNonConstMapAsExpressionStatement3(node); | 
|  | } else if (node.isSet) { | 
|  | _typeArgumentsVerifier.checkSetLiteral(node); | 
|  | _checkForSetElementTypeNotAssignable3(node); | 
|  | } | 
|  | super.visitSetOrMapLiteral(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitSimpleFormalParameter(SimpleFormalParameter node) { | 
|  | _checkForPrivateOptionalParameter(node); | 
|  | _checkForTypeAnnotationDeferredClass(node.type); | 
|  | super.visitSimpleFormalParameter(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitSimpleIdentifier(SimpleIdentifier node) { | 
|  | _checkForAmbiguousImport( | 
|  | name: node.token, | 
|  | element: node.writeOrReadElement2, | 
|  | ); | 
|  | _checkForReferenceBeforeDeclaration( | 
|  | nameToken: node.token, | 
|  | element: node.element, | 
|  | ); | 
|  | _checkForInvalidInstanceMemberAccess(node); | 
|  | _checkForTypeParameterReferencedByStatic( | 
|  | name: node.token, | 
|  | element: node.element, | 
|  | ); | 
|  | if (!_isUnqualifiedReferenceToNonLocalStaticMemberAllowed(node)) { | 
|  | _checkForUnqualifiedReferenceToNonLocalStaticMember(node); | 
|  | } | 
|  | _checkUseVerifier.checkSimpleIdentifier(node); | 
|  | super.visitSimpleIdentifier(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitSpreadElement(SpreadElement node) { | 
|  | if (node.isNullAware) { | 
|  | _checkForUnnecessaryNullAware(node.expression, node.spreadOperator); | 
|  | } | 
|  | super.visitSpreadElement(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitSuperConstructorInvocation(SuperConstructorInvocation node) { | 
|  | _requiredParametersVerifier.visitSuperConstructorInvocation( | 
|  | node, | 
|  | enclosingConstructor: _enclosingExecutable.element.ifTypeOrNull(), | 
|  | ); | 
|  | _constArgumentsVerifier.visitSuperConstructorInvocation(node); | 
|  | _isInConstructorInitializer = true; | 
|  | try { | 
|  | _checkForExtensionTypeConstructorWithSuperInvocation(node); | 
|  | super.visitSuperConstructorInvocation(node); | 
|  | } finally { | 
|  | _isInConstructorInitializer = false; | 
|  | } | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitSuperFormalParameter(SuperFormalParameter node) { | 
|  | super.visitSuperFormalParameter(node); | 
|  |  | 
|  | if (_enclosingClass is ExtensionTypeElement2) { | 
|  | errorReporter.atToken( | 
|  | node.superKeyword, | 
|  | CompileTimeErrorCode | 
|  | .EXTENSION_TYPE_CONSTRUCTOR_WITH_SUPER_FORMAL_PARAMETER, | 
|  | ); | 
|  | return; | 
|  | } | 
|  |  | 
|  | var constructor = node.parentFormalParameterList.parent; | 
|  | if (!(constructor is ConstructorDeclaration && | 
|  | constructor.isNonRedirectingGenerative)) { | 
|  | errorReporter.atToken( | 
|  | node.superKeyword, | 
|  | CompileTimeErrorCode.INVALID_SUPER_FORMAL_PARAMETER_LOCATION, | 
|  | ); | 
|  | return; | 
|  | } | 
|  |  | 
|  | var element = | 
|  | node.declaredFragment?.element as SuperFormalParameterElementImpl2; | 
|  | var superParameter = element.superConstructorParameter2; | 
|  |  | 
|  | if (superParameter == null) { | 
|  | errorReporter.atToken( | 
|  | node.name, | 
|  | node.isNamed | 
|  | ? CompileTimeErrorCode | 
|  | .SUPER_FORMAL_PARAMETER_WITHOUT_ASSOCIATED_NAMED | 
|  | : CompileTimeErrorCode | 
|  | .SUPER_FORMAL_PARAMETER_WITHOUT_ASSOCIATED_POSITIONAL, | 
|  | ); | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (!_currentLibrary.typeSystem | 
|  | .isSubtypeOf(element.type, superParameter.type)) { | 
|  | errorReporter.atToken( | 
|  | node.name, | 
|  | CompileTimeErrorCode | 
|  | .SUPER_FORMAL_PARAMETER_TYPE_IS_NOT_SUBTYPE_OF_ASSOCIATED, | 
|  | arguments: [element.type, superParameter.type], | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitSwitchCase(covariant SwitchCaseImpl node) { | 
|  | _withHiddenElements(node.statements, () { | 
|  | _duplicateDefinitionVerifier.checkStatements(node.statements); | 
|  | super.visitSwitchCase(node); | 
|  | }); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitSwitchDefault(covariant SwitchDefaultImpl node) { | 
|  | _withHiddenElements(node.statements, () { | 
|  | _duplicateDefinitionVerifier.checkStatements(node.statements); | 
|  | super.visitSwitchDefault(node); | 
|  | }); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitSwitchExpression(SwitchExpression node) { | 
|  | checkForUseOfVoidResult(node.expression); | 
|  | super.visitSwitchExpression(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitSwitchPatternCase(covariant SwitchPatternCaseImpl node) { | 
|  | _withHiddenElements(node.statements, () { | 
|  | _duplicateDefinitionVerifier.checkStatements(node.statements); | 
|  | super.visitSwitchPatternCase(node); | 
|  | }); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitSwitchStatement(SwitchStatement node) { | 
|  | checkForUseOfVoidResult(node.expression); | 
|  | _checkForMissingEnumConstantInSwitch(node); | 
|  | super.visitSwitchStatement(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitThisExpression(ThisExpression node) { | 
|  | _checkForInvalidReferenceToThis(node); | 
|  | super.visitThisExpression(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitThrowExpression(ThrowExpression node) { | 
|  | _checkForConstEvalThrowsException(node); | 
|  | checkForUseOfVoidResult(node.expression); | 
|  | _checkForThrowOfInvalidType(node); | 
|  | super.visitThrowExpression(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { | 
|  | _checkForFinalNotInitialized(node.variables); | 
|  | _checkForNotInitializedNonNullableVariable(node.variables, true); | 
|  |  | 
|  | for (var variable in node.variables.variables) { | 
|  | var fragment = variable.declaredFragment; | 
|  | fragment as TopLevelVariableElementImpl; | 
|  | _checkForMainFunction1(variable.name, fragment); | 
|  | } | 
|  |  | 
|  | super.visitTopLevelVariableDeclaration(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitTypeArgumentList(TypeArgumentList node) { | 
|  | NodeList<TypeAnnotation> list = node.arguments; | 
|  | for (TypeAnnotation type in list) { | 
|  | _checkForTypeAnnotationDeferredClass(type); | 
|  | } | 
|  | super.visitTypeArgumentList(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitTypeParameter(TypeParameter node) { | 
|  | _checkForBuiltInIdentifierAsName(node.name, | 
|  | CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME); | 
|  | _checkForTypeAnnotationDeferredClass(node.bound); | 
|  | _checkForGenericFunctionType(node.bound); | 
|  | node.bound?.accept(_uninstantiatedBoundChecker); | 
|  | super.visitTypeParameter(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitTypeParameterList(covariant TypeParameterListImpl node) { | 
|  | _duplicateDefinitionVerifier.checkTypeParameters(node); | 
|  | _checkForTypeParameterBoundRecursion(node.typeParameters); | 
|  | super.visitTypeParameterList(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitVariableDeclaration(VariableDeclaration node) { | 
|  | var nameToken = node.name; | 
|  | var initializerNode = node.initializer; | 
|  | // do checks | 
|  | _checkForAbstractOrExternalVariableInitializer(node); | 
|  | // visit initializer | 
|  | String name = nameToken.lexeme; | 
|  | _namesForReferenceToDeclaredVariableInInitializer.add(name); | 
|  | try { | 
|  | if (initializerNode != null) { | 
|  | initializerNode.accept(this); | 
|  | } | 
|  | } finally { | 
|  | _namesForReferenceToDeclaredVariableInInitializer.remove(name); | 
|  | } | 
|  | // declare the variable | 
|  | AstNode grandparent = node.parent!.parent!; | 
|  | if (grandparent is! TopLevelVariableDeclaration && | 
|  | grandparent is! FieldDeclaration) { | 
|  | var element = node.declaredFragment!.element; | 
|  | // There is no hidden elements if we are outside of a function body, | 
|  | // which will happen for variables declared in control flow elements. | 
|  | _hiddenElements?.declare(element); | 
|  | } | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitVariableDeclarationList(VariableDeclarationList node) { | 
|  | _checkForTypeAnnotationDeferredClass(node.type); | 
|  | super.visitVariableDeclarationList(node); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void visitVariableDeclarationStatement(VariableDeclarationStatement node) { | 
|  | _isInLateLocalVariable.add(node.variables.isLate); | 
|  |  | 
|  | _checkForFinalNotInitialized(node.variables); | 
|  | super.visitVariableDeclarationStatement(node); | 
|  |  | 
|  | _isInLateLocalVariable.removeLast(); | 
|  | } | 
|  |  | 
|  | /// Checks the class for problems with the superclass, mixins, or implemented | 
|  | /// interfaces. | 
|  | /// | 
|  | /// Returns `false` if a severe hierarchy error was found, so that further | 
|  | /// checking is not useful. | 
|  | bool _checkClassInheritance( | 
|  | InterfaceElementImpl declarationElement, | 
|  | NamedCompilationUnitMember node, | 
|  | NamedType? superclass, | 
|  | WithClauseImpl? withClause, | 
|  | ImplementsClause? implementsClause) { | 
|  | // Only check for all of the inheritance logic around clauses if there | 
|  | // isn't an error code such as "Cannot extend double" already on the | 
|  | // class. | 
|  | if (!_checkForExtendsDisallowedClass(superclass) && | 
|  | !_checkForImplementsClauseErrorCodes(implementsClause) && | 
|  | !_checkForAllMixinErrorCodes(withClause) && | 
|  | !_checkForNoGenerativeConstructorsInSuperclass(superclass)) { | 
|  | _checkForExtendsDeferredClass(superclass); | 
|  | _checkForRepeatedType( | 
|  | libraryContext.setOfImplements(declarationElement.asElement2), | 
|  | implementsClause?.interfaces, | 
|  | CompileTimeErrorCode.IMPLEMENTS_REPEATED, | 
|  | ); | 
|  | _checkImplementsSuperClass(implementsClause); | 
|  | _checkMixinsSuperClass(withClause); | 
|  | _checkForMixinWithConflictingPrivateMember(withClause, superclass); | 
|  | _checkForConflictingGenerics(node); | 
|  | _checkForBaseClassOrMixinImplementedOutsideOfLibrary(implementsClause); | 
|  | _checkForInterfaceClassOrMixinSuperclassOutsideOfLibrary( | 
|  | superclass, withClause); | 
|  | _checkForFinalSupertypeOutsideOfLibrary( | 
|  | superclass, withClause, implementsClause, null); | 
|  | _checkForClassUsedAsMixin(withClause); | 
|  | _checkForSealedSupertypeOutsideOfLibrary( | 
|  | superclass, withClause, implementsClause, null); | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /// Given a list of [directives] that have the same prefix, generate an error | 
|  | /// if there is more than one import and any of those imports is deferred. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.SHARED_DEFERRED_PREFIX]. | 
|  | void _checkDeferredPrefixCollision(List<ImportDirective> directives) { | 
|  | int count = directives.length; | 
|  | if (count > 1) { | 
|  | for (int i = 0; i < count; i++) { | 
|  | var deferredToken = directives[i].deferredKeyword; | 
|  | if (deferredToken != null) { | 
|  | errorReporter.atToken( | 
|  | deferredToken, | 
|  | CompileTimeErrorCode.SHARED_DEFERRED_PREFIX, | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForAbstractOrExternalFieldConstructorInitializer( | 
|  | Token identifier, FieldElement2 fieldElement) { | 
|  | if (fieldElement.isAbstract) { | 
|  | errorReporter.atToken( | 
|  | identifier, | 
|  | CompileTimeErrorCode.ABSTRACT_FIELD_CONSTRUCTOR_INITIALIZER, | 
|  | ); | 
|  | } | 
|  | if (fieldElement.isExternal) { | 
|  | errorReporter.atToken( | 
|  | identifier, | 
|  | CompileTimeErrorCode.EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForAbstractOrExternalVariableInitializer( | 
|  | VariableDeclaration node) { | 
|  | var declaredElement = node.declaredFragment?.element; | 
|  | if (node.initializer != null) { | 
|  | if (declaredElement is FieldElement2) { | 
|  | if (declaredElement.isAbstract) { | 
|  | errorReporter.atToken( | 
|  | node.name, | 
|  | CompileTimeErrorCode.ABSTRACT_FIELD_INITIALIZER, | 
|  | ); | 
|  | } | 
|  | if (declaredElement.isExternal) { | 
|  | errorReporter.atToken( | 
|  | node.name, | 
|  | CompileTimeErrorCode.EXTERNAL_FIELD_INITIALIZER, | 
|  | ); | 
|  | } | 
|  | } else if (declaredElement is TopLevelVariableElement2) { | 
|  | if (declaredElement.isExternal) { | 
|  | errorReporter.atToken( | 
|  | node.name, | 
|  | CompileTimeErrorCode.EXTERNAL_VARIABLE_INITIALIZER, | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that all classes of the given [withClause] are valid. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.MIXIN_CLASS_DECLARES_CONSTRUCTOR], | 
|  | /// [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]. | 
|  | bool _checkForAllMixinErrorCodes(WithClauseImpl? withClause) { | 
|  | if (withClause == null) { | 
|  | return false; | 
|  | } | 
|  | bool problemReported = false; | 
|  | int mixinTypeIndex = -1; | 
|  | for (int mixinNameIndex = 0; | 
|  | mixinNameIndex < withClause.mixinTypes.length; | 
|  | mixinNameIndex++) { | 
|  | var mixinName = withClause.mixinTypes[mixinNameIndex]; | 
|  | DartType mixinType = mixinName.typeOrThrow; | 
|  | if (mixinType is InterfaceType) { | 
|  | mixinTypeIndex++; | 
|  | if (_checkForExtendsOrImplementsDisallowedClass( | 
|  | mixinName, CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS)) { | 
|  | problemReported = true; | 
|  | } else { | 
|  | var mixinElement = mixinType.element3; | 
|  | if (_checkForExtendsOrImplementsDeferredClass( | 
|  | mixinName, CompileTimeErrorCode.MIXIN_DEFERRED_CLASS)) { | 
|  | problemReported = true; | 
|  | } | 
|  | if (mixinType.element3 is ExtensionTypeElement2) { | 
|  | // Already reported. | 
|  | } else if (mixinElement is MixinElement2) { | 
|  | if (_checkForMixinSuperclassConstraints( | 
|  | mixinNameIndex, mixinName)) { | 
|  | problemReported = true; | 
|  | } else if (_checkForMixinSuperInvokedMembers( | 
|  | mixinTypeIndex, mixinName, mixinElement, mixinType)) { | 
|  | problemReported = true; | 
|  | } | 
|  | } else { | 
|  | bool isMixinClass = | 
|  | mixinElement is ClassElementImpl2 && mixinElement.isMixinClass; | 
|  | if (!isMixinClass && | 
|  | _checkForMixinClassDeclaresConstructor( | 
|  | mixinName, mixinElement)) { | 
|  | problemReported = true; | 
|  | } | 
|  | if (_checkForMixinInheritsNotFromObject(mixinName, mixinElement)) { | 
|  | problemReported = true; | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | return problemReported; | 
|  | } | 
|  |  | 
|  | /// Check for errors related to the redirected constructors. | 
|  | void _checkForAllRedirectConstructorErrorCodes( | 
|  | ConstructorDeclarationImpl declaration) { | 
|  | // Prepare redirected constructor node | 
|  | var redirectedConstructor = declaration.redirectedConstructor; | 
|  | if (redirectedConstructor == null) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | // Prepare redirected constructor type | 
|  | var redirectedElement = redirectedConstructor.element; | 
|  | if (redirectedElement == null) { | 
|  | // If the element is null, we check for the | 
|  | // REDIRECT_TO_MISSING_CONSTRUCTOR case | 
|  | NamedType constructorNamedType = redirectedConstructor.type; | 
|  | DartType redirectedType = constructorNamedType.typeOrThrow; | 
|  | if (!(redirectedType is DynamicType || redirectedType is InvalidType)) { | 
|  | // Prepare the constructor name | 
|  | String constructorStrName = constructorNamedType.qualifiedName; | 
|  | if (redirectedConstructor.name != null) { | 
|  | constructorStrName += ".${redirectedConstructor.name!.name}"; | 
|  | } | 
|  | errorReporter.atNode( | 
|  | redirectedConstructor, | 
|  | CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR, | 
|  | arguments: [constructorStrName, redirectedType], | 
|  | ); | 
|  | } | 
|  | return; | 
|  | } | 
|  | var redirectedType = redirectedElement.type; | 
|  | var redirectedReturnType = redirectedType.returnType; | 
|  |  | 
|  | // Report specific problem when return type is incompatible | 
|  | var constructorType = declaration.declaredFragment!.element.type; | 
|  | var constructorReturnType = constructorType.returnType; | 
|  | if (!typeSystem.isAssignableTo(redirectedReturnType, constructorReturnType, | 
|  | strictCasts: strictCasts)) { | 
|  | errorReporter.atNode( | 
|  | redirectedConstructor, | 
|  | CompileTimeErrorCode.REDIRECT_TO_INVALID_RETURN_TYPE, | 
|  | arguments: [redirectedReturnType, constructorReturnType], | 
|  | ); | 
|  | return; | 
|  | } else if (!typeSystem.isSubtypeOf(redirectedType, constructorType)) { | 
|  | // Check parameters. | 
|  | errorReporter.atNode( | 
|  | redirectedConstructor, | 
|  | CompileTimeErrorCode.REDIRECT_TO_INVALID_FUNCTION_TYPE, | 
|  | arguments: [redirectedType, constructorType], | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that the export namespace of the given export [directive] does not | 
|  | /// export any name already exported by another export directive. The | 
|  | /// [libraryExport] is the [LibraryExport] retrieved from the node. If the | 
|  | /// element in the node was `null`, then this method is not called. The | 
|  | /// [exportedLibrary] is the library element containing the exported element. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.AMBIGUOUS_EXPORT]. | 
|  | void _checkForAmbiguousExport( | 
|  | ExportDirectiveImpl directive, | 
|  | LibraryExportElementImpl libraryExport, | 
|  | LibraryElementImpl? exportedLibrary) { | 
|  | if (exportedLibrary == null) { | 
|  | return; | 
|  | } | 
|  | // check exported names | 
|  | Namespace namespace = | 
|  | NamespaceBuilder().createExportNamespaceForDirective2(libraryExport); | 
|  | Map<String, Element2> definedNames = namespace.definedNames2; | 
|  | for (String name in definedNames.keys) { | 
|  | var element = definedNames[name]!; | 
|  | var prevElement = libraryContext._exportedElements[name]; | 
|  | if (prevElement != null && prevElement != element) { | 
|  | errorReporter.atNode( | 
|  | directive.uri, | 
|  | CompileTimeErrorCode.AMBIGUOUS_EXPORT, | 
|  | arguments: [name, prevElement.library2!.uri, element.library2!.uri], | 
|  | ); | 
|  | return; | 
|  | } else { | 
|  | libraryContext._exportedElements[name] = element; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Check the given node to see whether it was ambiguous because the name was | 
|  | /// imported from two or more imports. | 
|  | void _checkForAmbiguousImport({ | 
|  | required Token name, | 
|  | required Element2? element, | 
|  | }) { | 
|  | if (element is MultiplyDefinedElementImpl2) { | 
|  | var conflictingMembers = element.conflictingElements2; | 
|  | var libraryNames = | 
|  | conflictingMembers.map((e) => _getLibraryName(e)).toList(); | 
|  | libraryNames.sort(); | 
|  | errorReporter.atToken( | 
|  | name, | 
|  | CompileTimeErrorCode.AMBIGUOUS_IMPORT, | 
|  | arguments: [name.lexeme, libraryNames.quotedAndCommaSeparatedWithAnd], | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that the given [expression] is not final. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.ASSIGNMENT_TO_CONST], | 
|  | /// [CompileTimeErrorCode.ASSIGNMENT_TO_FINAL], and | 
|  | /// [CompileTimeErrorCode.ASSIGNMENT_TO_METHOD]. | 
|  | void _checkForAssignmentToFinal(Expression expression) { | 
|  | // TODO(scheglov): Check SimpleIdentifier(s) as all other nodes. | 
|  | if (expression is! SimpleIdentifier) return; | 
|  |  | 
|  | // Already handled in the assignment resolver. | 
|  | if (expression.parent is AssignmentExpression) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | // prepare element | 
|  | var highlightedNode = expression; | 
|  | var element = expression.element?.asElement; | 
|  | if (expression is PrefixedIdentifier) { | 
|  | var prefixedIdentifier = expression as PrefixedIdentifier; | 
|  | highlightedNode = prefixedIdentifier.identifier; | 
|  | } | 
|  | // check if element is assignable | 
|  | if (element is VariableElement) { | 
|  | if (element.isConst) { | 
|  | errorReporter.atNode( | 
|  | expression, | 
|  | CompileTimeErrorCode.ASSIGNMENT_TO_CONST, | 
|  | ); | 
|  | } | 
|  | } else if (element is PropertyAccessorElement && element.isGetter) { | 
|  | var variable = element.variable2; | 
|  | if (variable == null) { | 
|  | return; | 
|  | } | 
|  | if (variable.isConst) { | 
|  | errorReporter.atNode( | 
|  | expression, | 
|  | CompileTimeErrorCode.ASSIGNMENT_TO_CONST, | 
|  | ); | 
|  | } else if (variable is FieldElement && variable.isSynthetic) { | 
|  | errorReporter.atNode( | 
|  | highlightedNode, | 
|  | CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_NO_SETTER, | 
|  | arguments: [variable.name, variable.enclosingElement3.displayName], | 
|  | ); | 
|  | } else { | 
|  | errorReporter.atNode( | 
|  | highlightedNode, | 
|  | CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, | 
|  | arguments: [variable.name], | 
|  | ); | 
|  | } | 
|  | } else if (element is FunctionElement) { | 
|  | errorReporter.atNode( | 
|  | expression, | 
|  | CompileTimeErrorCode.ASSIGNMENT_TO_FUNCTION, | 
|  | ); | 
|  | } else if (element is MethodElement) { | 
|  | errorReporter.atNode( | 
|  | expression, | 
|  | CompileTimeErrorCode.ASSIGNMENT_TO_METHOD, | 
|  | ); | 
|  | } else if (element is InterfaceElement || | 
|  | element is DynamicElementImpl || | 
|  | element is TypeParameterElement) { | 
|  | errorReporter.atNode( | 
|  | expression, | 
|  | CompileTimeErrorCode.ASSIGNMENT_TO_TYPE, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForAwaitInLateLocalVariableInitializer(AwaitExpression node) { | 
|  | if (_isInLateLocalVariable.last) { | 
|  | errorReporter.atToken( | 
|  | node.awaitKeyword, | 
|  | CompileTimeErrorCode.AWAIT_IN_LATE_LOCAL_VARIABLE_INITIALIZER, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForAwaitOfIncompatibleType(AwaitExpression node) { | 
|  | var expression = node.expression; | 
|  | var expressionType = expression.typeOrThrow; | 
|  | if (typeSystem.isIncompatibleWithAwait(expressionType)) { | 
|  | errorReporter.atToken( | 
|  | node.awaitKeyword, | 
|  | CompileTimeErrorCode.AWAIT_OF_INCOMPATIBLE_TYPE, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verifies that the nodes don't reference `Function` from `dart:core`. | 
|  | void _checkForBadFunctionUse({ | 
|  | required NamedType? superclass, | 
|  | required ImplementsClause? implementsClause, | 
|  | required WithClause? withClause, | 
|  | }) { | 
|  | // With the `class_modifiers` feature `Function` is final. | 
|  | if (_featureSet!.isEnabled(Feature.class_modifiers)) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (superclass != null) { | 
|  | var type = superclass.type; | 
|  | if (type != null && type.isDartCoreFunction) { | 
|  | errorReporter.atNode( | 
|  | superclass, | 
|  | WarningCode.DEPRECATED_EXTENDS_FUNCTION, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | if (implementsClause != null) { | 
|  | for (var interface in implementsClause.interfaces) { | 
|  | var type = interface.type; | 
|  | if (type != null && type.isDartCoreFunction) { | 
|  | errorReporter.atNode( | 
|  | interface, | 
|  | WarningCode.DEPRECATED_IMPLEMENTS_FUNCTION, | 
|  | ); | 
|  | break; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | if (withClause != null) { | 
|  | for (NamedType mixin in withClause.mixinTypes) { | 
|  | var type = mixin.type; | 
|  | if (type != null && type.isDartCoreFunction) { | 
|  | errorReporter.atNode( | 
|  | mixin, | 
|  | WarningCode.DEPRECATED_MIXIN_FUNCTION, | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that if a class is implementing a base class or mixin, it must be | 
|  | /// within the same library as that class or mixin. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.BASE_CLASS_IMPLEMENTED_OUTSIDE_OF_LIBRARY], | 
|  | /// [CompileTimeErrorCode.BASE_MIXIN_IMPLEMENTED_OUTSIDE_OF_LIBRARY]. | 
|  | void _checkForBaseClassOrMixinImplementedOutsideOfLibrary( | 
|  | ImplementsClause? implementsClause) { | 
|  | if (implementsClause == null) return; | 
|  | for (NamedType interface in implementsClause.interfaces) { | 
|  | var interfaceType = interface.type; | 
|  | if (interfaceType is InterfaceType) { | 
|  | var implementedInterfaces = [ | 
|  | interfaceType, | 
|  | ...interfaceType.element3.allSupertypes, | 
|  | ].map((e) => e.element3).toList(); | 
|  | for (var interfaceElement in implementedInterfaces) { | 
|  | if ((interfaceElement is ClassElementImpl2 && | 
|  | interfaceElement.isBase || | 
|  | interfaceElement is MixinElementImpl2 && | 
|  | interfaceElement.isBase) && | 
|  | interfaceElement.library2 != _currentLibrary && | 
|  | !_mayIgnoreClassModifiers(interfaceElement.library2)) { | 
|  | // Should this be combined with _checkForImplementsClauseErrorCodes | 
|  | // to avoid double errors if implementing `int`. | 
|  | if (interfaceElement is ClassElementImpl2 && | 
|  | !interfaceElement.isSealed) { | 
|  | errorReporter.atNode( | 
|  | interface, | 
|  | CompileTimeErrorCode.BASE_CLASS_IMPLEMENTED_OUTSIDE_OF_LIBRARY, | 
|  | arguments: [interfaceElement.name3!], | 
|  | ); | 
|  | } else if (interfaceElement is MixinElement2) { | 
|  | errorReporter.atNode( | 
|  | interface, | 
|  | CompileTimeErrorCode.BASE_MIXIN_IMPLEMENTED_OUTSIDE_OF_LIBRARY, | 
|  | arguments: [interfaceElement.name3!], | 
|  | ); | 
|  | } | 
|  | break; | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that the given [token] is not a keyword, and generates the | 
|  | /// given [errorCode] on the identifier if it is a keyword. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_EXTENSION_NAME], | 
|  | /// [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME], | 
|  | /// [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME], and | 
|  | /// [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]. | 
|  | void _checkForBuiltInIdentifierAsName(Token token, ErrorCode errorCode) { | 
|  | if (token.type.isKeyword && token.keyword?.isPseudo != true) { | 
|  | errorReporter.atToken( | 
|  | token, | 
|  | errorCode, | 
|  | arguments: [token.lexeme], | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that if a class is being mixed in and class modifiers are enabled | 
|  | /// in that class' library, then it must be a mixin class. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.CLASS_USED_AS_MIXIN]. | 
|  | void _checkForClassUsedAsMixin(WithClause? withClause) { | 
|  | if (withClause != null) { | 
|  | for (NamedType withMixin in withClause.mixinTypes) { | 
|  | var withType = withMixin.type; | 
|  | if (withType is InterfaceType) { | 
|  | var withElement = withType.element3; | 
|  | if (withElement is ClassElementImpl2 && | 
|  | !withElement.isMixinClass && | 
|  | withElement.library2.featureSet | 
|  | .isEnabled(Feature.class_modifiers) && | 
|  | !_mayIgnoreClassModifiers(withElement.library2)) { | 
|  | errorReporter.atNode( | 
|  | withMixin, | 
|  | CompileTimeErrorCode.CLASS_USED_AS_MIXIN, | 
|  | arguments: [withElement.name3!], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that the [_enclosingClass] does not have a method and getter pair | 
|  | /// with the same name, via inheritance. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE], | 
|  | /// [CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD], and | 
|  | /// [CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD]. | 
|  | void _checkForConflictingClassMembers(InterfaceElement fragment) { | 
|  | var enclosingClass = _enclosingClass.asElement as InterfaceElement?; | 
|  | if (enclosingClass == null) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | Uri libraryUri = _currentLibrary.source.uri; | 
|  | var conflictingDeclaredNames = <String>{}; | 
|  |  | 
|  | // method declared in the enclosing class vs. inherited getter/setter | 
|  | for (MethodElement method in fragment.methods) { | 
|  | if (method.source != _currentUnit.source) { | 
|  | continue; | 
|  | } | 
|  |  | 
|  | String name = method.name; | 
|  |  | 
|  | // find inherited property accessors | 
|  | var getter = _inheritanceManager.getInherited2( | 
|  | enclosingClass, Name(libraryUri, name)); | 
|  | var setter = _inheritanceManager.getInherited2( | 
|  | enclosingClass, Name(libraryUri, '$name=')); | 
|  |  | 
|  | if (method.isStatic) { | 
|  | void reportStaticConflict(ExecutableElement inherited) { | 
|  | errorReporter.atElement2( | 
|  | method.asElement2, | 
|  | CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, | 
|  | arguments: [ | 
|  | enclosingClass.displayName, | 
|  | name, | 
|  | inherited.enclosingElement3.displayName, | 
|  | ], | 
|  | ); | 
|  | } | 
|  |  | 
|  | if (getter != null) { | 
|  | reportStaticConflict(getter); | 
|  | continue; | 
|  | } | 
|  |  | 
|  | if (setter != null) { | 
|  | reportStaticConflict(setter); | 
|  | continue; | 
|  | } | 
|  | } | 
|  |  | 
|  | // Extension type methods preclude accessors. | 
|  | if (enclosingClass is ExtensionTypeElement) { | 
|  | continue; | 
|  | } | 
|  |  | 
|  | void reportFieldConflict(PropertyAccessorElement inherited) { | 
|  | errorReporter.atElement2( | 
|  | method.asElement2, | 
|  | CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD, | 
|  | arguments: [ | 
|  | enclosingClass.displayName, | 
|  | name, | 
|  | inherited.enclosingElement3.displayName | 
|  | ], | 
|  | ); | 
|  | } | 
|  |  | 
|  | if (getter is PropertyAccessorElementOrMember) { | 
|  | reportFieldConflict(getter); | 
|  | continue; | 
|  | } | 
|  |  | 
|  | if (setter is PropertyAccessorElementOrMember) { | 
|  | reportFieldConflict(setter); | 
|  | continue; | 
|  | } | 
|  | } | 
|  |  | 
|  | // getter declared in the enclosing class vs. inherited method | 
|  | for (PropertyAccessorElement accessor in fragment.accessors) { | 
|  | String name = accessor.displayName; | 
|  |  | 
|  | // find inherited method or property accessor | 
|  | var inherited = _inheritanceManager.getInherited2( | 
|  | enclosingClass, Name(libraryUri, name)); | 
|  | inherited ??= _inheritanceManager.getInherited2( | 
|  | enclosingClass, Name(libraryUri, '$name=')); | 
|  |  | 
|  | if (accessor.isStatic && inherited != null) { | 
|  | errorReporter.atElement2( | 
|  | accessor.asElement2, | 
|  | CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, | 
|  | arguments: [ | 
|  | enclosingClass.displayName, | 
|  | name, | 
|  | inherited.enclosingElement3.displayName, | 
|  | ], | 
|  | ); | 
|  | conflictingDeclaredNames.add(name); | 
|  | } else if (inherited is MethodElementOrMember) { | 
|  | // Extension type accessors preclude inherited accessors/methods. | 
|  | if (enclosingClass is ExtensionTypeElement) { | 
|  | continue; | 
|  | } | 
|  | errorReporter.atElement2( | 
|  | accessor.asElement2, | 
|  | CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD, | 
|  | arguments: [ | 
|  | enclosingClass.displayName, | 
|  | name, | 
|  | inherited.enclosingElement3.displayName | 
|  | ], | 
|  | ); | 
|  | conflictingDeclaredNames.add(name); | 
|  | } | 
|  | } | 
|  |  | 
|  | // Inherited method and setter with the same name. | 
|  | var inherited = _inheritanceManager.getInheritedMap2(enclosingClass); | 
|  | for (var entry in inherited.entries) { | 
|  | var method = entry.value; | 
|  | if (method is MethodElement) { | 
|  | var methodName = entry.key; | 
|  | if (conflictingDeclaredNames.contains(methodName.name)) { | 
|  | continue; | 
|  | } | 
|  | var setterName = methodName.forSetter; | 
|  | var setter = inherited[setterName]; | 
|  | if (setter is PropertyAccessorElementOrMember) { | 
|  | errorReporter.atElement2( | 
|  | enclosingClass.asElement2, | 
|  | CompileTimeErrorCode.CONFLICTING_INHERITED_METHOD_AND_SETTER, | 
|  | arguments: [ | 
|  | enclosingClass.kind.displayName, | 
|  | enclosingClass.displayName, | 
|  | methodName.name, | 
|  | ], | 
|  | contextMessages: [ | 
|  | DiagnosticMessageImpl( | 
|  | filePath: method.source.fullName, | 
|  | message: formatList( | 
|  | "The method is inherited from the {0} '{1}'.", | 
|  | [ | 
|  | method.enclosingElement3.kind.displayName, | 
|  | method.enclosingElement3.name, | 
|  | ], | 
|  | ), | 
|  | offset: method.nameOffset, | 
|  | length: method.nameLength, | 
|  | url: null, | 
|  | ), | 
|  | DiagnosticMessageImpl( | 
|  | filePath: setter.source.fullName, | 
|  | message: formatList( | 
|  | "The setter is inherited from the {0} '{1}'.", | 
|  | [ | 
|  | setter.enclosingElement3.kind.displayName, | 
|  | setter.enclosingElement3.name, | 
|  | ], | 
|  | ), | 
|  | offset: setter.nameOffset, | 
|  | length: setter.nameLength, | 
|  | url: null, | 
|  | ), | 
|  | ], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify all conflicts between type variable and enclosing class. | 
|  | void _checkForConflictingClassTypeVariableErrorCodes() { | 
|  | var enclosingClass = _enclosingClass!; | 
|  | for (TypeParameterElement2 typeParameter | 
|  | in enclosingClass.typeParameters2) { | 
|  | if (typeParameter.isWildcardVariable) continue; | 
|  |  | 
|  | var name = typeParameter.name3; | 
|  | if (name == null) continue; | 
|  |  | 
|  | // name is same as the name of the enclosing class | 
|  | if (enclosingClass.name3 == name) { | 
|  | var code = enclosingClass is MixinElement2 | 
|  | ? CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MIXIN | 
|  | : CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS; | 
|  | errorReporter.atElement2( | 
|  | typeParameter, | 
|  | code, | 
|  | arguments: [name], | 
|  | ); | 
|  | } | 
|  | // check members | 
|  | if (enclosingClass.getNamedConstructor2(name) != null || | 
|  | enclosingClass.getMethod2(name) != null || | 
|  | enclosingClass.getGetter2(name) != null || | 
|  | enclosingClass.getSetter2(name) != null) { | 
|  | var code = enclosingClass is MixinElement2 | 
|  | ? CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_MIXIN | 
|  | : CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS; | 
|  | errorReporter.atElement2( | 
|  | typeParameter, | 
|  | code, | 
|  | arguments: [name], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForConflictingEnumTypeVariableErrorCodes( | 
|  | EnumElementImpl element, | 
|  | ) { | 
|  | for (var typeParameter in element.typeParameters) { | 
|  | var name = typeParameter.name; | 
|  | // name is same as the name of the enclosing enum | 
|  | if (element.name == name) { | 
|  | errorReporter.atElement2( | 
|  | typeParameter.asElement2, | 
|  | CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_ENUM, | 
|  | arguments: [name], | 
|  | ); | 
|  | } | 
|  | // check members | 
|  | if (element.getMethod(name) != null || | 
|  | element.getGetter(name) != null || | 
|  | element.getSetter(name) != null) { | 
|  | errorReporter.atElement2( | 
|  | typeParameter.asElement2, | 
|  | CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_ENUM, | 
|  | arguments: [name], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForConflictingExtensionTypeTypeVariableErrorCodes( | 
|  | ExtensionTypeElementImpl element, | 
|  | ) { | 
|  | for (var typeParameter in element.typeParameters) { | 
|  | if (typeParameter.isWildcardVariable) continue; | 
|  |  | 
|  | var name = typeParameter.name; | 
|  | // name is same as the name of the enclosing class | 
|  | if (element.name == name) { | 
|  | errorReporter.atElement2( | 
|  | typeParameter.asElement2, | 
|  | CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_EXTENSION_TYPE, | 
|  | arguments: [name], | 
|  | ); | 
|  | } | 
|  | // check members | 
|  | if (element.getNamedConstructor(name) != null || | 
|  | element.getMethod(name) != null || | 
|  | element.getGetter(name) != null || | 
|  | element.getSetter(name) != null) { | 
|  | errorReporter.atElement2( | 
|  | typeParameter.asElement2, | 
|  | CompileTimeErrorCode | 
|  | .CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION_TYPE, | 
|  | arguments: [name], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify all conflicts between type variable and enclosing extension. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_EXTENSION], and | 
|  | /// [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION]. | 
|  | void _checkForConflictingExtensionTypeVariableErrorCodes() { | 
|  | for (TypeParameterElement2 typeParameter | 
|  | in _enclosingExtension!.typeParameters2) { | 
|  | var name = typeParameter.name3; | 
|  | if (name == null) continue; | 
|  |  | 
|  | // name is same as the name of the enclosing class | 
|  | if (_enclosingExtension!.name3 == name) { | 
|  | errorReporter.atElement2( | 
|  | typeParameter, | 
|  | CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_EXTENSION, | 
|  | arguments: [name], | 
|  | ); | 
|  | } | 
|  | // check members | 
|  | if (_enclosingExtension!.getMethod2(name) != null || | 
|  | _enclosingExtension!.getGetter2(name) != null || | 
|  | _enclosingExtension!.getSetter2(name) != null) { | 
|  | errorReporter.atElement2( | 
|  | typeParameter, | 
|  | CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION, | 
|  | arguments: [name], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForConflictingGenerics(NamedCompilationUnitMember node) { | 
|  | var fragment = node.declaredFragment as InterfaceElementImpl; | 
|  |  | 
|  | // Report only on the declaration. | 
|  | if (fragment.isAugmentation) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | var analysisSession = _currentLibrary.session; | 
|  | var errors = analysisSession.classHierarchy.errors(fragment.asElement2); | 
|  |  | 
|  | for (var error in errors) { | 
|  | if (error is IncompatibleInterfacesClassHierarchyError) { | 
|  | errorReporter.atToken( | 
|  | node.name, | 
|  | CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES, | 
|  | arguments: [ | 
|  | _enclosingClass!.kind.displayName, | 
|  | _enclosingClass!.name3!, | 
|  | error.first.getDisplayString(), | 
|  | error.second.getDisplayString(), | 
|  | ], | 
|  | ); | 
|  | } else { | 
|  | throw UnimplementedError('${error.runtimeType}'); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Check that the given constructor [declaration] has a valid combination of | 
|  | /// redirecting constructor invocation(s), super constructor invocation(s), | 
|  | /// field initializers, and assert initializers. | 
|  | void _checkForConflictingInitializerErrorCodes( | 
|  | ConstructorDeclaration declaration) { | 
|  | var enclosingClass = _enclosingClass; | 
|  | if (enclosingClass == null) { | 
|  | return; | 
|  | } | 
|  | // Count and check each redirecting initializer. | 
|  | var redirectingInitializerCount = 0; | 
|  | var superInitializerCount = 0; | 
|  | late SuperConstructorInvocation superInitializer; | 
|  | for (ConstructorInitializer initializer in declaration.initializers) { | 
|  | if (initializer is RedirectingConstructorInvocation) { | 
|  | if (redirectingInitializerCount > 0) { | 
|  | errorReporter.atNode( | 
|  | initializer, | 
|  | CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS, | 
|  | ); | 
|  | } | 
|  | if (declaration.factoryKeyword == null) { | 
|  | RedirectingConstructorInvocation invocation = initializer; | 
|  | var redirectingElement = invocation.element; | 
|  | if (redirectingElement == null) { | 
|  | String enclosingNamedType = enclosingClass.displayName; | 
|  | String constructorStrName = enclosingNamedType; | 
|  | if (invocation.constructorName != null) { | 
|  | constructorStrName += ".${invocation.constructorName!.name}"; | 
|  | } | 
|  | errorReporter.atNode( | 
|  | invocation, | 
|  | CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR, | 
|  | arguments: [constructorStrName, enclosingNamedType], | 
|  | ); | 
|  | } else { | 
|  | if (redirectingElement.isFactory) { | 
|  | errorReporter.atNode( | 
|  | initializer, | 
|  | CompileTimeErrorCode | 
|  | .REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR, | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  | // [declaration] is a redirecting constructor via a redirecting | 
|  | // initializer. | 
|  | _checkForRedirectToNonConstConstructor( | 
|  | declaration.declaredFragment!.element, | 
|  | initializer.element, | 
|  | initializer.constructorName ?? initializer.thisKeyword, | 
|  | ); | 
|  | redirectingInitializerCount++; | 
|  | } else if (initializer is SuperConstructorInvocation) { | 
|  | if (enclosingClass is EnumElement2) { | 
|  | errorReporter.atToken( | 
|  | initializer.superKeyword, | 
|  | CompileTimeErrorCode.SUPER_IN_ENUM_CONSTRUCTOR, | 
|  | ); | 
|  | } else if (superInitializerCount == 1) { | 
|  | // Only report the second (first illegal) superinitializer. | 
|  | errorReporter.atNode( | 
|  | initializer, | 
|  | CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, | 
|  | ); | 
|  | } | 
|  | superInitializer = initializer; | 
|  | superInitializerCount++; | 
|  | } | 
|  | } | 
|  | // Check for initializers which are illegal when alongside a redirecting | 
|  | // initializer. | 
|  | if (redirectingInitializerCount > 0) { | 
|  | for (ConstructorInitializer initializer in declaration.initializers) { | 
|  | if (initializer is SuperConstructorInvocation) { | 
|  | if (enclosingClass is! EnumElement2) { | 
|  | errorReporter.atNode( | 
|  | initializer, | 
|  | CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR, | 
|  | ); | 
|  | } | 
|  | } | 
|  | if (initializer is ConstructorFieldInitializer) { | 
|  | errorReporter.atNode( | 
|  | initializer, | 
|  | CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, | 
|  | ); | 
|  | } | 
|  | if (initializer is AssertInitializer) { | 
|  | errorReporter.atNode( | 
|  | initializer, | 
|  | CompileTimeErrorCode.ASSERT_IN_REDIRECTING_CONSTRUCTOR, | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  | if (enclosingClass is! EnumElement2 && | 
|  | redirectingInitializerCount == 0 && | 
|  | superInitializerCount == 1 && | 
|  | superInitializer != declaration.initializers.last) { | 
|  | var superType = enclosingClass.supertype; | 
|  | if (superType != null) { | 
|  | var superNamedType = superType.element3.displayName; | 
|  | var constructorStrName = superNamedType; | 
|  | var constructorName = superInitializer.constructorName; | 
|  | if (constructorName != null) { | 
|  | constructorStrName += '.${constructorName.name}'; | 
|  | } | 
|  | errorReporter.atToken( | 
|  | superInitializer.superKeyword, | 
|  | CompileTimeErrorCode.SUPER_INVOCATION_NOT_LAST, | 
|  | arguments: [constructorStrName], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that if the given [constructor] declaration is 'const' then there | 
|  | /// are no invocations of non-'const' super constructors, and that there are | 
|  | /// no instance variables mixed in. | 
|  | /// | 
|  | /// Return `true` if an error is reported here, and the caller should stop | 
|  | /// checking the constructor for constant-related errors. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER], and | 
|  | /// [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD]. | 
|  | bool _checkForConstConstructorWithNonConstSuper( | 
|  | ConstructorDeclaration constructor) { | 
|  | var enclosingClass = _enclosingClass; | 
|  | if (enclosingClass == null || !_enclosingExecutable.isConstConstructor) { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | // OK, const factory, checked elsewhere | 
|  | if (constructor.factoryKeyword != null) { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | // check for mixins | 
|  | var instanceFields = <FieldElement2>[]; | 
|  | for (var mixin in enclosingClass.mixins) { | 
|  | instanceFields.addAll(mixin.element3.fields2.where((field) { | 
|  | if (field.isStatic) { | 
|  | return false; | 
|  | } | 
|  | if (field.isSynthetic) { | 
|  | return false; | 
|  | } | 
|  | // From the abstract and external fields specification: | 
|  | // > An abstract instance variable declaration D is treated as an | 
|  | // > abstract getter declaration and possibly an abstract setter | 
|  | // > declaration. The setter is included if and only if D is non-final. | 
|  | if (field.isAbstract && field.isFinal) { | 
|  | return false; | 
|  | } | 
|  | return true; | 
|  | })); | 
|  | } | 
|  | if (instanceFields.length == 1) { | 
|  | var field = instanceFields.single; | 
|  | errorReporter.atNode( | 
|  | constructor.returnType, | 
|  | CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD, | 
|  | arguments: ["'${field.enclosingElement2.name3}.${field.name3}'"], | 
|  | ); | 
|  | return true; | 
|  | } else if (instanceFields.length > 1) { | 
|  | var fieldNames = instanceFields | 
|  | .map((field) => "'${field.enclosingElement2.name3}.${field.name3}'") | 
|  | .join(', '); | 
|  | errorReporter.atNode( | 
|  | constructor.returnType, | 
|  | CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELDS, | 
|  | arguments: [fieldNames], | 
|  | ); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | // Enum(s) always call a const super-constructor. | 
|  | if (enclosingClass is EnumElement2) { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | var element = constructor.declaredFragment?.element; | 
|  | if (element == null) { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | // Redirecting constructors are checked to be const elsewhere. | 
|  | if (element.redirectedConstructor2 != null) { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | var invokedSuper = element.superConstructor2; | 
|  | if (invokedSuper == null || invokedSuper.isConst) { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | // Often there is an explicit `super()` invocation, report on it. | 
|  | var superInvocation = constructor.initializers | 
|  | .whereType<SuperConstructorInvocation>() | 
|  | .firstOrNull; | 
|  | var errorNode = superInvocation ?? constructor.returnType; | 
|  |  | 
|  | errorReporter.atNode( | 
|  | errorNode, | 
|  | CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER, | 
|  | arguments: [element.enclosingElement2.displayName], | 
|  | ); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | /// Verify that if the given [constructor] declaration is 'const' then there | 
|  | /// are no non-final instance variable. The [constructorElement] is the | 
|  | /// constructor element. | 
|  | void _checkForConstConstructorWithNonFinalField( | 
|  | ConstructorDeclaration constructor, | 
|  | ConstructorElement2 constructorElement) { | 
|  | if (!_enclosingExecutable.isConstConstructor) { | 
|  | return; | 
|  | } | 
|  | if (!_enclosingExecutable.isGenerativeConstructor) { | 
|  | return; | 
|  | } | 
|  | // check if there is non-final field | 
|  | var classElement = constructorElement.enclosingElement2; | 
|  | if (classElement is! ClassElement2 || !classElement.hasNonFinalField) { | 
|  | return; | 
|  | } | 
|  | errorReporter.atConstructorDeclaration( | 
|  | constructor, | 
|  | CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD, | 
|  | ); | 
|  | } | 
|  |  | 
|  | /// Verify that the given 'const' instance creation [expression] is not | 
|  | /// creating a deferred type. The [constructorName] is the constructor name, | 
|  | /// always non-`null`. The [namedType] is the name of the type defining the | 
|  | /// constructor, always non-`null`. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.CONST_DEFERRED_CLASS]. | 
|  | void _checkForConstDeferredClass(InstanceCreationExpression expression, | 
|  | ConstructorName constructorName, NamedType namedType) { | 
|  | if (namedType.isDeferred) { | 
|  | errorReporter.atNode( | 
|  | constructorName, | 
|  | CompileTimeErrorCode.CONST_DEFERRED_CLASS, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that the given throw [expression] is not enclosed in a 'const' | 
|  | /// constructor declaration. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION]. | 
|  | void _checkForConstEvalThrowsException(ThrowExpression expression) { | 
|  | if (_enclosingExecutable.isConstConstructor) { | 
|  | errorReporter.atNode( | 
|  | expression, | 
|  | CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that the given instance creation [expression] is not being invoked | 
|  | /// on an abstract class. The [namedType] is the [NamedType] of the | 
|  | /// [ConstructorName] from the [InstanceCreationExpression], this is the AST | 
|  | /// node that the error is attached to. The [type] is the type being | 
|  | /// constructed with this [InstanceCreationExpression]. | 
|  | void _checkForConstOrNewWithAbstractClass( | 
|  | InstanceCreationExpression expression, | 
|  | NamedType namedType, | 
|  | InterfaceType type) { | 
|  | var element = type.element3; | 
|  | if (element is ClassElement2 && element.isAbstract) { | 
|  | var element = expression.constructorName.element; | 
|  | if (element != null && !element.isFactory) { | 
|  | bool isImplicit = | 
|  | (expression as InstanceCreationExpressionImpl).isImplicit; | 
|  | if (!isImplicit) { | 
|  | errorReporter.atNode( | 
|  | namedType, | 
|  | CompileTimeErrorCode.INSTANTIATE_ABSTRACT_CLASS, | 
|  | ); | 
|  | } else { | 
|  | errorReporter.atNode( | 
|  | namedType, | 
|  | CompileTimeErrorCode.INSTANTIATE_ABSTRACT_CLASS, | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that the given [expression] is not a mixin instantiation. | 
|  | void _checkForConstOrNewWithMixin(InstanceCreationExpression expression, | 
|  | NamedType namedType, InterfaceType type) { | 
|  | if (type.element3 is MixinElement2) { | 
|  | errorReporter.atNode( | 
|  | namedType, | 
|  | CompileTimeErrorCode.MIXIN_INSTANTIATE, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that the given 'const' instance creation [expression] is not being | 
|  | /// invoked on a constructor that is not 'const'. | 
|  | /// | 
|  | /// This method assumes that the instance creation was tested to be 'const' | 
|  | /// before being called. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.CONST_WITH_NON_CONST]. | 
|  | void _checkForConstWithNonConst(InstanceCreationExpression expression) { | 
|  | var constructorElement = expression.constructorName.element; | 
|  | if (constructorElement != null && !constructorElement.isConst) { | 
|  | if (expression.keyword != null) { | 
|  | errorReporter.atToken( | 
|  | expression.keyword!, | 
|  | CompileTimeErrorCode.CONST_WITH_NON_CONST, | 
|  | ); | 
|  | } else { | 
|  | errorReporter.atNode( | 
|  | expression, | 
|  | CompileTimeErrorCode.CONST_WITH_NON_CONST, | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that if the given 'const' instance creation [expression] is being | 
|  | /// invoked on the resolved constructor. The [constructorName] is the | 
|  | /// constructor name, always non-`null`. The [namedType] is the name of the | 
|  | /// type defining the constructor, always non-`null`. | 
|  | /// | 
|  | /// This method assumes that the instance creation was tested to be 'const' | 
|  | /// before being called. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR], and | 
|  | /// [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT]. | 
|  | void _checkForConstWithUndefinedConstructor( | 
|  | InstanceCreationExpression expression, | 
|  | ConstructorName constructorName, | 
|  | NamedType namedType) { | 
|  | // OK if resolved | 
|  | if (constructorName.element != null) { | 
|  | return; | 
|  | } | 
|  | // report as named or default constructor absence | 
|  | var name = constructorName.name; | 
|  | if (name != null) { | 
|  | errorReporter.atNode( | 
|  | name, | 
|  | CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR, | 
|  | arguments: [namedType.qualifiedName, name.name], | 
|  | ); | 
|  | } else { | 
|  | errorReporter.atNode( | 
|  | constructorName, | 
|  | CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, | 
|  | arguments: [namedType.qualifiedName], | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForDeadNullCoalesce(TypeImpl lhsType, Expression rhs) { | 
|  | if (typeSystem.isStrictlyNonNullable(lhsType)) { | 
|  | errorReporter.atNode( | 
|  | rhs, | 
|  | StaticWarningCode.DEAD_NULL_AWARE_EXPRESSION, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Report a diagnostic if there are any extensions in the imported library | 
|  | /// that are not hidden. | 
|  | void _checkForDeferredImportOfExtensions( | 
|  | ImportDirective directive, LibraryImport importElement) { | 
|  | for (var element in importElement.namespace.definedNames2.values) { | 
|  | if (element is ExtensionElement2) { | 
|  | errorReporter.atNode( | 
|  | directive.uri, | 
|  | CompileTimeErrorCode.DEFERRED_IMPORT_OF_EXTENSION, | 
|  | ); | 
|  | return; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that any deferred imports in the given compilation [unit] have a | 
|  | /// unique prefix. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.SHARED_DEFERRED_PREFIX]. | 
|  | void _checkForDeferredPrefixCollisions(CompilationUnit unit) { | 
|  | NodeList<Directive> directives = unit.directives; | 
|  | int count = directives.length; | 
|  | if (count > 0) { | 
|  | Map<PrefixElement, List<ImportDirective>> prefixToDirectivesMap = | 
|  | HashMap<PrefixElement, List<ImportDirective>>(); | 
|  | for (int i = 0; i < count; i++) { | 
|  | Directive directive = directives[i]; | 
|  | if (directive is ImportDirective) { | 
|  | var prefix = directive.prefix; | 
|  | if (prefix != null) { | 
|  | var element = prefix.element?.asElement; | 
|  | if (element is PrefixElement) { | 
|  | var elements = prefixToDirectivesMap[element]; | 
|  | if (elements == null) { | 
|  | elements = <ImportDirective>[]; | 
|  | prefixToDirectivesMap[element] = elements; | 
|  | } | 
|  | elements.add(directive); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | for (List<ImportDirective> imports in prefixToDirectivesMap.values) { | 
|  | _checkDeferredPrefixCollision(imports); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Return `true` if the caller should continue checking the rest of the | 
|  | /// information in the for-each part. | 
|  | bool _checkForEachParts(ForEachParts node, Element2? variableElement) { | 
|  | if (checkForUseOfVoidResult(node.iterable)) { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | var iterableType = node.iterable.typeOrThrow; | 
|  |  | 
|  | Token? awaitKeyword; | 
|  | var parent = node.parent; | 
|  | if (parent is ForStatement) { | 
|  | awaitKeyword = parent.awaitKeyword; | 
|  | } else if (parent is ForElement) { | 
|  | awaitKeyword = parent.awaitKeyword; | 
|  | } | 
|  |  | 
|  | // Use an explicit string instead of [loopType] to remove the "<E>". | 
|  | String loopNamedType = awaitKeyword != null ? 'Stream' : 'Iterable'; | 
|  |  | 
|  | if (iterableType is DynamicType && strictCasts) { | 
|  | errorReporter.atNode( | 
|  | node.iterable, | 
|  | CompileTimeErrorCode.FOR_IN_OF_INVALID_TYPE, | 
|  | arguments: [iterableType, loopNamedType], | 
|  | ); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | // TODO(scheglov): use NullableDereferenceVerifier | 
|  | if (typeSystem.isNullable(iterableType)) { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | // The type of the loop variable. | 
|  | TypeImpl variableType; | 
|  | if (variableElement is VariableElementImpl2) { | 
|  | variableType = variableElement.type; | 
|  | } else { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | // The object being iterated has to implement Iterable<T> for some T that | 
|  | // is assignable to the variable's type. | 
|  | // TODO(rnystrom): Move this into mostSpecificTypeArgument()? | 
|  | iterableType = typeSystem.resolveToBound(iterableType); | 
|  |  | 
|  | var requiredSequenceType = awaitKeyword != null | 
|  | ? _typeProvider.streamDynamicType | 
|  | : _typeProvider.iterableDynamicType; | 
|  |  | 
|  | if (typeSystem.isTop(iterableType)) { | 
|  | iterableType = requiredSequenceType; | 
|  | } | 
|  |  | 
|  | if (!typeSystem.isAssignableTo(iterableType, requiredSequenceType, | 
|  | strictCasts: strictCasts)) { | 
|  | errorReporter.atNode( | 
|  | node.iterable, | 
|  | CompileTimeErrorCode.FOR_IN_OF_INVALID_TYPE, | 
|  | arguments: [iterableType, loopNamedType], | 
|  | ); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | TypeImpl? sequenceElementType; | 
|  | { | 
|  | var sequenceElement = awaitKeyword != null | 
|  | ? _typeProvider.streamElement | 
|  | : _typeProvider.iterableElement; | 
|  | var sequenceType = iterableType.asInstanceOf(sequenceElement); | 
|  | if (sequenceType != null) { | 
|  | sequenceElementType = sequenceType.typeArguments[0]; | 
|  | } | 
|  | } | 
|  |  | 
|  | if (sequenceElementType == null) { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | if (!typeSystem.isAssignableTo(sequenceElementType, variableType, | 
|  | strictCasts: strictCasts)) { | 
|  | // Use an explicit string instead of [loopType] to remove the "<E>". | 
|  | String loopNamedType = awaitKeyword != null ? 'Stream' : 'Iterable'; | 
|  |  | 
|  | // A for-in loop is specified to desugar to a different set of statements | 
|  | // which include an assignment of the sequence element's `iterator`'s | 
|  | // `current` value, at which point "implicit tear-off conversion" may be | 
|  | // performed. We do not perform this desugaring; instead we allow a | 
|  | // special assignability here. | 
|  | var implicitCallMethod = getImplicitCallMethod( | 
|  | sequenceElementType, variableType, node.iterable); | 
|  | if (implicitCallMethod == null) { | 
|  | errorReporter.atNode( | 
|  | node.iterable, | 
|  | CompileTimeErrorCode.FOR_IN_OF_INVALID_ELEMENT_TYPE, | 
|  | arguments: [iterableType, loopNamedType, variableType], | 
|  | ); | 
|  | } else { | 
|  | var tearoffType = implicitCallMethod.type; | 
|  | // An implicit tear-off conversion does occur on the values of the | 
|  | // iterator, but this does not guarantee their assignability. | 
|  |  | 
|  | if (_featureSet?.isEnabled(Feature.constructor_tearoffs) ?? true) { | 
|  | var typeArguments = typeSystem.inferFunctionTypeInstantiation( | 
|  | variableType as FunctionTypeImpl, | 
|  | tearoffType, | 
|  | errorReporter: errorReporter, | 
|  | errorNode: node.iterable, | 
|  | genericMetadataIsEnabled: true, | 
|  | inferenceUsingBoundsIsEnabled: | 
|  | _featureSet?.isEnabled(Feature.inference_using_bounds) ?? true, | 
|  | strictInference: options.strictInference, | 
|  | strictCasts: options.strictCasts, | 
|  | typeSystemOperations: typeSystemOperations, | 
|  | dataForTesting: null, | 
|  | nodeForTesting: null, | 
|  | ); | 
|  | if (typeArguments.isNotEmpty) { | 
|  | tearoffType = tearoffType.instantiate(typeArguments); | 
|  | } | 
|  | } | 
|  |  | 
|  | if (!typeSystem.isAssignableTo(tearoffType, variableType, | 
|  | strictCasts: strictCasts)) { | 
|  | errorReporter.atNode( | 
|  | node.iterable, | 
|  | CompileTimeErrorCode.FOR_IN_OF_INVALID_ELEMENT_TYPE, | 
|  | arguments: [iterableType, loopNamedType, variableType], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | return true; | 
|  | } | 
|  |  | 
|  | void _checkForEnumInstantiatedToBoundsIsNotWellBounded( | 
|  | EnumDeclaration node, | 
|  | EnumElementImpl element, | 
|  | ) { | 
|  | var valuesFieldType = element.valuesField?.type; | 
|  | if (valuesFieldType is InterfaceTypeImpl) { | 
|  | var isWellBounded = typeSystem.isWellBounded( | 
|  | valuesFieldType.typeArguments.single, | 
|  | allowSuperBounded: true, | 
|  | ); | 
|  | if (isWellBounded is NotWellBoundedTypeResult) { | 
|  | errorReporter.atToken( | 
|  | node.name, | 
|  | CompileTimeErrorCode.ENUM_INSTANTIATED_TO_BOUNDS_IS_NOT_WELL_BOUNDED, | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Check that if the visiting library is not system, then any given library | 
|  | /// should not be SDK internal library. The [libraryExport] is the | 
|  | /// [LibraryExport] retrieved from the node, if the element in the node was | 
|  | /// `null`, then this method is not called. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY]. | 
|  | void _checkForExportInternalLibrary( | 
|  | ExportDirective directive, LibraryExport libraryExport) { | 
|  | if (_isInSystemLibrary) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | var exportedLibrary = libraryExport.exportedLibrary2; | 
|  | if (exportedLibrary == null) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | // should be private | 
|  | var sdk = _currentLibrary.context.sourceFactory.dartSdk!; | 
|  | var uri = exportedLibrary.uri.toString(); | 
|  |  | 
|  | var sdkLibrary = sdk.getSdkLibrary(uri); | 
|  | if (sdkLibrary == null) { | 
|  | return; | 
|  | } | 
|  | if (!sdkLibrary.isInternal) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | // It is safe to assume that `directive.uri.stringValue` is non-`null`, | 
|  | // because the only time it is `null` is if the URI contains a string | 
|  | // interpolation, in which case the export would never have resolved in the | 
|  | // first place. | 
|  | errorReporter.atNode( | 
|  | directive, | 
|  | CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY, | 
|  | arguments: [directive.uri.stringValue!], | 
|  | ); | 
|  | } | 
|  |  | 
|  | /// Verifies that the given [superclass], found in an extends-clause, is not a | 
|  | /// deferred class. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS]. | 
|  | void _checkForExtendsDeferredClass(NamedType? superclass) { | 
|  | if (superclass == null) { | 
|  | return; | 
|  | } | 
|  | _checkForExtendsOrImplementsDeferredClass( | 
|  | superclass, CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS); | 
|  | } | 
|  |  | 
|  | /// Verifies that the given [superclass], found in an extends-clause, is not a | 
|  | /// class such as 'num' or 'String'. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]. | 
|  | bool _checkForExtendsDisallowedClass(NamedType? superclass) { | 
|  | if (superclass == null) { | 
|  | return false; | 
|  | } | 
|  | return _checkForExtendsOrImplementsDisallowedClass( | 
|  | superclass, CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS); | 
|  | } | 
|  |  | 
|  | /// Verify that the given [namedType] does not extend, implement or mixin | 
|  | /// classes that are deferred. | 
|  | /// | 
|  | /// See [_checkForExtendsDeferredClass], | 
|  | /// [_checkForAllMixinErrorCodes], | 
|  | /// [CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS], | 
|  | /// [CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS], and | 
|  | /// [CompileTimeErrorCode.MIXIN_DEFERRED_CLASS]. | 
|  | bool _checkForExtendsOrImplementsDeferredClass( | 
|  | NamedType namedType, ErrorCode errorCode) { | 
|  | if (namedType.isSynthetic) { | 
|  | return false; | 
|  | } | 
|  | if (namedType.isDeferred) { | 
|  | errorReporter.atNode( | 
|  | namedType, | 
|  | errorCode, | 
|  | ); | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /// Verify that the given [namedType] does not extend, implement or mixin | 
|  | /// classes such as 'num' or 'String'. | 
|  | /// | 
|  | // TODO(scheglov): Remove this method, when all inheritance / override | 
|  | // is concentrated. We keep it for now only because we need to know when | 
|  | // inheritance is completely wrong, so that we don't need to check anything | 
|  | // else. | 
|  | bool _checkForExtendsOrImplementsDisallowedClass( | 
|  | NamedType namedType, ErrorCode errorCode) { | 
|  | if (namedType.isSynthetic) { | 
|  | return false; | 
|  | } | 
|  | // The SDK implementation may implement disallowed types. For example, | 
|  | // JSNumber in dart2js and _Smi in Dart VM both implement int. | 
|  | if (_currentLibrary.source.uri.isScheme('dart')) { | 
|  | return false; | 
|  | } | 
|  | var type = namedType.type; | 
|  | return type is InterfaceType && | 
|  | _typeProvider.isNonSubtypableClass2(type.element3); | 
|  | } | 
|  |  | 
|  | void _checkForExtensionDeclaresInstanceField(FieldDeclaration node) { | 
|  | if (node.parent is! ExtensionDeclaration) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (node.isStatic || node.externalKeyword != null) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | for (var field in node.fields.variables) { | 
|  | errorReporter.atToken( | 
|  | field.name, | 
|  | CompileTimeErrorCode.EXTENSION_DECLARES_INSTANCE_FIELD, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForExtensionDeclaresMemberOfObject(MethodDeclaration node) { | 
|  | if (_enclosingExtension != null) { | 
|  | if (node.hasObjectMemberName) { | 
|  | errorReporter.atToken( | 
|  | node.name, | 
|  | CompileTimeErrorCode.EXTENSION_DECLARES_MEMBER_OF_OBJECT, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | if (_enclosingClass is ExtensionTypeElement2) { | 
|  | if (node.hasObjectMemberName) { | 
|  | errorReporter.atToken( | 
|  | node.name, | 
|  | CompileTimeErrorCode.EXTENSION_TYPE_DECLARES_MEMBER_OF_OBJECT, | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForExtensionTypeConstructorWithSuperInvocation( | 
|  | SuperConstructorInvocation node, | 
|  | ) { | 
|  | if (_enclosingClass is ExtensionTypeElement2) { | 
|  | errorReporter.atToken( | 
|  | node.superKeyword, | 
|  | CompileTimeErrorCode.EXTENSION_TYPE_CONSTRUCTOR_WITH_SUPER_INVOCATION, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForExtensionTypeDeclaresInstanceField(FieldDeclaration node) { | 
|  | if (_enclosingClass is! ExtensionTypeElement2) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (node.isStatic || node.externalKeyword != null) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | for (var field in node.fields.variables) { | 
|  | errorReporter.atToken( | 
|  | field.name, | 
|  | CompileTimeErrorCode.EXTENSION_TYPE_DECLARES_INSTANCE_FIELD, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForExtensionTypeImplementsDeferred( | 
|  | ExtensionTypeDeclarationImpl node, | 
|  | ) { | 
|  | var clause = node.implementsClause; | 
|  | if (clause == null) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | for (var type in clause.interfaces) { | 
|  | _checkForExtendsOrImplementsDeferredClass( | 
|  | type, | 
|  | CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForExtensionTypeImplementsItself( | 
|  | ExtensionTypeDeclarationImpl node, | 
|  | ExtensionTypeElementImpl element, | 
|  | ) { | 
|  | if (element.hasImplementsSelfReference) { | 
|  | errorReporter.atToken( | 
|  | node.name, | 
|  | CompileTimeErrorCode.EXTENSION_TYPE_IMPLEMENTS_ITSELF, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForExtensionTypeMemberConflicts({ | 
|  | required ExtensionTypeDeclaration node, | 
|  | required ExtensionTypeElement element, | 
|  | }) { | 
|  | void report(String memberName, List<ExecutableElement> candidates) { | 
|  | var contextMessages = candidates.map<DiagnosticMessage>((executable) { | 
|  | var nonSynthetic = executable.nonSynthetic; | 
|  | var container = executable.enclosingElement3 as InterfaceElement; | 
|  | return DiagnosticMessageImpl( | 
|  | filePath: executable.source.fullName, | 
|  | offset: nonSynthetic.nameOffset, | 
|  | length: nonSynthetic.nameLength, | 
|  | message: "Inherited from '${container.name}'", | 
|  | url: null, | 
|  | ); | 
|  | }).toList(); | 
|  | errorReporter.atToken( | 
|  | node.name, | 
|  | CompileTimeErrorCode.EXTENSION_TYPE_INHERITED_MEMBER_CONFLICT, | 
|  | arguments: [node.name.lexeme, memberName], | 
|  | contextMessages: contextMessages, | 
|  | ); | 
|  | } | 
|  |  | 
|  | var interface = _inheritanceManager.getInterface(element); | 
|  | for (var conflict in interface.conflicts) { | 
|  | switch (conflict) { | 
|  | case CandidatesConflict _: | 
|  | report(conflict.name.name, conflict.candidates); | 
|  | case HasNonExtensionAndExtensionMemberConflict _: | 
|  | report(conflict.name.name, [ | 
|  | ...conflict.nonExtension, | 
|  | ...conflict.extension, | 
|  | ]); | 
|  | case NotUniqueExtensionMemberConflict _: | 
|  | report(conflict.name.name, conflict.candidates); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForExtensionTypeRepresentationDependsOnItself( | 
|  | ExtensionTypeDeclarationImpl node, | 
|  | ExtensionTypeElementImpl element, | 
|  | ) { | 
|  | if (element.hasRepresentationSelfReference) { | 
|  | errorReporter.atToken( | 
|  | node.name, | 
|  | CompileTimeErrorCode.EXTENSION_TYPE_REPRESENTATION_DEPENDS_ON_ITSELF, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForExtensionTypeRepresentationTypeBottom( | 
|  | ExtensionTypeDeclarationImpl node, | 
|  | ExtensionTypeElementImpl element, | 
|  | ) { | 
|  | var representationType = element.representation.type; | 
|  | if (representationType.isBottom) { | 
|  | errorReporter.atNode( | 
|  | node.representation.fieldType, | 
|  | CompileTimeErrorCode.EXTENSION_TYPE_REPRESENTATION_TYPE_BOTTOM, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForExtensionTypeWithAbstractMember( | 
|  | ExtensionTypeDeclarationImpl node, | 
|  | ) { | 
|  | for (var member in node.members) { | 
|  | if (member is MethodDeclarationImpl && !member.isStatic) { | 
|  | if (member.isAbstract) { | 
|  | errorReporter.atNode( | 
|  | member, | 
|  | CompileTimeErrorCode.EXTENSION_TYPE_WITH_ABSTRACT_MEMBER, | 
|  | arguments: [member.name.lexeme, node.name.lexeme], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that the given field formal [parameter] is in a constructor | 
|  | /// declaration. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]. | 
|  | void _checkForFieldInitializingFormalRedirectingConstructor( | 
|  | FieldFormalParameter parameter) { | 
|  | // prepare the node that should be a ConstructorDeclaration | 
|  | var formalParameterList = parameter.parent; | 
|  | if (formalParameterList is! FormalParameterList) { | 
|  | formalParameterList = formalParameterList?.parent; | 
|  | } | 
|  | var constructor = formalParameterList?.parent; | 
|  | // now check whether the node is actually a ConstructorDeclaration | 
|  | if (constructor is ConstructorDeclaration) { | 
|  | // constructor cannot be a factory | 
|  | if (constructor.factoryKeyword != null) { | 
|  | errorReporter.atNode( | 
|  | parameter, | 
|  | CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR, | 
|  | ); | 
|  | return; | 
|  | } | 
|  | // constructor cannot have a redirection | 
|  | for (ConstructorInitializer initializer in constructor.initializers) { | 
|  | if (initializer is RedirectingConstructorInvocation) { | 
|  | errorReporter.atNode( | 
|  | parameter, | 
|  | CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, | 
|  | ); | 
|  | return; | 
|  | } | 
|  | } | 
|  | } else { | 
|  | errorReporter.atNode( | 
|  | parameter, | 
|  | CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that the given variable declaration [list] has only initialized | 
|  | /// variables if the list is final or const. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.CONST_NOT_INITIALIZED], and | 
|  | /// [CompileTimeErrorCode.FINAL_NOT_INITIALIZED]. | 
|  | void _checkForFinalNotInitialized(VariableDeclarationList list) { | 
|  | if (_isInNativeClass || list.isSynthetic) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | // Handled during resolution, with flow analysis. | 
|  | if (list.isFinal && list.parent is VariableDeclarationStatement) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | bool isConst = list.isConst; | 
|  | if (!(isConst || list.isFinal)) { | 
|  | return; | 
|  | } | 
|  | NodeList<VariableDeclaration> variables = list.variables; | 
|  | for (VariableDeclaration variable in variables) { | 
|  | if (variable.initializer == null) { | 
|  | if (isConst) { | 
|  | errorReporter.atToken( | 
|  | variable.name, | 
|  | CompileTimeErrorCode.CONST_NOT_INITIALIZED, | 
|  | arguments: [variable.name.lexeme], | 
|  | ); | 
|  | } else { | 
|  | var variableElement = variable.declaredFragment?.element; | 
|  | if (variableElement is FieldElement2 && | 
|  | (variableElement.isAbstract || variableElement.isExternal)) { | 
|  | // Abstract and external fields can't be initialized, so no error. | 
|  | } else if (variableElement is TopLevelVariableElement2 && | 
|  | variableElement.isExternal) { | 
|  | // External top level variables can't be initialized, so no error. | 
|  | } else if (!variable.isLate) { | 
|  | errorReporter.atToken( | 
|  | variable.name, | 
|  | CompileTimeErrorCode.FINAL_NOT_INITIALIZED, | 
|  | arguments: [variable.name.lexeme], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// If there are no constructors in the given [members], verify that all | 
|  | /// final fields are initialized.  Cases in which there is at least one | 
|  | /// constructor are handled in [_checkForFinalNotInitialized]. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.CONST_NOT_INITIALIZED], and | 
|  | /// [CompileTimeErrorCode.FINAL_NOT_INITIALIZED]. | 
|  | void _checkForFinalNotInitializedInClass( | 
|  | InstanceElementImpl fragment, | 
|  | List<ClassMember> members, | 
|  | ) { | 
|  | if (fragment is InterfaceElementImpl) { | 
|  | var element = fragment.element; | 
|  | for (var constructor in element.constructors2) { | 
|  | if (constructor.isGenerative && !constructor.isSynthetic) { | 
|  | return; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | for (ClassMember classMember in members) { | 
|  | if (classMember is FieldDeclaration) { | 
|  | var fields = classMember.fields; | 
|  | _checkForFinalNotInitialized(fields); | 
|  | _checkForNotInitializedNonNullableInstanceFields(classMember); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Check that if a direct supertype of a node is final, then it must be in | 
|  | /// the same library. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.FINAL_CLASS_EXTENDED_OUTSIDE_OF_LIBRARY], | 
|  | /// [CompileTimeErrorCode.FINAL_CLASS_IMPLEMENTED_OUTSIDE_OF_LIBRARY], | 
|  | /// [CompileTimeErrorCode. | 
|  | /// FINAL_CLASS_USED_AS_MIXIN_CONSTRAINT_OUTSIDE_OF_LIBRARY]. | 
|  | void _checkForFinalSupertypeOutsideOfLibrary( | 
|  | NamedType? superclass, | 
|  | WithClause? withClause, | 
|  | ImplementsClause? implementsClause, | 
|  | MixinOnClause? onClause, | 
|  | ) { | 
|  | if (superclass != null) { | 
|  | var type = superclass.type; | 
|  | if (type is InterfaceType) { | 
|  | var element = type.element3; | 
|  | if (element is ClassElementImpl2 && | 
|  | element.isFinal && | 
|  | !element.isSealed && | 
|  | element.library2 != _currentLibrary && | 
|  | !_mayIgnoreClassModifiers(element.library2)) { | 
|  | errorReporter.atNode( | 
|  | superclass, | 
|  | CompileTimeErrorCode.FINAL_CLASS_EXTENDED_OUTSIDE_OF_LIBRARY, | 
|  | arguments: [element.name3!], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  | if (implementsClause != null) { | 
|  | for (NamedType namedType in implementsClause.interfaces) { | 
|  | var type = namedType.type; | 
|  | if (type is InterfaceType) { | 
|  | var implementedInterfaces = [ | 
|  | type, | 
|  | ...type.element3.allSupertypes, | 
|  | ].map((e) => e.element3).toList(); | 
|  | for (var element in implementedInterfaces) { | 
|  | if (element is ClassElement2 && | 
|  | element.isFinal && | 
|  | !element.isSealed && | 
|  | element.library2 != _currentLibrary && | 
|  | !_mayIgnoreClassModifiers(element.library2)) { | 
|  | // If the final interface is an indirect interface and is in a | 
|  | // different library that has class modifiers enabled, there is a | 
|  | // nearer declaration that would emit an error, if any. | 
|  | if (element != type.element3 && | 
|  | type.element3.library2.featureSet | 
|  | .isEnabled(Feature.class_modifiers)) { | 
|  | continue; | 
|  | } | 
|  |  | 
|  | errorReporter.atNode( | 
|  | namedType, | 
|  | CompileTimeErrorCode.FINAL_CLASS_IMPLEMENTED_OUTSIDE_OF_LIBRARY, | 
|  | arguments: [element.name3!], | 
|  | ); | 
|  | break; | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | if (onClause != null) { | 
|  | for (NamedType namedType in onClause.superclassConstraints) { | 
|  | var type = namedType.type; | 
|  | if (type is InterfaceType) { | 
|  | var element = type.element3; | 
|  | if (element is ClassElement2 && | 
|  | element.isFinal && | 
|  | !element.isSealed && | 
|  | element.library2 != _currentLibrary && | 
|  | !_mayIgnoreClassModifiers(element.library2)) { | 
|  | errorReporter.atNode( | 
|  | namedType, | 
|  | CompileTimeErrorCode | 
|  | .FINAL_CLASS_USED_AS_MIXIN_CONSTRAINT_OUTSIDE_OF_LIBRARY, | 
|  | arguments: [element.name3!], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForGenericFunctionType(TypeAnnotation? node) { | 
|  | if (node == null) { | 
|  | return; | 
|  | } | 
|  | if (_featureSet?.isEnabled(Feature.generic_metadata) ?? false) { | 
|  | return; | 
|  | } | 
|  | DartType type = node.typeOrThrow; | 
|  | if (type is FunctionType && type.typeParameters.isNotEmpty) { | 
|  | errorReporter.atNode( | 
|  | node, | 
|  | CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForIllegalLanguageOverride(CompilationUnit node) { | 
|  | var sourceLanguageConstraint = | 
|  | (options as AnalysisOptionsImpl).sourceLanguageConstraint; | 
|  | if (sourceLanguageConstraint == null) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | var languageVersion = _currentLibrary.languageVersion.effective; | 
|  | if (sourceLanguageConstraint.allows(languageVersion)) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | var languageVersionToken = node.languageVersionToken; | 
|  | if (languageVersionToken != null) { | 
|  | errorReporter.atToken( | 
|  | languageVersionToken, | 
|  | CompileTimeErrorCode.ILLEGAL_LANGUAGE_VERSION_OVERRIDE, | 
|  | arguments: ['$sourceLanguageConstraint'], | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that the given implements [clause] does not implement classes such | 
|  | /// as 'num' or 'String'. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS], | 
|  | /// [CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS]. | 
|  | bool _checkForImplementsClauseErrorCodes(ImplementsClause? clause) { | 
|  | if (clause == null) { | 
|  | return false; | 
|  | } | 
|  | bool foundError = false; | 
|  | for (NamedType type in clause.interfaces) { | 
|  | if (_checkForExtendsOrImplementsDisallowedClass( | 
|  | type, CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS)) { | 
|  | foundError = true; | 
|  | } else if (_checkForExtendsOrImplementsDeferredClass( | 
|  | type, CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS)) { | 
|  | foundError = true; | 
|  | } | 
|  | } | 
|  | return foundError; | 
|  | } | 
|  |  | 
|  | /// Check that if the visiting library is not system, then any given library | 
|  | /// should not be SDK internal library. The [importElement] is the | 
|  | /// [LibraryImportElement] retrieved from the node, if the element in the node | 
|  | /// was `null`, then this method is not called. | 
|  | void _checkForImportInternalLibrary( | 
|  | ImportDirective directive, LibraryImport importElement) { | 
|  | if (_isInSystemLibrary || _isWasm(importElement)) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | var importedLibrary = importElement.importedLibrary2; | 
|  | if (importedLibrary == null) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | // should be private | 
|  | var sdk = _currentLibrary.context.sourceFactory.dartSdk!; | 
|  | var uri = importedLibrary.uri.toString(); | 
|  | var sdkLibrary = sdk.getSdkLibrary(uri); | 
|  | if (sdkLibrary == null || !sdkLibrary.isInternal) { | 
|  | return; | 
|  | } | 
|  | // The only way an import URI's `stringValue` can be `null` is if the string | 
|  | // contained interpolations, in which case the import would have failed to | 
|  | // resolve, and we would never reach here.  So it is safe to assume that | 
|  | // `directive.uri.stringValue` is non-`null`. | 
|  | errorReporter.atNode( | 
|  | directive.uri, | 
|  | CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY, | 
|  | arguments: [directive.uri.stringValue!], | 
|  | ); | 
|  | } | 
|  |  | 
|  | /// Check that the given [typeReference] is not a type reference and that then | 
|  | /// the [name] is reference to an instance member. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]. | 
|  | void _checkForInstanceAccessToStaticMember(InterfaceElement2? typeReference, | 
|  | Expression? target, SimpleIdentifier name) { | 
|  | if (_isInComment) { | 
|  | // OK, in comment | 
|  | return; | 
|  | } | 
|  | // prepare member Element | 
|  | var element = name.writeOrReadElement2; | 
|  | if (element is ExecutableElement2) { | 
|  | if (!element.isStatic) { | 
|  | // OK, instance member | 
|  | return; | 
|  | } | 
|  | var enclosingElement = element.enclosingElement2; | 
|  | if (enclosingElement is ExtensionElement2) { | 
|  | if (target is ExtensionOverride) { | 
|  | // OK, target is an extension override | 
|  | return; | 
|  | } else if (target is SimpleIdentifier && | 
|  | target.element is ExtensionElement2) { | 
|  | return; | 
|  | } else if (target is PrefixedIdentifier && | 
|  | target.element is ExtensionElement2) { | 
|  | return; | 
|  | } | 
|  | } else { | 
|  | if (typeReference != null) { | 
|  | // OK, target is a type | 
|  | return; | 
|  | } | 
|  | if (enclosingElement is! InterfaceElement2) { | 
|  | // OK, top-level element | 
|  | return; | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that if a class is extending an interface class or mixing in an | 
|  | /// interface mixin, it must be within the same library as that class or | 
|  | /// mixin. | 
|  | /// | 
|  | /// See | 
|  | /// [CompileTimeErrorCode.INTERFACE_CLASS_EXTENDED_OUTSIDE_OF_LIBRARY]. | 
|  | void _checkForInterfaceClassOrMixinSuperclassOutsideOfLibrary( | 
|  | NamedType? superclass, WithClause? withClause) { | 
|  | if (superclass != null) { | 
|  | var superclassType = superclass.type; | 
|  | if (superclassType is InterfaceType) { | 
|  | var superclassElement = superclassType.element3; | 
|  | if (superclassElement is ClassElementImpl2 && | 
|  | superclassElement.isInterface && | 
|  | !superclassElement.isSealed && | 
|  | superclassElement.library2 != _currentLibrary && | 
|  | !_mayIgnoreClassModifiers(superclassElement.library2)) { | 
|  | errorReporter.atNode( | 
|  | superclass, | 
|  | CompileTimeErrorCode.INTERFACE_CLASS_EXTENDED_OUTSIDE_OF_LIBRARY, | 
|  | arguments: [superclassElement.name3!], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that an 'int' can be assigned to the parameter corresponding to the | 
|  | /// given [argument]. This is used for prefix and postfix expressions where | 
|  | /// the argument value is implicit. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. | 
|  | void _checkForIntNotAssignable(ExpressionImpl argument) { | 
|  | var parameterElement = argument.correspondingParameter; | 
|  | var parameterType = parameterElement?.type; | 
|  | if (parameterType != null) { | 
|  | checkForArgumentTypeNotAssignable(argument, parameterType, _intType, | 
|  | CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that the given [annotation] isn't defined in a deferred library. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY]. | 
|  | void _checkForInvalidAnnotationFromDeferredLibrary(Annotation annotation) { | 
|  | Identifier nameIdentifier = annotation.name; | 
|  | if (nameIdentifier is PrefixedIdentifier && nameIdentifier.isDeferred) { | 
|  | errorReporter.atNode( | 
|  | annotation.name, | 
|  | CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Check the given [initializer] to ensure that the field being initialized | 
|  | /// is a valid field. The [fieldName] is the field name from the | 
|  | /// [ConstructorFieldInitializer]. The [staticElement] is the static element | 
|  | /// from the name in the [ConstructorFieldInitializer]. | 
|  | void _checkForInvalidField(ConstructorFieldInitializer initializer, | 
|  | SimpleIdentifier fieldName, Element2? staticElement) { | 
|  | if (staticElement is FieldElement2) { | 
|  | if (staticElement.isSynthetic) { | 
|  | errorReporter.atNode( | 
|  | initializer, | 
|  | CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, | 
|  | arguments: [fieldName.name], | 
|  | ); | 
|  | } else if (staticElement.isStatic) { | 
|  | errorReporter.atNode( | 
|  | initializer, | 
|  | CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, | 
|  | arguments: [fieldName.name], | 
|  | ); | 
|  | } | 
|  | } else { | 
|  | errorReporter.atNode( | 
|  | initializer, | 
|  | CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, | 
|  | arguments: [fieldName.name], | 
|  | ); | 
|  | return; | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForInvalidGenerativeConstructorReference(ConstructorName node) { | 
|  | var constructorElement = node.element; | 
|  | if (constructorElement != null && | 
|  | constructorElement.isGenerative && | 
|  | constructorElement.enclosingElement2 is EnumElement2) { | 
|  | if (_currentLibrary.featureSet.isEnabled(Feature.enhanced_enums)) { | 
|  | errorReporter.atNode( | 
|  | node, | 
|  | CompileTimeErrorCode.INVALID_REFERENCE_TO_GENERATIVE_ENUM_CONSTRUCTOR, | 
|  | ); | 
|  | } else { | 
|  | errorReporter.atNode( | 
|  | node.type, | 
|  | CompileTimeErrorCode.INSTANTIATE_ENUM, | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that if the given [identifier] is part of a constructor | 
|  | /// initializer, then it does not implicitly reference 'this' expression. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER], | 
|  | /// [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY], and | 
|  | /// [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC]. | 
|  | void _checkForInvalidInstanceMemberAccess(SimpleIdentifier identifier) { | 
|  | if (_isInComment) { | 
|  | return; | 
|  | } | 
|  | if (!_isInConstructorInitializer && | 
|  | !_enclosingExecutable.inStaticMethod && | 
|  | !_enclosingExecutable.inFactoryConstructor && | 
|  | !_isInInstanceNotLateVariableDeclaration && | 
|  | !_isInStaticVariableDeclaration) { | 
|  | return; | 
|  | } | 
|  | // prepare element | 
|  | var element = identifier.writeOrReadElement2; | 
|  | if (!(element is MethodElement2 || element is PropertyAccessorElement2)) { | 
|  | return; | 
|  | } | 
|  | // static element | 
|  | ExecutableElement2 executableElement = element as ExecutableElement2; | 
|  | if (executableElement.isStatic) { | 
|  | return; | 
|  | } | 
|  | // not a class member | 
|  | var enclosingElement = element.enclosingElement2; | 
|  | if (enclosingElement is! InterfaceElement2 && | 
|  | enclosingElement is! ExtensionElement2) { | 
|  | return; | 
|  | } | 
|  | // qualified method invocation | 
|  | var parent = identifier.parent; | 
|  | if (parent is MethodInvocation) { | 
|  | if (identical(parent.methodName, identifier) && | 
|  | parent.realTarget != null) { | 
|  | return; | 
|  | } | 
|  | } | 
|  | // qualified property access | 
|  | if (parent is PropertyAccess) { | 
|  | if (identical(parent.propertyName, identifier)) { | 
|  | return; | 
|  | } | 
|  | } | 
|  | if (parent is PrefixedIdentifier) { | 
|  | if (identical(parent.identifier, identifier)) { | 
|  | return; | 
|  | } | 
|  | } | 
|  |  | 
|  | if (_enclosingExecutable.inStaticMethod) { | 
|  | errorReporter.atNode( | 
|  | identifier, | 
|  | CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, | 
|  | ); | 
|  | } else if (_enclosingExecutable.inFactoryConstructor) { | 
|  | errorReporter.atNode( | 
|  | identifier, | 
|  | CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, | 
|  | ); | 
|  | } else { | 
|  | errorReporter.atNode( | 
|  | identifier, | 
|  | CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, | 
|  | arguments: [identifier.name], | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Check to see whether the given function [body] has a modifier associated | 
|  | /// with it, and report it as an error if it does. | 
|  | void _checkForInvalidModifierOnBody( | 
|  | FunctionBody body, CompileTimeErrorCode errorCode) { | 
|  | var keyword = body.keyword; | 
|  | if (keyword != null) { | 
|  | errorReporter.atToken( | 
|  | keyword, | 
|  | errorCode, | 
|  | arguments: [keyword.lexeme], | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that the usage of the given 'this' is valid. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]. | 
|  | void _checkForInvalidReferenceToThis(ThisExpression expression) { | 
|  | if (!_hasAccessToThis) { | 
|  | errorReporter.atNode( | 
|  | expression, | 
|  | CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForLateFinalFieldWithConstConstructor(FieldDeclaration node) { | 
|  | if (node.isStatic) return; | 
|  |  | 
|  | var variableList = node.fields; | 
|  | if (!variableList.isFinal) return; | 
|  |  | 
|  | var lateKeyword = variableList.lateKeyword; | 
|  | if (lateKeyword == null) return; | 
|  |  | 
|  | var enclosingClass = _enclosingClass; | 
|  | if (enclosingClass == null) { | 
|  | // The field is in an extension and should be handled elsewhere. | 
|  | return; | 
|  | } | 
|  |  | 
|  | var hasGenerativeConstConstructor = | 
|  | enclosingClass.constructors2.any((c) => c.isConst && !c.isFactory); | 
|  | if (!hasGenerativeConstConstructor) return; | 
|  |  | 
|  | errorReporter.atToken( | 
|  | lateKeyword, | 
|  | CompileTimeErrorCode.LATE_FINAL_FIELD_WITH_CONST_CONSTRUCTOR, | 
|  | ); | 
|  | } | 
|  |  | 
|  | /// Verify that the elements of the given list [literal] are subtypes of the | 
|  | /// list's static type. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]. | 
|  | void _checkForListElementTypeNotAssignable(ListLiteral literal) { | 
|  | // Determine the list's element type. We base this on the static type and | 
|  | // not the literal's type arguments because in strong mode, the type | 
|  | // arguments may be inferred. | 
|  | DartType listType = literal.typeOrThrow; | 
|  | assert(listType is InterfaceTypeImpl); | 
|  |  | 
|  | var typeArguments = (listType as InterfaceTypeImpl).typeArguments; | 
|  | assert(typeArguments.length == 1); | 
|  |  | 
|  | var listElementType = typeArguments[0]; | 
|  |  | 
|  | // Check every list element. | 
|  | var verifier = LiteralElementVerifier( | 
|  | _typeProvider, | 
|  | typeSystem, | 
|  | errorReporter, | 
|  | this, | 
|  | forList: true, | 
|  | elementType: listElementType, | 
|  | featureSet: _featureSet!, | 
|  | ); | 
|  | for (CollectionElement element in literal.elements) { | 
|  | verifier.verify(element); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForMainFunction1(Token nameToken, Element declaredElement) { | 
|  | // We should only check exported declarations, i.e. top-level. | 
|  | if (declaredElement.enclosingElement3 is! CompilationUnitElement) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (declaredElement.displayName != 'main') { | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (declaredElement is! FunctionElement) { | 
|  | errorReporter.atToken( | 
|  | nameToken, | 
|  | CompileTimeErrorCode.MAIN_IS_NOT_FUNCTION, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForMainFunction2(FunctionDeclarationImpl functionDeclaration) { | 
|  | if (functionDeclaration.name.lexeme != 'main') { | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (functionDeclaration.parent is! CompilationUnit) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | var parameterList = functionDeclaration.functionExpression.parameters; | 
|  | if (parameterList == null) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | var parameters = parameterList.parameters; | 
|  | var positional = parameters.where((e) => e.isPositional).toList(); | 
|  | var requiredPositional = | 
|  | parameters.where((e) => e.isRequiredPositional).toList(); | 
|  |  | 
|  | if (requiredPositional.length > 2) { | 
|  | errorReporter.atToken( | 
|  | functionDeclaration.name, | 
|  | CompileTimeErrorCode.MAIN_HAS_TOO_MANY_REQUIRED_POSITIONAL_PARAMETERS, | 
|  | ); | 
|  | } | 
|  |  | 
|  | if (parameters.any((e) => e.isRequiredNamed)) { | 
|  | errorReporter.atToken( | 
|  | functionDeclaration.name, | 
|  | CompileTimeErrorCode.MAIN_HAS_REQUIRED_NAMED_PARAMETERS, | 
|  | ); | 
|  | } | 
|  |  | 
|  | if (positional.isNotEmpty) { | 
|  | var first = positional.first; | 
|  | var type = first.declaredFragment!.element.type; | 
|  | var listOfString = _typeProvider.listType(_typeProvider.stringType); | 
|  | if (!typeSystem.isSubtypeOf(listOfString, type)) { | 
|  | errorReporter.atNode( | 
|  | first.notDefault.typeOrSelf, | 
|  | CompileTimeErrorCode.MAIN_FIRST_POSITIONAL_PARAMETER_TYPE, | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForMapTypeNotAssignable(SetOrMapLiteral literal) { | 
|  | // Determine the map's key and value types. We base this on the static type | 
|  | // and not the literal's type arguments because in strong mode, the type | 
|  | // arguments may be inferred. | 
|  | DartType mapType = literal.typeOrThrow; | 
|  | assert(mapType is InterfaceTypeImpl); | 
|  |  | 
|  | var typeArguments = (mapType as InterfaceTypeImpl).typeArguments; | 
|  | // It is possible for the number of type arguments to be inconsistent when | 
|  | // the literal is ambiguous and a non-map type was selected. | 
|  | // TODO(brianwilkerson): Unify this and _checkForSetElementTypeNotAssignable3 | 
|  | //  to better handle recovery situations. | 
|  | if (typeArguments.length == 2) { | 
|  | var keyType = typeArguments[0]; | 
|  | var valueType = typeArguments[1]; | 
|  |  | 
|  | var verifier = LiteralElementVerifier( | 
|  | _typeProvider, | 
|  | typeSystem, | 
|  | errorReporter, | 
|  | this, | 
|  | forMap: true, | 
|  | mapKeyType: keyType, | 
|  | mapValueType: valueType, | 
|  | featureSet: _featureSet!, | 
|  | ); | 
|  | for (CollectionElement element in literal.elements) { | 
|  | verifier.verify(element); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Check to make sure that the given switch [statement] whose static type is | 
|  | /// an enum type either have a default case or include all of the enum | 
|  | /// constants. | 
|  | void _checkForMissingEnumConstantInSwitch(SwitchStatement statement) { | 
|  | if (_currentLibrary.featureSet.isEnabled(Feature.patterns)) { | 
|  | // Exhaustiveness checking cover this warning. | 
|  | return; | 
|  | } | 
|  |  | 
|  | // TODO(brianwilkerson): This needs to be checked after constant values have | 
|  | // been computed. | 
|  | var expressionType = statement.expression.staticType; | 
|  |  | 
|  | var hasCaseNull = false; | 
|  | if (expressionType is InterfaceType) { | 
|  | var enumElement = expressionType.element3; | 
|  | if (enumElement is EnumElement2) { | 
|  | var constantNames = enumElement.fields2 | 
|  | .where((field) => field.isEnumConstant) | 
|  | .map((field) => field.name3) | 
|  | .toSet(); | 
|  |  | 
|  | for (var member in statement.members) { | 
|  | Expression? caseConstant; | 
|  | if (member is SwitchCase) { | 
|  | caseConstant = member.expression; | 
|  | } else if (member is SwitchPatternCase) { | 
|  | var guardedPattern = member.guardedPattern; | 
|  | if (guardedPattern.whenClause == null) { | 
|  | var pattern = guardedPattern.pattern.unParenthesized; | 
|  | if (pattern is ConstantPattern) { | 
|  | caseConstant = pattern.expression; | 
|  | } | 
|  | } | 
|  | } | 
|  | if (caseConstant != null) { | 
|  | var expression = caseConstant.unParenthesized; | 
|  | if (expression is NullLiteral) { | 
|  | hasCaseNull = true; | 
|  | } else { | 
|  | var constantName = _getConstantName(expression); | 
|  | constantNames.remove(constantName); | 
|  | } | 
|  | } | 
|  | if (member is SwitchDefault) { | 
|  | return; | 
|  | } | 
|  | } | 
|  |  | 
|  | for (var constantName in constantNames) { | 
|  | int offset = statement.offset; | 
|  | int end = statement.rightParenthesis.end; | 
|  | errorReporter.atOffset( | 
|  | offset: offset, | 
|  | length: end - offset, | 
|  | errorCode: StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH, | 
|  | arguments: [constantName!], | 
|  | ); | 
|  | } | 
|  |  | 
|  | if (typeSystem.isNullable(expressionType) && !hasCaseNull) { | 
|  | int offset = statement.offset; | 
|  | int end = statement.rightParenthesis.end; | 
|  | errorReporter.atOffset( | 
|  | offset: offset, | 
|  | length: end - offset, | 
|  | errorCode: StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH, | 
|  | arguments: ['null'], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that the given mixin does not have an explicitly declared | 
|  | /// constructor. The [mixinName] is the node to report problem on. The | 
|  | /// [mixinElement] is the mixing to evaluate. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.MIXIN_CLASS_DECLARES_CONSTRUCTOR]. | 
|  | bool _checkForMixinClassDeclaresConstructor( | 
|  | NamedType mixinName, InterfaceElement2 mixinElement) { | 
|  | for (var constructor in mixinElement.constructors2) { | 
|  | if (!constructor.isSynthetic && !constructor.isFactory) { | 
|  | errorReporter.atNode( | 
|  | mixinName, | 
|  | CompileTimeErrorCode.MIXIN_CLASS_DECLARES_CONSTRUCTOR, | 
|  | arguments: [mixinElement.name3!], | 
|  | ); | 
|  | return true; | 
|  | } | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /// Verify that mixin classes must have 'Object' as their superclass and that | 
|  | /// they do not have a constructor. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.MIXIN_CLASS_DECLARES_CONSTRUCTOR], | 
|  | /// [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]. | 
|  | void _checkForMixinClassErrorCodes( | 
|  | NamedCompilationUnitMember node, | 
|  | List<ClassMember> members, | 
|  | NamedType? superclass, | 
|  | WithClause? withClause) { | 
|  | var element = node.declaredFragment?.element; | 
|  | if (element is ClassElementImpl2 && element.isMixinClass) { | 
|  | // Check that the class does not have a constructor. | 
|  | for (ClassMember member in members) { | 
|  | if (member is ConstructorDeclarationImpl) { | 
|  | if (!member.isSynthetic && member.factoryKeyword == null) { | 
|  | // Report errors on non-trivial generative constructors on mixin | 
|  | // classes. | 
|  | if (!member.isTrivial) { | 
|  | errorReporter.atNode( | 
|  | member.returnType, | 
|  | CompileTimeErrorCode.MIXIN_CLASS_DECLARES_CONSTRUCTOR, | 
|  | arguments: [element.name3!], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | // Check that the class has 'Object' as their superclass. | 
|  | if (superclass != null && !superclass.typeOrThrow.isDartCoreObject) { | 
|  | errorReporter.atNode( | 
|  | superclass, | 
|  | CompileTimeErrorCode.MIXIN_CLASS_DECLARATION_EXTENDS_NOT_OBJECT, | 
|  | arguments: [element.name3!], | 
|  | ); | 
|  | } else if (withClause != null && | 
|  | !(element.isMixinApplication && withClause.mixinTypes.length < 2)) { | 
|  | errorReporter.atNode( | 
|  | withClause, | 
|  | CompileTimeErrorCode.MIXIN_CLASS_DECLARATION_EXTENDS_NOT_OBJECT, | 
|  | arguments: [element.name3!], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that the given mixin has the 'Object' superclass. | 
|  | /// | 
|  | /// The [mixinName] is the node to report problem on. The [mixinElement] is | 
|  | /// the mixing to evaluate. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]. | 
|  | bool _checkForMixinInheritsNotFromObject( | 
|  | NamedType mixinName, InterfaceElement2 mixinElement) { | 
|  | if (mixinElement is! ClassElement2) { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | var mixinSupertype = mixinElement.supertype; | 
|  | if (mixinSupertype == null || mixinSupertype.isDartCoreObject) { | 
|  | // TODO(scheglov): don't use firstFragment | 
|  | var mixins = mixinElement.firstFragment.mixins; | 
|  | if (mixins.isEmpty || | 
|  | mixinElement.isMixinApplication && mixins.length < 2) { | 
|  | return false; | 
|  | } | 
|  | } | 
|  |  | 
|  | errorReporter.atNode( | 
|  | mixinName, | 
|  | CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, | 
|  | arguments: [mixinElement.name3!], | 
|  | ); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | /// Check that superclass constrains for the mixin type of [mixinName] at | 
|  | /// the [mixinIndex] position in the mixins list are satisfied by the | 
|  | /// [_enclosingClass], or a previous mixin. | 
|  | bool _checkForMixinSuperclassConstraints( | 
|  | int mixinIndex, NamedTypeImpl mixinName) { | 
|  | var mixinType = mixinName.type as InterfaceTypeImpl; | 
|  | for (var constraint in mixinType.superclassConstraints) { | 
|  | var superType = _enclosingClass!.supertype as InterfaceTypeImpl; | 
|  | superType = superType.withNullability(NullabilitySuffix.none); | 
|  |  | 
|  | bool isSatisfied = typeSystem.isSubtypeOf(superType, constraint); | 
|  | if (!isSatisfied) { | 
|  | for (int i = 0; i < mixinIndex && !isSatisfied; i++) { | 
|  | isSatisfied = | 
|  | typeSystem.isSubtypeOf(_enclosingClass!.mixins[i], constraint); | 
|  | } | 
|  | } | 
|  | if (!isSatisfied) { | 
|  | // This error can only occur if [mixinName] resolved to an actual mixin, | 
|  | // so we can safely rely on `mixinName.type` being non-`null`. | 
|  | errorReporter.atToken( | 
|  | mixinName.name2, | 
|  | CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE, | 
|  | arguments: [ | 
|  | mixinName.type!, | 
|  | superType, | 
|  | constraint, | 
|  | ], | 
|  | ); | 
|  | return true; | 
|  | } | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /// Check that the superclass of the given [mixinElement] at the given | 
|  | /// [mixinIndex] in the list of mixins of [_enclosingClass] has concrete | 
|  | /// implementations of all the super-invoked members of the [mixinElement]. | 
|  | bool _checkForMixinSuperInvokedMembers(int mixinIndex, NamedType mixinName, | 
|  | InterfaceElement2 mixinElement, InterfaceType mixinType) { | 
|  | var mixinElementImpl = mixinElement as MixinElementImpl2; | 
|  | if (mixinElementImpl.superInvokedNames.isEmpty) { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | Uri mixinLibraryUri = mixinElement.library2.uri; | 
|  | for (var name in mixinElementImpl.superInvokedNames) { | 
|  | var nameObject = Name(mixinLibraryUri, name); | 
|  |  | 
|  | var superMember = _inheritanceManager.getMember2( | 
|  | _enclosingClass!.asElement, nameObject, | 
|  | forMixinIndex: mixinIndex, concrete: true, forSuper: true); | 
|  |  | 
|  | if (superMember == null) { | 
|  | var isSetter = name.endsWith('='); | 
|  |  | 
|  | var errorCode = isSetter | 
|  | ? CompileTimeErrorCode | 
|  | .MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_SETTER | 
|  | : CompileTimeErrorCode | 
|  | .MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_MEMBER; | 
|  |  | 
|  | if (isSetter) { | 
|  | name = name.substring(0, name.length - 1); | 
|  | } | 
|  |  | 
|  | errorReporter.atNode( | 
|  | mixinName, | 
|  | errorCode, | 
|  | arguments: [name], | 
|  | ); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | var mixinMember = | 
|  | _inheritanceManager.getMember(mixinType, nameObject, forSuper: true); | 
|  |  | 
|  | if (mixinMember != null) { | 
|  | var isCorrect = CorrectOverrideHelper( | 
|  | typeSystem: typeSystem, | 
|  | thisMember: superMember.asElement2, | 
|  | ).isCorrectOverrideOf( | 
|  | superMember: mixinMember.asElement2, | 
|  | ); | 
|  | if (!isCorrect) { | 
|  | errorReporter.atNode( | 
|  | mixinName, | 
|  | CompileTimeErrorCode | 
|  | .MIXIN_APPLICATION_CONCRETE_SUPER_INVOKED_MEMBER_TYPE, | 
|  | arguments: [name, mixinMember.type, superMember.type], | 
|  | ); | 
|  | return true; | 
|  | } | 
|  | } | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /// Check for the declaration of a mixin from a library other than the current | 
|  | /// library that defines a private member that conflicts with a private name | 
|  | /// from the same library but from a superclass or a different mixin. | 
|  | void _checkForMixinWithConflictingPrivateMember( | 
|  | WithClause? withClause, NamedType? superclassName) { | 
|  | if (withClause == null) { | 
|  | return; | 
|  | } | 
|  | var declaredSupertype = superclassName?.type ?? _typeProvider.objectType; | 
|  | if (declaredSupertype is! InterfaceType) { | 
|  | return; | 
|  | } | 
|  | var mixedInNames = <LibraryElement2, Map<String, String>>{}; | 
|  |  | 
|  | /// Report an error and return `true` if the given [name] is a private name | 
|  | /// (which is defined in the given [library]) and it conflicts with another | 
|  | /// definition of that name inherited from the superclass. | 
|  | bool isConflictingName( | 
|  | String name, LibraryElement2 library, NamedType namedType) { | 
|  | if (Identifier.isPrivateName(name)) { | 
|  | Map<String, String> names = mixedInNames.putIfAbsent(library, () => {}); | 
|  | var conflictingName = names[name]; | 
|  | if (conflictingName != null) { | 
|  | if (name.endsWith('=')) { | 
|  | name = name.substring(0, name.length - 1); | 
|  | } | 
|  | errorReporter.atNode( | 
|  | namedType, | 
|  | CompileTimeErrorCode.PRIVATE_COLLISION_IN_MIXIN_APPLICATION, | 
|  | arguments: [name, namedType.name2.lexeme, conflictingName], | 
|  | ); | 
|  | return true; | 
|  | } | 
|  | names[name] = namedType.name2.lexeme; | 
|  | var inheritedMember = _inheritanceManager.getMember4( | 
|  | declaredSupertype.element3, | 
|  | Name(library.uri, name), | 
|  | concrete: true, | 
|  | ); | 
|  | if (inheritedMember != null) { | 
|  | if (name.endsWith('=')) { | 
|  | name = name.substring(0, name.length - 1); | 
|  | } | 
|  | // Inherited members are always contained inside named elements, so we | 
|  | // can safely assume `inheritedMember.enclosingElement3.name` is | 
|  | // non-`null`. | 
|  | errorReporter.atNode( | 
|  | namedType, | 
|  | CompileTimeErrorCode.PRIVATE_COLLISION_IN_MIXIN_APPLICATION, | 
|  | arguments: [ | 
|  | name, | 
|  | namedType.name2.lexeme, | 
|  | inheritedMember.enclosingElement2!.name3! | 
|  | ], | 
|  | ); | 
|  | return true; | 
|  | } | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | for (NamedType mixinType in withClause.mixinTypes) { | 
|  | DartType type = mixinType.typeOrThrow; | 
|  | if (type is InterfaceType) { | 
|  | var library = type.element3.library2; | 
|  | if (library != _currentLibrary) { | 
|  | for (var getter in type.getters) { | 
|  | if (getter.isStatic) { | 
|  | continue; | 
|  | } | 
|  | if (isConflictingName(getter.lookupName!, library, mixinType)) { | 
|  | return; | 
|  | } | 
|  | } | 
|  | for (var setter in type.setters) { | 
|  | if (setter.isStatic) { | 
|  | continue; | 
|  | } | 
|  | if (isConflictingName(setter.lookupName!, library, mixinType)) { | 
|  | return; | 
|  | } | 
|  | } | 
|  | for (var method in type.methods2) { | 
|  | if (method.isStatic) { | 
|  | continue; | 
|  | } | 
|  | if (isConflictingName(method.lookupName!, library, mixinType)) { | 
|  | return; | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Checks to ensure that the given native function [body] is in SDK code. | 
|  | /// | 
|  | /// See [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE]. | 
|  | void _checkForNativeFunctionBodyInNonSdkCode(NativeFunctionBody body) { | 
|  | if (!_isInSystemLibrary) { | 
|  | errorReporter.atNode( | 
|  | body, | 
|  | ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that the given instance creation [expression] invokes an existing | 
|  | /// constructor. The [constructorName] is the constructor name. | 
|  | /// The [namedType] is the name of the type defining the constructor. | 
|  | /// | 
|  | /// This method assumes that the instance creation was tested to be 'new' | 
|  | /// before being called. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.NEW_WITH_UNDEFINED_CONSTRUCTOR]. | 
|  | void _checkForNewWithUndefinedConstructor( | 
|  | InstanceCreationExpression expression, | 
|  | ConstructorName constructorName, | 
|  | NamedType namedType) { | 
|  | // OK if resolved | 
|  | if (constructorName.element != null) { | 
|  | return; | 
|  | } | 
|  | DartType type = namedType.typeOrThrow; | 
|  | if (type is InterfaceType) { | 
|  | var element = type.element3; | 
|  | if (element is EnumElement2 || element is MixinElement2) { | 
|  | // We have already reported the error. | 
|  | return; | 
|  | } | 
|  | } | 
|  | // report as named or default constructor absence | 
|  | var name = constructorName.name; | 
|  | if (name != null) { | 
|  | errorReporter.atNode( | 
|  | name, | 
|  | CompileTimeErrorCode.NEW_WITH_UNDEFINED_CONSTRUCTOR, | 
|  | arguments: [namedType.qualifiedName, name.name], | 
|  | ); | 
|  | } else { | 
|  | errorReporter.atNode( | 
|  | constructorName, | 
|  | CompileTimeErrorCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, | 
|  | arguments: [namedType.qualifiedName], | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Check that if the given class [fragment] implicitly calls default | 
|  | /// constructor of its superclass, there should be such default constructor - | 
|  | /// implicit or explicit. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]. | 
|  | void _checkForNoDefaultSuperConstructorImplicit( | 
|  | ClassElementImpl fragment, | 
|  | ) { | 
|  | // do nothing if there is explicit constructor | 
|  | var constructors = fragment.element.constructors2; | 
|  | if (!constructors[0].isSynthetic) { | 
|  | return; | 
|  | } | 
|  | // prepare super | 
|  | var superType = fragment.supertype; | 
|  | if (superType == null) { | 
|  | return; | 
|  | } | 
|  | var superElement = superType.element; | 
|  | // try to find default generative super constructor | 
|  | var superUnnamedConstructor = superElement.unnamedConstructor; | 
|  | if (superUnnamedConstructor != null) { | 
|  | if (superUnnamedConstructor.isFactory) { | 
|  | errorReporter.atElement2( | 
|  | fragment.asElement2, | 
|  | CompileTimeErrorCode.NON_GENERATIVE_IMPLICIT_CONSTRUCTOR, | 
|  | arguments: [ | 
|  | superElement.name, | 
|  | fragment.name, | 
|  | superUnnamedConstructor, | 
|  | ], | 
|  | ); | 
|  | return; | 
|  | } | 
|  | if (superUnnamedConstructor.isDefaultConstructor) { | 
|  | return; | 
|  | } | 
|  | } | 
|  |  | 
|  | if (!_typeProvider.isNonSubtypableClass(superType.element)) { | 
|  | // Don't report this diagnostic for non-subtypable classes because the | 
|  | // real problem was already reported. | 
|  | errorReporter.atElement2( | 
|  | fragment.asElement2, | 
|  | CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, | 
|  | arguments: [superType, fragment.displayName], | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | bool _checkForNoGenerativeConstructorsInSuperclass(NamedType? superclass) { | 
|  | var superType = _enclosingClass!.supertype; | 
|  | if (superType == null) { | 
|  | return false; | 
|  | } | 
|  | if (_enclosingClass!.constructors2 | 
|  | .every((constructor) => constructor.isFactory)) { | 
|  | // A class with no generative constructors *can* be extended if the | 
|  | // subclass has only factory constructors. | 
|  | return false; | 
|  | } | 
|  | var superElement = superType.element3; | 
|  | if (superElement.constructors2.isEmpty) { | 
|  | // Exclude empty constructor set, which indicates other errors occurred. | 
|  | return false; | 
|  | } | 
|  | if (superElement.constructors2 | 
|  | .every((constructor) => constructor.isFactory)) { | 
|  | // For `E extends Exception`, etc., this will never work, because it has | 
|  | // no generative constructors. State this clearly to users. | 
|  | errorReporter.atNode( | 
|  | superclass!, | 
|  | CompileTimeErrorCode.NO_GENERATIVE_CONSTRUCTORS_IN_SUPERCLASS, | 
|  | arguments: [_enclosingClass!.name3!, superElement.name3!], | 
|  | ); | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | void _checkForNonConstGenerativeEnumConstructor(ConstructorDeclaration node) { | 
|  | if (_enclosingClass is EnumElement2 && | 
|  | node.constKeyword == null && | 
|  | node.factoryKeyword == null) { | 
|  | errorReporter.atConstructorDeclaration( | 
|  | node, | 
|  | CompileTimeErrorCode.NON_CONST_GENERATIVE_ENUM_CONSTRUCTOR, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify the given map [literal] either: | 
|  | /// * has `const modifier` | 
|  | /// * has explicit type arguments | 
|  | /// * is not start of the statement | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT]. | 
|  | void _checkForNonConstMapAsExpressionStatement3(SetOrMapLiteral literal) { | 
|  | // "const" | 
|  | if (literal.constKeyword != null) { | 
|  | return; | 
|  | } | 
|  | // has type arguments | 
|  | if (literal.typeArguments != null) { | 
|  | return; | 
|  | } | 
|  | // prepare statement | 
|  | var statement = literal.thisOrAncestorOfType<ExpressionStatement>(); | 
|  | if (statement == null) { | 
|  | return; | 
|  | } | 
|  | // OK, statement does not start with map | 
|  | if (!identical(statement.beginToken, literal.beginToken)) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | // TODO(srawlins): Add any tests showing this is reported. | 
|  | errorReporter.atNode( | 
|  | literal, | 
|  | CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT, | 
|  | ); | 
|  | } | 
|  |  | 
|  | void _checkForNonCovariantTypeParameterPositionInRepresentationType( | 
|  | ExtensionTypeDeclaration node, | 
|  | ExtensionTypeElement element, | 
|  | ) { | 
|  | var typeParameters = node.typeParameters?.typeParameters; | 
|  | if (typeParameters == null) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | var representationType = element.representation.type; | 
|  |  | 
|  | for (var typeParameterNode in typeParameters) { | 
|  | var typeParameterElement = typeParameterNode.declaredFragment!.element; | 
|  | var nonCovariant = representationType.accept( | 
|  | NonCovariantTypeParameterPositionVisitor( | 
|  | [typeParameterElement], | 
|  | initialVariance: Variance.covariant, | 
|  | ), | 
|  | ); | 
|  | if (nonCovariant) { | 
|  | errorReporter.atNode( | 
|  | typeParameterNode, | 
|  | CompileTimeErrorCode | 
|  | .NON_COVARIANT_TYPE_PARAMETER_POSITION_IN_REPRESENTATION_TYPE, | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForNonFinalFieldInEnum(FieldDeclaration node) { | 
|  | if (node.isStatic) return; | 
|  |  | 
|  | var variableList = node.fields; | 
|  | if (variableList.isFinal) return; | 
|  |  | 
|  | var enclosingClass = _enclosingClass; | 
|  | if (enclosingClass == null || enclosingClass is! EnumElement2) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | errorReporter.atToken( | 
|  | variableList.variables.first.name, | 
|  | CompileTimeErrorCode.NON_FINAL_FIELD_IN_ENUM, | 
|  | ); | 
|  | } | 
|  |  | 
|  | /// Verify that the given method [declaration] of operator `[]=`, has `void` | 
|  | /// return type. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.NON_VOID_RETURN_FOR_OPERATOR]. | 
|  | void _checkForNonVoidReturnTypeForOperator(MethodDeclaration declaration) { | 
|  | // check that []= operator | 
|  | if (declaration.name.lexeme != "[]=") { | 
|  | return; | 
|  | } | 
|  | // check return type | 
|  | var annotation = declaration.returnType; | 
|  | if (annotation != null) { | 
|  | DartType type = annotation.typeOrThrow; | 
|  | if (type is! VoidType) { | 
|  | errorReporter.atNode( | 
|  | annotation, | 
|  | CompileTimeErrorCode.NON_VOID_RETURN_FOR_OPERATOR, | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify the [namedType], used as the return type of a setter, is valid | 
|  | /// (either `null` or the type 'void'). | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.NON_VOID_RETURN_FOR_SETTER]. | 
|  | void _checkForNonVoidReturnTypeForSetter(TypeAnnotation? namedType) { | 
|  | if (namedType != null) { | 
|  | DartType type = namedType.typeOrThrow; | 
|  | if (type is! VoidType) { | 
|  | errorReporter.atNode( | 
|  | namedType, | 
|  | CompileTimeErrorCode.NON_VOID_RETURN_FOR_SETTER, | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForNotInitializedNonNullableInstanceFields( | 
|  | FieldDeclaration fieldDeclaration, | 
|  | ) { | 
|  | if (fieldDeclaration.isStatic) return; | 
|  | var fields = fieldDeclaration.fields; | 
|  |  | 
|  | if (fields.isLate) return; | 
|  | if (fields.isFinal) return; | 
|  |  | 
|  | if (_isEnclosingClassFfiStruct) return; | 
|  | if (_isEnclosingClassFfiUnion) return; | 
|  |  | 
|  | for (var field in fields.variables) { | 
|  | var fieldElement = field.declaredFragment?.element as FieldElement2; | 
|  | if (fieldElement.isAbstract || fieldElement.isExternal) continue; | 
|  | if (field.initializer != null) continue; | 
|  |  | 
|  | var type = fieldElement.type; | 
|  | if (!typeSystem.isPotentiallyNonNullable(type)) continue; | 
|  |  | 
|  | errorReporter.atNode( | 
|  | field, | 
|  | CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD, | 
|  | arguments: [field.name.lexeme], | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForNotInitializedNonNullableStaticField(FieldDeclaration node) { | 
|  | if (!node.isStatic) { | 
|  | return; | 
|  | } | 
|  | _checkForNotInitializedNonNullableVariable(node.fields, false); | 
|  | } | 
|  |  | 
|  | void _checkForNotInitializedNonNullableVariable( | 
|  | VariableDeclarationList node, | 
|  | bool topLevel, | 
|  | ) { | 
|  | // Checked separately. | 
|  | if (node.isConst || (topLevel && node.isFinal)) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (node.isLate) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | var parent = node.parent; | 
|  | if (parent is FieldDeclaration) { | 
|  | if (parent.externalKeyword != null) { | 
|  | return; | 
|  | } | 
|  | } else if (parent is TopLevelVariableDeclaration) { | 
|  | if (parent.externalKeyword != null) { | 
|  | return; | 
|  | } | 
|  | } | 
|  |  | 
|  | if (node.type == null) { | 
|  | return; | 
|  | } | 
|  | var type = node.type!.typeOrThrow; | 
|  |  | 
|  | if (!typeSystem.isPotentiallyNonNullable(type)) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | for (var variable in node.variables) { | 
|  | if (variable.initializer == null) { | 
|  | errorReporter.atToken( | 
|  | variable.name, | 
|  | CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_VARIABLE, | 
|  | arguments: [variable.name.lexeme], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that all classes of the given [onClause] are valid. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS], | 
|  | /// [CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_DEFERRED_CLASS]. | 
|  | bool _checkForOnClauseErrorCodes(MixinOnClause? onClause) { | 
|  | if (onClause == null) { | 
|  | return false; | 
|  | } | 
|  | bool problemReported = false; | 
|  | for (NamedType namedType in onClause.superclassConstraints) { | 
|  | DartType type = namedType.typeOrThrow; | 
|  | if (type is InterfaceType) { | 
|  | if (_checkForExtendsOrImplementsDisallowedClass( | 
|  | namedType, | 
|  | CompileTimeErrorCode | 
|  | .MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS)) { | 
|  | problemReported = true; | 
|  | } else { | 
|  | if (_checkForExtendsOrImplementsDeferredClass( | 
|  | namedType, | 
|  | CompileTimeErrorCode | 
|  | .MIXIN_SUPER_CLASS_CONSTRAINT_DEFERRED_CLASS)) { | 
|  | problemReported = true; | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | return problemReported; | 
|  | } | 
|  |  | 
|  | /// Verify the given operator-method [declaration], does not have an optional | 
|  | /// parameter. | 
|  | /// | 
|  | /// This method assumes that the method declaration was tested to be an | 
|  | /// operator declaration before being called. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR]. | 
|  | void _checkForOptionalParameterInOperator(MethodDeclaration declaration) { | 
|  | var parameterList = declaration.parameters; | 
|  | if (parameterList == null) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | NodeList<FormalParameter> formalParameters = parameterList.parameters; | 
|  | for (FormalParameter formalParameter in formalParameters) { | 
|  | if (formalParameter.isOptional) { | 
|  | errorReporter.atNode( | 
|  | formalParameter, | 
|  | CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR, | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Via informal specification: dart-lang/language/issues/4 | 
|  | /// | 
|  | /// If e is an integer literal which is not the operand of a unary minus | 
|  | /// operator, then: | 
|  | ///   - If the context type is double, it is a compile-time error if the | 
|  | ///   numerical value of e is not precisely representable by a double. | 
|  | ///   Otherwise the static type of e is double and the result of evaluating e | 
|  | ///   is a double instance representing that value. | 
|  | ///   - Otherwise (the current behavior of e, with a static type of int). | 
|  | /// | 
|  | /// and | 
|  | /// | 
|  | /// If e is -n and n is an integer literal, then | 
|  | ///   - If the context type is double, it is a compile-time error if the | 
|  | ///   numerical value of n is not precisely representable by a double. | 
|  | ///   Otherwise the static type of e is double and the result of evaluating e | 
|  | ///   is the result of calling the unary minus operator on a double instance | 
|  | ///   representing the numerical value of n. | 
|  | ///   - Otherwise (the current behavior of -n) | 
|  | void _checkForOutOfRange(IntegerLiteralImpl node) { | 
|  | var source = node.literal.lexeme; | 
|  | if (node.beginToken.type == TokenType.INT_WITH_SEPARATORS || | 
|  | node.beginToken.type == TokenType.HEXADECIMAL_WITH_SEPARATORS) { | 
|  | source = shared.stripSeparators(source); | 
|  | } | 
|  | bool isNegated = node.immediatelyNegated; | 
|  |  | 
|  | bool treatedAsDouble = node.staticType == _typeProvider.doubleType; | 
|  | bool valid = treatedAsDouble | 
|  | ? IntegerLiteralImpl.isValidAsDouble(source) | 
|  | : IntegerLiteralImpl.isValidAsInteger(source, isNegated); | 
|  |  | 
|  | if (!valid) { | 
|  | var lexeme = node.literal.lexeme; | 
|  | var messageArguments = [ | 
|  | isNegated ? '-$lexeme' : lexeme, | 
|  | if (treatedAsDouble) | 
|  | // Suggest the nearest valid double (as a BigInt, for printing). | 
|  | // TODO(srawlins): Insert digit separators at the same positions as | 
|  | // the input. This should be tested code, and a shared impl when we | 
|  | // have an assist that adds digit separators to a number literal. | 
|  | BigInt.from(IntegerLiteralImpl.nearestValidDouble(source)).toString(), | 
|  | ]; | 
|  |  | 
|  | errorReporter.atNode( | 
|  | node, | 
|  | treatedAsDouble | 
|  | ? CompileTimeErrorCode.INTEGER_LITERAL_IMPRECISE_AS_DOUBLE | 
|  | : CompileTimeErrorCode.INTEGER_LITERAL_OUT_OF_RANGE, | 
|  | arguments: messageArguments, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Check that the given named optional [parameter] does not begin with '_'. | 
|  | void _checkForPrivateOptionalParameter(FormalParameter parameter) { | 
|  | // should be named parameter | 
|  | if (!parameter.isNamed) { | 
|  | return; | 
|  | } | 
|  | // name should start with '_' | 
|  | var name = parameter.name; | 
|  | if (name == null || name.isSynthetic || !name.lexeme.startsWith('_')) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | errorReporter.atToken( | 
|  | name, | 
|  | CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, | 
|  | ); | 
|  | } | 
|  |  | 
|  | /// Check whether the given constructor [declaration] is the redirecting | 
|  | /// generative constructor and references itself directly or indirectly. The | 
|  | /// [constructorElement] is the constructor element. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT]. | 
|  | void _checkForRecursiveConstructorRedirect(ConstructorDeclaration declaration, | 
|  | ConstructorElement2 constructorElement) { | 
|  | // we check generative constructor here | 
|  | if (declaration.factoryKeyword != null) { | 
|  | return; | 
|  | } | 
|  | // try to find redirecting constructor invocation and analyze it for | 
|  | // recursion | 
|  | for (ConstructorInitializer initializer in declaration.initializers) { | 
|  | if (initializer is RedirectingConstructorInvocation) { | 
|  | if (_hasRedirectingFactoryConstructorCycle(constructorElement)) { | 
|  | errorReporter.atNode( | 
|  | initializer, | 
|  | CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT, | 
|  | ); | 
|  | } | 
|  | return; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Check whether the given constructor [declaration] has redirected | 
|  | /// constructor and references itself directly or indirectly. The | 
|  | /// constructor [element] is the element introduced by the declaration. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT]. | 
|  | bool _checkForRecursiveFactoryRedirect( | 
|  | ConstructorDeclaration declaration, ConstructorElement2 element) { | 
|  | // prepare redirected constructor | 
|  | var redirectedConstructorNode = declaration.redirectedConstructor; | 
|  | if (redirectedConstructorNode == null) { | 
|  | return false; | 
|  | } | 
|  | // OK if no cycle | 
|  | if (!_hasRedirectingFactoryConstructorCycle(element)) { | 
|  | return false; | 
|  | } | 
|  | // report error | 
|  | errorReporter.atNode( | 
|  | redirectedConstructorNode, | 
|  | CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT, | 
|  | ); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | /// Check that the given constructor [declaration] has a valid redirected | 
|  | /// constructor. | 
|  | void _checkForRedirectingConstructorErrorCodes( | 
|  | ConstructorDeclaration declaration) { | 
|  | // Check for default values in the parameters. | 
|  | var redirectedConstructor = declaration.redirectedConstructor; | 
|  | if (redirectedConstructor == null) { | 
|  | return; | 
|  | } | 
|  | for (FormalParameter parameter in declaration.parameters.parameters) { | 
|  | if (parameter is DefaultFormalParameter && | 
|  | parameter.defaultValue != null) { | 
|  | errorReporter.atToken( | 
|  | parameter.name!, | 
|  | CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR, | 
|  | ); | 
|  | } | 
|  | } | 
|  | var redirectedElement = redirectedConstructor.element; | 
|  | _checkForRedirectToNonConstConstructor( | 
|  | declaration.declaredFragment!.element, | 
|  | redirectedElement, | 
|  | redirectedConstructor, | 
|  | ); | 
|  | var redirectedClass = redirectedElement?.enclosingElement2; | 
|  | if (redirectedClass is ClassElement2 && | 
|  | redirectedClass.isAbstract && | 
|  | redirectedElement != null && | 
|  | !redirectedElement.isFactory) { | 
|  | String enclosingNamedType = _enclosingClass!.displayName; | 
|  | String constructorStrName = enclosingNamedType; | 
|  | if (declaration.name != null) { | 
|  | constructorStrName += ".${declaration.name!.lexeme}"; | 
|  | } | 
|  | errorReporter.atNode( | 
|  | redirectedConstructor, | 
|  | CompileTimeErrorCode.REDIRECT_TO_ABSTRACT_CLASS_CONSTRUCTOR, | 
|  | arguments: [constructorStrName, redirectedClass.name3!], | 
|  | ); | 
|  | } | 
|  | _checkForInvalidGenerativeConstructorReference(redirectedConstructor); | 
|  | } | 
|  |  | 
|  | /// Check whether the redirecting constructor, [element], is const, and | 
|  | /// [redirectedElement], its redirectee, is not const. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR]. | 
|  | void _checkForRedirectToNonConstConstructor( | 
|  | ConstructorElement2 element, | 
|  | ConstructorElement2? redirectedElement, | 
|  | SyntacticEntity errorEntity, | 
|  | ) { | 
|  | // This constructor is const, but it redirects to a non-const constructor. | 
|  | if (redirectedElement != null && | 
|  | element.isConst && | 
|  | !redirectedElement.isConst) { | 
|  | errorReporter.atEntity( | 
|  | errorEntity, | 
|  | CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForReferenceBeforeDeclaration({ | 
|  | required Token nameToken, | 
|  | required Element2? element, | 
|  | }) { | 
|  | if (element != null && | 
|  | _hiddenElements != null && | 
|  | _hiddenElements!.contains(element)) { | 
|  | _hiddenElements!.contains(element); | 
|  | errorReporter.reportError( | 
|  | _diagnosticFactory.referencedBeforeDeclaration( | 
|  | errorReporter.source, | 
|  | nameToken: nameToken, | 
|  | element2: element, | 
|  | ), | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForRepeatedType( | 
|  | Set<InstanceElement2> accumulatedElements, | 
|  | List<NamedType>? namedTypes, | 
|  | ErrorCode errorCode, | 
|  | ) { | 
|  | if (namedTypes == null) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | for (var namedType in namedTypes) { | 
|  | var type = namedType.type; | 
|  | if (type is InterfaceType) { | 
|  | var element = type.element3; | 
|  | var added = accumulatedElements.add(element); | 
|  | if (!added) { | 
|  | errorReporter.atNode( | 
|  | namedType, | 
|  | errorCode, | 
|  | arguments: [element.name3!], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Check that the given rethrow [expression] is inside of a catch clause. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH]. | 
|  | void _checkForRethrowOutsideCatch(RethrowExpression expression) { | 
|  | if (_enclosingExecutable.catchClauseLevel == 0) { | 
|  | errorReporter.atNode( | 
|  | expression, | 
|  | CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Check that if the given constructor [declaration] is generative, then | 
|  | /// it does not have an expression function body. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR]. | 
|  | void _checkForReturnInGenerativeConstructor( | 
|  | ConstructorDeclaration declaration) { | 
|  | // ignore factory | 
|  | if (declaration.factoryKeyword != null) { | 
|  | return; | 
|  | } | 
|  | // block body (with possible return statement) is checked elsewhere | 
|  | FunctionBody body = declaration.body; | 
|  | if (body is! ExpressionFunctionBody) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | errorReporter.atNode( | 
|  | body, | 
|  | CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, | 
|  | ); | 
|  | } | 
|  |  | 
|  | /// Check that if a direct supertype of a node is sealed, then it must be in | 
|  | /// the same library. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.SEALED_CLASS_SUBTYPE_OUTSIDE_OF_LIBRARY]. | 
|  | void _checkForSealedSupertypeOutsideOfLibrary( | 
|  | NamedType? superclass, | 
|  | WithClause? withClause, | 
|  | ImplementsClause? implementsClause, | 
|  | MixinOnClause? onClause) { | 
|  | void reportErrorsForSealedClassesAndMixins(List<NamedType> namedTypes) { | 
|  | for (NamedType namedType in namedTypes) { | 
|  | var type = namedType.type; | 
|  | if (type is InterfaceType) { | 
|  | var element = type.element3; | 
|  | if (element is ClassElement2 && | 
|  | element.isSealed && | 
|  | element.library2 != _currentLibrary) { | 
|  | errorReporter.atNode( | 
|  | namedType, | 
|  | CompileTimeErrorCode.SEALED_CLASS_SUBTYPE_OUTSIDE_OF_LIBRARY, | 
|  | arguments: [element.name3!], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | if (superclass != null) { | 
|  | reportErrorsForSealedClassesAndMixins([superclass]); | 
|  | } | 
|  | if (withClause != null) { | 
|  | reportErrorsForSealedClassesAndMixins(withClause.mixinTypes); | 
|  | } | 
|  | if (implementsClause != null) { | 
|  | reportErrorsForSealedClassesAndMixins(implementsClause.interfaces); | 
|  | } | 
|  | if (onClause != null) { | 
|  | reportErrorsForSealedClassesAndMixins(onClause.superclassConstraints); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that the elements in the given set [literal] are subtypes of the | 
|  | /// set's static type. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE]. | 
|  | void _checkForSetElementTypeNotAssignable3(SetOrMapLiteral literal) { | 
|  | // Determine the set's element type. We base this on the static type and | 
|  | // not the literal's type arguments because in strong mode, the type | 
|  | // arguments may be inferred. | 
|  | var setType = literal.typeOrThrow; | 
|  | assert(setType is InterfaceTypeImpl); | 
|  |  | 
|  | var typeArguments = (setType as InterfaceTypeImpl).typeArguments; | 
|  | // It is possible for the number of type arguments to be inconsistent when | 
|  | // the literal is ambiguous and a non-set type was selected. | 
|  | // TODO(brianwilkerson): Unify this and _checkForMapTypeNotAssignable3 to | 
|  | //  better handle recovery situations. | 
|  | if (typeArguments.length == 1) { | 
|  | var setElementType = typeArguments[0]; | 
|  |  | 
|  | // Check every set element. | 
|  | var verifier = LiteralElementVerifier( | 
|  | _typeProvider, | 
|  | typeSystem, | 
|  | errorReporter, | 
|  | this, | 
|  | forSet: true, | 
|  | elementType: setElementType, | 
|  | featureSet: _featureSet!, | 
|  | ); | 
|  | for (CollectionElement element in literal.elements) { | 
|  | verifier.verify(element); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Check the given [typeReference] and that the [name] is not a reference to | 
|  | /// an instance member. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.STATIC_ACCESS_TO_INSTANCE_MEMBER]. | 
|  | void _checkForStaticAccessToInstanceMember( | 
|  | InterfaceElement2? typeReference, SimpleIdentifier name) { | 
|  | // OK, in comment | 
|  | if (_isInComment) { | 
|  | return; | 
|  | } | 
|  | // OK, target is not a type | 
|  | if (typeReference == null) { | 
|  | return; | 
|  | } | 
|  | // prepare member Element | 
|  | var element = name.element; | 
|  | if (element is ExecutableElement2) { | 
|  | // OK, static | 
|  | if (element.isStatic || element is ConstructorElement2) { | 
|  | return; | 
|  | } | 
|  | errorReporter.atNode( | 
|  | name, | 
|  | CompileTimeErrorCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, | 
|  | arguments: [name.name], | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForThrowOfInvalidType(ThrowExpression node) { | 
|  | var expression = node.expression; | 
|  | var type = node.expression.typeOrThrow; | 
|  |  | 
|  | if (!typeSystem.isAssignableTo(type, typeSystem.objectNone, | 
|  | strictCasts: strictCasts)) { | 
|  | errorReporter.atNode( | 
|  | expression, | 
|  | CompileTimeErrorCode.THROW_OF_INVALID_TYPE, | 
|  | arguments: [type], | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that the given [element] does not reference itself directly. | 
|  | /// If it does, report the error on the [nameToken]. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]. | 
|  | void _checkForTypeAliasCannotReferenceItself( | 
|  | Token nameToken, | 
|  | TypeAliasElementImpl element, | 
|  | ) { | 
|  | if (element.hasSelfReference) { | 
|  | errorReporter.atToken( | 
|  | nameToken, | 
|  | CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that the [type] is not a deferred type. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.TYPE_ANNOTATION_DEFERRED_CLASS]. | 
|  | void _checkForTypeAnnotationDeferredClass(TypeAnnotation? type) { | 
|  | if (type is NamedType && type.isDeferred) { | 
|  | errorReporter.atNode( | 
|  | type, | 
|  | CompileTimeErrorCode.TYPE_ANNOTATION_DEFERRED_CLASS, | 
|  | arguments: [type.qualifiedName], | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Check that none of the type [parameters] references itself in its bound. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND]. | 
|  | void _checkForTypeParameterBoundRecursion(List<TypeParameter> parameters) { | 
|  | Map<TypeParameterElement2, TypeParameter>? elementToNode; | 
|  | for (var parameter in parameters) { | 
|  | if (parameter.bound != null) { | 
|  | if (elementToNode == null) { | 
|  | elementToNode = {}; | 
|  | for (var parameter in parameters) { | 
|  | elementToNode[parameter.declaredFragment!.element] = parameter; | 
|  | } | 
|  | } | 
|  |  | 
|  | TypeParameter? current = parameter; | 
|  | for (var step = 0; current != null; step++) { | 
|  | var boundNode = current.bound; | 
|  | if (boundNode is NamedType) { | 
|  | var boundType = boundNode.typeOrThrow; | 
|  | boundType = boundType.extensionTypeErasure; | 
|  | current = elementToNode[boundType.element3]; | 
|  | } else { | 
|  | current = null; | 
|  | } | 
|  | if (step == parameters.length) { | 
|  | var element = parameter.declaredFragment!.element; | 
|  | // This error can only occur if there is a bound, so we can safely | 
|  | // assume `element.bound` is non-`null`. | 
|  | errorReporter.atToken( | 
|  | parameter.name, | 
|  | CompileTimeErrorCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, | 
|  | arguments: [element.displayName, element.bound!], | 
|  | ); | 
|  | break; | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForTypeParameterReferencedByStatic({ | 
|  | required Token name, | 
|  | required Element2? element, | 
|  | }) { | 
|  | if (_enclosingExecutable.inStaticMethod || _isInStaticVariableDeclaration) { | 
|  | if (element is TypeParameterElement2 && | 
|  | element.enclosingElement2 is InstanceElement2) { | 
|  | // The class's type parameters are not in scope for static methods. | 
|  | // However all other type parameters are legal (e.g. the static method's | 
|  | // type parameters, or a local function's type parameters). | 
|  | errorReporter.atToken( | 
|  | name, | 
|  | CompileTimeErrorCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Check that if the given generative [constructor] has neither an explicit | 
|  | /// super constructor invocation nor a redirecting constructor invocation, | 
|  | /// that the superclass has a default generative constructor. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT], | 
|  | /// [CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR], and | 
|  | /// [CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT]. | 
|  | void _checkForUndefinedConstructorInInitializerImplicit( | 
|  | ConstructorDeclaration constructor) { | 
|  | if (_enclosingClass == null) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | // Ignore if the constructor is not generative. | 
|  | if (constructor.factoryKeyword != null) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | // Ignore if the constructor is external. See | 
|  | // https://github.com/dart-lang/language/issues/869. | 
|  | if (constructor.externalKeyword != null) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | // Ignore if the constructor has either an implicit super constructor | 
|  | // invocation or a redirecting constructor invocation. | 
|  | for (ConstructorInitializer constructorInitializer | 
|  | in constructor.initializers) { | 
|  | if (constructorInitializer is SuperConstructorInvocation || | 
|  | constructorInitializer is RedirectingConstructorInvocation) { | 
|  | return; | 
|  | } | 
|  | } | 
|  |  | 
|  | // Check to see whether the superclass has a non-factory unnamed | 
|  | // constructor. | 
|  | var superType = _enclosingClass!.supertype; | 
|  | if (superType == null) { | 
|  | return; | 
|  | } | 
|  | var superElement = superType.element3; | 
|  |  | 
|  | if (superElement.constructors2 | 
|  | .every((constructor) => constructor.isFactory)) { | 
|  | // Already reported [NO_GENERATIVE_CONSTRUCTORS_IN_SUPERCLASS]. | 
|  | return; | 
|  | } | 
|  |  | 
|  | var superUnnamedConstructor = superElement.unnamedConstructor2; | 
|  | if (superUnnamedConstructor == null) { | 
|  | errorReporter.atNode( | 
|  | constructor.returnType, | 
|  | CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, | 
|  | arguments: [superElement.name3!], | 
|  | ); | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (superUnnamedConstructor.isFactory) { | 
|  | errorReporter.atNode( | 
|  | constructor.returnType, | 
|  | CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, | 
|  | arguments: [superUnnamedConstructor], | 
|  | ); | 
|  | return; | 
|  | } | 
|  |  | 
|  | var requiredPositionalParameterCount = superUnnamedConstructor | 
|  | .formalParameters | 
|  | .where((parameter) => parameter.isRequiredPositional) | 
|  | .length; | 
|  | var requiredNamedParameters = superUnnamedConstructor.formalParameters | 
|  | .where((parameter) => parameter.isRequiredNamed) | 
|  | .map((parameter) => parameter.name3) | 
|  | .toSet(); | 
|  |  | 
|  | void reportError(ErrorCode errorCode, List<Object> arguments) { | 
|  | Identifier returnType = constructor.returnType; | 
|  | var name = constructor.name; | 
|  | int offset = returnType.offset; | 
|  | int length = (name != null ? name.end : returnType.end) - offset; | 
|  | errorReporter.atOffset( | 
|  | offset: offset, | 
|  | length: length, | 
|  | errorCode: errorCode, | 
|  | arguments: arguments, | 
|  | ); | 
|  | } | 
|  |  | 
|  | if (!_currentLibrary.featureSet.isEnabled(Feature.super_parameters)) { | 
|  | if (requiredPositionalParameterCount != 0 || | 
|  | requiredNamedParameters.isNotEmpty) { | 
|  | reportError( | 
|  | CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT, | 
|  | [superType], | 
|  | ); | 
|  | } | 
|  | return; | 
|  | } | 
|  |  | 
|  | var superParametersResult = verifySuperFormalParameters( | 
|  | constructor: constructor, | 
|  | errorReporter: errorReporter, | 
|  | ); | 
|  | requiredNamedParameters.removeAll( | 
|  | superParametersResult.namedArgumentNames, | 
|  | ); | 
|  |  | 
|  | if (requiredPositionalParameterCount > | 
|  | superParametersResult.positionalArgumentCount || | 
|  | requiredNamedParameters.isNotEmpty) { | 
|  | reportError( | 
|  | CompileTimeErrorCode.IMPLICIT_SUPER_INITIALIZER_MISSING_ARGUMENTS, | 
|  | [superType], | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForUnnecessaryNullAware(Expression target, Token operator, | 
|  | {_NullAwareElementOrMapEntryKind? nullAwareElementOrMapEntryKind}) { | 
|  | if (target is SuperExpression) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | ErrorCode errorCode; | 
|  | Token endToken = operator; | 
|  | List<Object> arguments = const []; | 
|  | if (operator.type == TokenType.QUESTION) { | 
|  | if (nullAwareElementOrMapEntryKind == null) { | 
|  | errorCode = StaticWarningCode.INVALID_NULL_AWARE_OPERATOR; | 
|  | endToken = operator.next!; | 
|  | arguments = ['?[', '[']; | 
|  | } else { | 
|  | switch (nullAwareElementOrMapEntryKind) { | 
|  | case _NullAwareElementOrMapEntryKind.element: | 
|  | errorCode = StaticWarningCode.INVALID_NULL_AWARE_ELEMENT; | 
|  | case _NullAwareElementOrMapEntryKind.mapEntryKey: | 
|  | errorCode = StaticWarningCode.INVALID_NULL_AWARE_MAP_ENTRY_KEY; | 
|  | case _NullAwareElementOrMapEntryKind.mapEntryValue: | 
|  | errorCode = StaticWarningCode.INVALID_NULL_AWARE_MAP_ENTRY_VALUE; | 
|  | } | 
|  | } | 
|  | } else if (operator.type == TokenType.QUESTION_PERIOD) { | 
|  | errorCode = StaticWarningCode.INVALID_NULL_AWARE_OPERATOR; | 
|  | arguments = [operator.lexeme, '.']; | 
|  | } else if (operator.type == TokenType.QUESTION_PERIOD_PERIOD) { | 
|  | errorCode = StaticWarningCode.INVALID_NULL_AWARE_OPERATOR; | 
|  | arguments = [operator.lexeme, '..']; | 
|  | } else if (operator.type == TokenType.PERIOD_PERIOD_PERIOD_QUESTION) { | 
|  | errorCode = StaticWarningCode.INVALID_NULL_AWARE_OPERATOR; | 
|  | arguments = [operator.lexeme, '...']; | 
|  | } else if (operator.type == TokenType.BANG) { | 
|  | errorCode = StaticWarningCode.UNNECESSARY_NON_NULL_ASSERTION; | 
|  | } else { | 
|  | return; | 
|  | } | 
|  |  | 
|  | /// If the operator is not valid because the target already makes use of a | 
|  | /// null aware operator, return the null aware operator from the target. | 
|  | Token? previousShortCircuitingOperator(Expression? target) { | 
|  | if (target is PropertyAccess) { | 
|  | var operator = target.operator; | 
|  | var type = operator.type; | 
|  | if (type == TokenType.QUESTION_PERIOD) { | 
|  | var realTarget = target.realTarget; | 
|  | return previousShortCircuitingOperator(realTarget) ?? operator; | 
|  | } | 
|  | } else if (target is IndexExpression) { | 
|  | if (target.question != null) { | 
|  | var realTarget = target.realTarget; | 
|  | return previousShortCircuitingOperator(realTarget) ?? target.question; | 
|  | } | 
|  | } else if (target is MethodInvocation) { | 
|  | var operator = target.operator; | 
|  | var type = operator?.type; | 
|  | if (type == TokenType.QUESTION_PERIOD) { | 
|  | var realTarget = target.realTarget; | 
|  | return previousShortCircuitingOperator(realTarget) ?? operator; | 
|  | } | 
|  | } | 
|  | return null; | 
|  | } | 
|  |  | 
|  | var targetType = target.staticType; | 
|  | if (target is ExtensionOverride) { | 
|  | var arguments = target.argumentList.arguments; | 
|  | if (arguments.length == 1) { | 
|  | targetType = arguments[0].typeOrThrow; | 
|  | } else { | 
|  | return; | 
|  | } | 
|  | } else if (targetType == null) { | 
|  | if (target is Identifier) { | 
|  | var targetElement = target.element; | 
|  | if (targetElement is InterfaceElement2 || | 
|  | targetElement is ExtensionElement2 || | 
|  | targetElement is TypeAliasElement2) { | 
|  | errorReporter.atOffset( | 
|  | offset: operator.offset, | 
|  | length: endToken.end - operator.offset, | 
|  | errorCode: errorCode, | 
|  | arguments: arguments, | 
|  | ); | 
|  | } | 
|  | } | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (typeSystem.isStrictlyNonNullable(targetType)) { | 
|  | if (errorCode == StaticWarningCode.INVALID_NULL_AWARE_OPERATOR) { | 
|  | var previousOperator = previousShortCircuitingOperator(target); | 
|  | if (previousOperator != null) { | 
|  | errorReporter.reportError( | 
|  | _diagnosticFactory.invalidNullAwareAfterShortCircuit( | 
|  | errorReporter.source, | 
|  | operator.offset, | 
|  | endToken.end - operator.offset, | 
|  | arguments, | 
|  | previousOperator)); | 
|  | return; | 
|  | } | 
|  | } | 
|  | errorReporter.atOffset( | 
|  | offset: operator.offset, | 
|  | length: endToken.end - operator.offset, | 
|  | errorCode: errorCode, | 
|  | arguments: arguments, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Check that if the given [name] is a reference to a static member it is | 
|  | /// defined in the enclosing class rather than in a superclass. | 
|  | /// | 
|  | /// See | 
|  | /// [CompileTimeErrorCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER]. | 
|  | void _checkForUnqualifiedReferenceToNonLocalStaticMember( | 
|  | SimpleIdentifier name) { | 
|  | var element = name.writeOrReadElement2; | 
|  | if (element == null || element is TypeParameterElement2) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | var enclosingElement = element.enclosingElement2; | 
|  | if (enclosingElement == null) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (identical(enclosingElement, _enclosingClass)) { | 
|  | return; | 
|  | } | 
|  | if (enclosingElement is! InterfaceElement2) { | 
|  | return; | 
|  | } | 
|  | if (element is ExecutableElement2 && !element.isStatic) { | 
|  | return; | 
|  | } | 
|  | if (element is MethodElement2) { | 
|  | // Invalid methods are reported in | 
|  | // [MethodInvocationResolver._resolveReceiverNull]. | 
|  | return; | 
|  | } | 
|  | if (_enclosingExtension != null) { | 
|  | errorReporter.atNode( | 
|  | name, | 
|  | CompileTimeErrorCode | 
|  | .UNQUALIFIED_REFERENCE_TO_STATIC_MEMBER_OF_EXTENDED_TYPE, | 
|  | arguments: [enclosingElement.displayName], | 
|  | ); | 
|  | } else { | 
|  | errorReporter.atNode( | 
|  | name, | 
|  | CompileTimeErrorCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER, | 
|  | arguments: [enclosingElement.displayName], | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForValidField(FieldFormalParameter parameter) { | 
|  | var parent2 = parameter.parent?.parent; | 
|  | if (parent2 is! ConstructorDeclaration && | 
|  | parent2?.parent is! ConstructorDeclaration) { | 
|  | return; | 
|  | } | 
|  | var element = parameter.declaredFragment?.element; | 
|  | if (element is FieldFormalParameterElementImpl2) { | 
|  | var fieldElement = element.field2; | 
|  | if (fieldElement == null || fieldElement.isSynthetic) { | 
|  | errorReporter.atNode( | 
|  | parameter, | 
|  | CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, | 
|  | arguments: [parameter.name.lexeme], | 
|  | ); | 
|  | } else { | 
|  | var parameterElement = parameter.declaredFragment?.element; | 
|  | if (parameterElement is FieldFormalParameterElementImpl2) { | 
|  | var declaredType = parameterElement.type; | 
|  | var fieldType = fieldElement.type; | 
|  | if (fieldElement.isSynthetic) { | 
|  | errorReporter.atNode( | 
|  | parameter, | 
|  | CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, | 
|  | arguments: [parameter.name.lexeme], | 
|  | ); | 
|  | } else if (fieldElement.isStatic) { | 
|  | errorReporter.atNode( | 
|  | parameter, | 
|  | CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, | 
|  | arguments: [parameter.name.lexeme], | 
|  | ); | 
|  | } else if (!typeSystem.isSubtypeOf(declaredType, fieldType)) { | 
|  | errorReporter.atNode( | 
|  | parameter, | 
|  | CompileTimeErrorCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE, | 
|  | arguments: [declaredType, fieldType], | 
|  | ); | 
|  | } | 
|  | } else { | 
|  | if (fieldElement.isSynthetic) { | 
|  | errorReporter.atNode( | 
|  | parameter, | 
|  | CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, | 
|  | arguments: [parameter.name.lexeme], | 
|  | ); | 
|  | } else if (fieldElement.isStatic) { | 
|  | errorReporter.atNode( | 
|  | parameter, | 
|  | CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, | 
|  | arguments: [parameter.name.lexeme], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | //        else { | 
|  | // TODO(jwren): Report error, constructor initializer variable is a top level element | 
|  | // (Either here or in ErrorVerifier.checkForAllFinalInitializedErrorCodes) | 
|  | //        } | 
|  | } | 
|  |  | 
|  | /// Verify the given operator-method [declaration], has correct number of | 
|  | /// parameters. | 
|  | /// | 
|  | /// This method assumes that the method declaration was tested to be an | 
|  | /// operator declaration before being called. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR]. | 
|  | bool _checkForWrongNumberOfParametersForOperator( | 
|  | MethodDeclaration declaration) { | 
|  | // prepare number of parameters | 
|  | var parameterList = declaration.parameters; | 
|  | if (parameterList == null) { | 
|  | return false; | 
|  | } | 
|  | int numParameters = parameterList.parameters.length; | 
|  | // prepare operator name | 
|  | var nameToken = declaration.name; | 
|  | var name = nameToken.lexeme; | 
|  | // check for exact number of parameters | 
|  | int expected = -1; | 
|  | if ("[]=" == name) { | 
|  | expected = 2; | 
|  | } else if ("<" == name || | 
|  | ">" == name || | 
|  | "<=" == name || | 
|  | ">=" == name || | 
|  | "==" == name || | 
|  | "+" == name || | 
|  | "/" == name || | 
|  | "~/" == name || | 
|  | "*" == name || | 
|  | "%" == name || | 
|  | "|" == name || | 
|  | "^" == name || | 
|  | "&" == name || | 
|  | "<<" == name || | 
|  | ">>" == name || | 
|  | ">>>" == name || | 
|  | "[]" == name) { | 
|  | expected = 1; | 
|  | } else if ("~" == name) { | 
|  | expected = 0; | 
|  | } | 
|  | if (expected != -1 && numParameters != expected) { | 
|  | errorReporter.atToken( | 
|  | nameToken, | 
|  | CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR, | 
|  | arguments: [name, expected, numParameters], | 
|  | ); | 
|  | return true; | 
|  | } else if ("-" == name && numParameters > 1) { | 
|  | errorReporter.atToken( | 
|  | nameToken, | 
|  | CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS, | 
|  | arguments: [numParameters], | 
|  | ); | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /// Verify that the given setter [parameterList] has only one required | 
|  | /// parameter. The [setterName] is the name of the setter to report problems | 
|  | /// on. | 
|  | /// | 
|  | /// This method assumes that the method declaration was tested to be a setter | 
|  | /// before being called. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]. | 
|  | void _checkForWrongNumberOfParametersForSetter( | 
|  | Token setterName, FormalParameterList? parameterList) { | 
|  | if (parameterList == null) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | NodeList<FormalParameter> parameters = parameterList.parameters; | 
|  | if (parameters.length != 1 || !parameters[0].isRequiredPositional) { | 
|  | errorReporter.atToken( | 
|  | setterName, | 
|  | CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForWrongTypeParameterVarianceInField(FieldDeclarationImpl node) { | 
|  | if (_enclosingClass != null) { | 
|  | for (var typeParameter in _enclosingClass!.asElement.typeParameters) { | 
|  | if (!typeParameter.isLegacyCovariant) { | 
|  | var fields = node.fields; | 
|  | var fieldFragment = fields.variables.first.declaredFragment!; | 
|  | var fieldName = fields.variables.first.name; | 
|  | Variance fieldVariance = | 
|  | typeParameter.computeVarianceInType(fieldFragment.type); | 
|  |  | 
|  | _checkForWrongVariancePosition( | 
|  | fieldVariance, typeParameter, fieldName); | 
|  | if (!fields.isFinal && node.covariantKeyword == null) { | 
|  | _checkForWrongVariancePosition( | 
|  | Variance.contravariant.combine(fieldVariance), | 
|  | typeParameter, | 
|  | fieldName); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForWrongTypeParameterVarianceInMethod( | 
|  | MethodDeclarationImpl method) { | 
|  | // Only need to report errors for parameters with explicitly defined type | 
|  | // parameters in classes or mixins. | 
|  | if (_enclosingClass == null) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | for (var typeParameter in _enclosingClass!.asElement.typeParameters) { | 
|  | if (typeParameter.isLegacyCovariant) { | 
|  | continue; | 
|  | } | 
|  |  | 
|  | var methodTypeParameters = method.typeParameters?.typeParameters; | 
|  | if (methodTypeParameters != null) { | 
|  | for (var methodTypeParameter in methodTypeParameters) { | 
|  | if (methodTypeParameter.bound == null) { | 
|  | continue; | 
|  | } | 
|  | var methodTypeParameterVariance = Variance.invariant.combine( | 
|  | typeParameter | 
|  | .computeVarianceInType(methodTypeParameter.bound!.typeOrThrow), | 
|  | ); | 
|  | _checkForWrongVariancePosition( | 
|  | methodTypeParameterVariance, typeParameter, methodTypeParameter); | 
|  | } | 
|  | } | 
|  |  | 
|  | var methodParameters = method.parameters?.parameters; | 
|  | if (methodParameters != null) { | 
|  | for (var methodParameter in methodParameters) { | 
|  | var methodParameterElement = methodParameter.declaredFragment!; | 
|  | if (methodParameterElement.isCovariant) { | 
|  | continue; | 
|  | } | 
|  | var methodParameterVariance = Variance.contravariant.combine( | 
|  | typeParameter.computeVarianceInType(methodParameterElement.type), | 
|  | ); | 
|  | _checkForWrongVariancePosition( | 
|  | methodParameterVariance, typeParameter, methodParameter); | 
|  | } | 
|  | } | 
|  |  | 
|  | var returnType = method.returnType; | 
|  | if (returnType != null) { | 
|  | var methodReturnTypeVariance = | 
|  | typeParameter.computeVarianceInType(returnType.typeOrThrow); | 
|  | _checkForWrongVariancePosition( | 
|  | methodReturnTypeVariance, typeParameter, returnType); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkForWrongTypeParameterVarianceInSuperinterfaces() { | 
|  | void checkOne(DartType? superInterface) { | 
|  | if (superInterface != null) { | 
|  | for (var typeParameter in _enclosingClass!.asElement.typeParameters) { | 
|  | var superVariance = | 
|  | typeParameter.computeVarianceInType(superInterface); | 
|  | // Let `D` be a class or mixin declaration, let `S` be a direct | 
|  | // superinterface of `D`, and let `X` be a type parameter declared by | 
|  | // `D`. | 
|  | // If `X` is an `out` type parameter, it can only occur in `S` in an | 
|  | // covariant or unrelated position. | 
|  | // If `X` is an `in` type parameter, it can only occur in `S` in an | 
|  | // contravariant or unrelated position. | 
|  | // If `X` is an `inout` type parameter, it can occur in `S` in any | 
|  | // position. | 
|  | if (!superVariance.greaterThanOrEqual(typeParameter.variance)) { | 
|  | if (!typeParameter.isLegacyCovariant) { | 
|  | errorReporter.atElement2( | 
|  | typeParameter.asElement2, | 
|  | CompileTimeErrorCode | 
|  | .WRONG_EXPLICIT_TYPE_PARAMETER_VARIANCE_IN_SUPERINTERFACE, | 
|  | arguments: [ | 
|  | typeParameter.name, | 
|  | typeParameter.variance.keyword, | 
|  | superVariance.keyword, | 
|  | superInterface, | 
|  | ], | 
|  | ); | 
|  | } else { | 
|  | errorReporter.atElement2( | 
|  | typeParameter.asElement2, | 
|  | CompileTimeErrorCode | 
|  | .WRONG_TYPE_PARAMETER_VARIANCE_IN_SUPERINTERFACE, | 
|  | arguments: [typeParameter.name, superInterface], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | checkOne(_enclosingClass!.supertype); | 
|  | _enclosingClass!.interfaces.forEach(checkOne); | 
|  | _enclosingClass!.mixins.forEach(checkOne); | 
|  |  | 
|  | var enclosingClass = _enclosingClass.asElement; | 
|  | if (enclosingClass is MixinElement) { | 
|  | enclosingClass.superclassConstraints.forEach(checkOne); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Check for invalid variance positions in members of a class or mixin. | 
|  | /// | 
|  | /// Let `C` be a class or mixin declaration with type parameter `T`. | 
|  | /// If `T` is an `out` type parameter then `T` can only appear in covariant | 
|  | /// positions within the accessors and methods of `C`. | 
|  | /// If `T` is an `in` type parameter then `T` can only appear in contravariant | 
|  | /// positions within the accessors and methods of `C`. | 
|  | /// If `T` is an `inout` type parameter or a type parameter with no explicit | 
|  | /// variance modifier then `T` can appear in any variant position within the | 
|  | /// accessors and methods of `C`. | 
|  | /// | 
|  | /// Errors should only be reported in classes and mixins since those are the | 
|  | /// only components that allow explicit variance modifiers. | 
|  | void _checkForWrongVariancePosition(Variance variance, | 
|  | TypeParameterElement typeParameter, SyntacticEntity errorTarget) { | 
|  | TypeParameterElementImpl typeParameterImpl = | 
|  | typeParameter as TypeParameterElementImpl; | 
|  | if (!variance.greaterThanOrEqual(typeParameterImpl.variance)) { | 
|  | errorReporter.atEntity( | 
|  | errorTarget, | 
|  | CompileTimeErrorCode.WRONG_TYPE_PARAMETER_VARIANCE_POSITION, | 
|  | arguments: [ | 
|  | typeParameterImpl.variance.keyword, | 
|  | typeParameterImpl.name, | 
|  | variance.keyword | 
|  | ], | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that the current class does not have the same class in the | 
|  | /// 'extends' and 'implements' clauses. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS]. | 
|  | void _checkImplementsSuperClass(ImplementsClause? implementsClause) { | 
|  | if (implementsClause == null) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | var superElement = _enclosingClass!.supertype?.element3; | 
|  | if (superElement == null) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | for (var interfaceNode in implementsClause.interfaces) { | 
|  | var type = interfaceNode.type; | 
|  | if (type is InterfaceType && type.element3 == superElement) { | 
|  | errorReporter.atNode( | 
|  | interfaceNode, | 
|  | CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, | 
|  | arguments: [superElement], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Checks the class for problems with the superclass, mixins, or implemented | 
|  | /// interfaces. | 
|  | void _checkMixinInheritance( | 
|  | MixinElementImpl declarationFragment, | 
|  | MixinDeclaration node, | 
|  | MixinOnClause? onClause, | 
|  | ImplementsClause? implementsClause) { | 
|  | // Only check for all of the inheritance logic around clauses if there | 
|  | // isn't an error code such as "Cannot implement double" already. | 
|  | if (!_checkForOnClauseErrorCodes(onClause) && | 
|  | !_checkForImplementsClauseErrorCodes(implementsClause)) { | 
|  | //      _checkForImplicitDynamicType(superclass); | 
|  | _checkForRepeatedType( | 
|  | libraryContext.setOfOn(declarationFragment.asElement2), | 
|  | onClause?.superclassConstraints, | 
|  | CompileTimeErrorCode.ON_REPEATED, | 
|  | ); | 
|  | _checkForRepeatedType( | 
|  | libraryContext.setOfImplements(declarationFragment.asElement2), | 
|  | implementsClause?.interfaces, | 
|  | CompileTimeErrorCode.IMPLEMENTS_REPEATED, | 
|  | ); | 
|  | _checkForConflictingGenerics(node); | 
|  | _checkForBaseClassOrMixinImplementedOutsideOfLibrary(implementsClause); | 
|  | _checkForFinalSupertypeOutsideOfLibrary( | 
|  | null, null, implementsClause, onClause); | 
|  | _checkForSealedSupertypeOutsideOfLibrary( | 
|  | null, null, implementsClause, onClause); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Verify that the current class does not have the same class in the | 
|  | /// 'extends' and 'with' clauses. | 
|  | /// | 
|  | /// See [CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS]. | 
|  | void _checkMixinsSuperClass(WithClause? withClause) { | 
|  | if (withClause == null) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | var superElement = _enclosingClass!.supertype?.element3; | 
|  | if (superElement == null) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | for (var mixinNode in withClause.mixinTypes) { | 
|  | var type = mixinNode.type; | 
|  | if (type is InterfaceType && type.element3 == superElement) { | 
|  | errorReporter.atNode( | 
|  | mixinNode, | 
|  | CompileTimeErrorCode.MIXINS_SUPER_CLASS, | 
|  | arguments: [superElement], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkUseOfCovariantInParameters(FormalParameterList node) { | 
|  | var parent = node.parent; | 
|  | if (_enclosingClass != null && parent is MethodDeclaration) { | 
|  | // Either [parent] is a static method, in which case `EXTRANEOUS_MODIFIER` | 
|  | // is reported by the parser, or [parent] is an instance method, in which | 
|  | // case any use of `covariant` is legal. | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (_enclosingExtension != null) { | 
|  | // `INVALID_USE_OF_COVARIANT_IN_EXTENSION` is reported by the parser. | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (parent is FunctionExpression) { | 
|  | var parent2 = parent.parent; | 
|  | if (parent2 is FunctionDeclaration && parent2.parent is CompilationUnit) { | 
|  | // `EXTRANEOUS_MODIFIER` is reported by the parser, for library-level | 
|  | // functions. | 
|  | return; | 
|  | } | 
|  | } | 
|  |  | 
|  | NodeList<FormalParameter> parameters = node.parameters; | 
|  | int length = parameters.length; | 
|  | for (int i = 0; i < length; i++) { | 
|  | var parameter = parameters[i].notDefault; | 
|  | var keyword = parameter.covariantKeyword; | 
|  | if (keyword != null) { | 
|  | errorReporter.atToken( | 
|  | keyword, | 
|  | CompileTimeErrorCode.INVALID_USE_OF_COVARIANT, | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void _checkUseOfDefaultValuesInParameters(FormalParameterList node) { | 
|  | var defaultValuesAreExpected = () { | 
|  | var parent = node.parent; | 
|  | if (parent is ConstructorDeclaration) { | 
|  | if (parent.externalKeyword != null) { | 
|  | return false; | 
|  | } else if (parent.factoryKeyword != null && | 
|  | parent.redirectedConstructor != null) { | 
|  | return false; | 
|  | } | 
|  | return true; | 
|  | } else if (parent is FunctionExpression) { | 
|  | var parent2 = parent.parent; | 
|  | if (parent2 is FunctionDeclaration && parent2.externalKeyword != null) { | 
|  | return false; | 
|  | } else if (parent.body is NativeFunctionBody) { | 
|  | return false; | 
|  | } | 
|  | return true; | 
|  | } else if (parent is MethodDeclaration) { | 
|  | if (parent.isAbstract) { | 
|  | return false; | 
|  | } else if (parent.externalKeyword != null) { | 
|  | return false; | 
|  | } else if (parent.body is NativeFunctionBody) { | 
|  | return false; | 
|  | } | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  | }(); | 
|  |  | 
|  | for (var parameter in node.parameters) { | 
|  | if (parameter is DefaultFormalParameter) { | 
|  | if (parameter.isRequiredNamed) { | 
|  | if (parameter.defaultValue != null) { | 
|  | var errorTarget = _parameterName(parameter) ?? parameter; | 
|  | errorReporter.atEntity( | 
|  | errorTarget, | 
|  | CompileTimeErrorCode.DEFAULT_VALUE_ON_REQUIRED_PARAMETER, | 
|  | ); | 
|  | } | 
|  | } else if (defaultValuesAreExpected) { | 
|  | var parameterElement = parameter.declaredFragment!.element; | 
|  | if (!parameterElement.hasDefaultValue) { | 
|  | var type = parameterElement.type; | 
|  | if (typeSystem.isPotentiallyNonNullable(type)) { | 
|  | var parameterName = _parameterName(parameter); | 
|  | var errorTarget = parameterName ?? parameter; | 
|  | if (parameterElement.metadata2.hasRequired) { | 
|  | errorReporter.atEntity( | 
|  | errorTarget, | 
|  | CompileTimeErrorCode | 
|  | .MISSING_DEFAULT_VALUE_FOR_PARAMETER_WITH_ANNOTATION, | 
|  | ); | 
|  | } else { | 
|  | if (!_isWildcardSuperFormalPositionalParameter(parameter)) { | 
|  | errorReporter.atEntity( | 
|  | errorTarget, | 
|  | parameterElement.isPositional | 
|  | ? CompileTimeErrorCode | 
|  | .MISSING_DEFAULT_VALUE_FOR_PARAMETER_POSITIONAL | 
|  | : CompileTimeErrorCode | 
|  | .MISSING_DEFAULT_VALUE_FOR_PARAMETER, | 
|  | arguments: [parameterName?.lexeme ?? '?'], | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | bool _computeThisAccessForFunctionBody(FunctionBody node) => | 
|  | switch (node.parent) { | 
|  | ConstructorDeclaration(:var factoryKeyword) => factoryKeyword == null, | 
|  | MethodDeclaration(:var isStatic) => !isStatic, | 
|  | _ => _hasAccessToThis | 
|  | }; | 
|  |  | 
|  | /// Given an [expression] in a switch case whose value is expected to be an | 
|  | /// enum constant, return the name of the constant. | 
|  | String? _getConstantName(Expression expression) { | 
|  | // TODO(brianwilkerson): Convert this to return the element representing the | 
|  | // constant. | 
|  | if (expression is SimpleIdentifier) { | 
|  | return expression.name; | 
|  | } else if (expression is PrefixedIdentifier) { | 
|  | return expression.identifier.name; | 
|  | } else if (expression is PropertyAccess) { | 
|  | return expression.propertyName.name; | 
|  | } | 
|  | return null; | 
|  | } | 
|  |  | 
|  | /// Return the name of the library that defines given [element]. | 
|  | String _getLibraryName(Element2? element) { | 
|  | if (element == null) { | 
|  | return ''; | 
|  | } | 
|  | var library = element.library2; | 
|  | if (library == null) { | 
|  | return ''; | 
|  | } | 
|  | var name = element.name3; | 
|  | if (name == null) { | 
|  | return ''; | 
|  | } | 
|  | var imports = _currentUnit.withEnclosing | 
|  | .expand((fragment) => fragment.libraryImports) | 
|  | .toList(); | 
|  | int count = imports.length; | 
|  | for (int i = 0; i < count; i++) { | 
|  | if (identical(imports[i].importedLibrary, library)) { | 
|  | return library.uri.toString(); | 
|  | } | 
|  | } | 
|  | List<String> indirectSources = <String>[]; | 
|  | for (var import in imports) { | 
|  | var importedLibrary = import.importedLibrary; | 
|  | if (importedLibrary != null) { | 
|  | if (import.namespace.get2(name) == element) { | 
|  | indirectSources.add( | 
|  | importedLibrary.definingCompilationUnit.source.uri.toString()); | 
|  | } | 
|  | } | 
|  | } | 
|  | int indirectCount = indirectSources.length; | 
|  | StringBuffer buffer = StringBuffer(); | 
|  | buffer.write(library.uri.toString()); | 
|  | if (indirectCount > 0) { | 
|  | buffer.write(" (via "); | 
|  | if (indirectCount > 1) { | 
|  | indirectSources.sort(); | 
|  | buffer.write(indirectSources.quotedAndCommaSeparatedWithAnd); | 
|  | } else { | 
|  | buffer.write(indirectSources[0]); | 
|  | } | 
|  | buffer.write(")"); | 
|  | } | 
|  | return buffer.toString(); | 
|  | } | 
|  |  | 
|  | /// Return `true` if the given [constructor] redirects to itself, directly or | 
|  | /// indirectly. | 
|  | bool _hasRedirectingFactoryConstructorCycle(ConstructorElement2 constructor) { | 
|  | Set<ConstructorElement2> constructors = HashSet<ConstructorElement2>(); | 
|  | ConstructorElement2? current = constructor; | 
|  | while (current != null) { | 
|  | if (constructors.contains(current)) { | 
|  | return identical(current, constructor); | 
|  | } | 
|  | constructors.add(current); | 
|  | current = current.redirectedConstructor2?.baseElement; | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /// Returns `true` if the given [library] is the `dart:ffi` library. | 
|  | bool _isDartFfiLibrary(LibraryElement2 library) => | 
|  | library.name3 == 'dart.ffi'; | 
|  |  | 
|  | /// Return `true` if the given [identifier] is in a location where it is | 
|  | /// allowed to resolve to a static member of a supertype. | 
|  | bool _isUnqualifiedReferenceToNonLocalStaticMemberAllowed( | 
|  | SimpleIdentifier identifier) { | 
|  | if (identifier.inDeclarationContext()) { | 
|  | return true; | 
|  | } | 
|  | var parent = identifier.parent; | 
|  | if (parent is Annotation) { | 
|  | return identical(parent.constructorName, identifier); | 
|  | } | 
|  | if (parent is CommentReference) { | 
|  | return true; | 
|  | } | 
|  | if (parent is ConstructorName) { | 
|  | return identical(parent.name, identifier); | 
|  | } | 
|  | if (parent is MethodInvocation) { | 
|  | return identical(parent.methodName, identifier); | 
|  | } | 
|  | if (parent is PrefixedIdentifier) { | 
|  | return identical(parent.identifier, identifier); | 
|  | } | 
|  | if (parent is PropertyAccess) { | 
|  | return identical(parent.propertyName, identifier); | 
|  | } | 
|  | if (parent is SuperConstructorInvocation) { | 
|  | return identical(parent.constructorName, identifier); | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /// Return `true` if the [importElement] is the internal library `dart:_wasm` | 
|  | /// and the current library is either `package:js/js.dart` or is in | 
|  | /// `package:ui`. | 
|  | bool _isWasm(LibraryImport importElement) { | 
|  | var importedUri = importElement.importedLibrary2?.uri.toString(); | 
|  | if (importedUri != 'dart:_wasm') { | 
|  | return false; | 
|  | } | 
|  | var importingUri = _currentLibrary.source.uri.toString(); | 
|  | if (importingUri == 'package:js/js.dart') { | 
|  | return true; | 
|  | } else if (importingUri.startsWith('package:ui/')) { | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | bool _isWildcardSuperFormalPositionalParameter( | 
|  | DefaultFormalParameter parameter) => | 
|  | parameter.parameter is SuperFormalParameter && | 
|  | parameter.isPositional && | 
|  | parameter.name?.lexeme == '_' && | 
|  | _currentLibrary.featureSet.isEnabled(Feature.wildcard_variables); | 
|  |  | 
|  | /// Checks whether a `final`, `base` or `interface` modifier can be ignored. | 
|  | /// | 
|  | /// Checks whether a subclass in the current library | 
|  | /// can ignore a class modifier of a declaration in [superLibrary]. | 
|  | /// | 
|  | /// Only true if the supertype library is a platform library, and | 
|  | /// either the current library is also a platform library, | 
|  | /// or the current library has a language version which predates | 
|  | /// class modifiers | 
|  | bool _mayIgnoreClassModifiers(LibraryElement2 superLibrary) { | 
|  | // Only modifiers in platform libraries can be ignored. | 
|  | if (!superLibrary.isInSdk) return false; | 
|  |  | 
|  | // Modifiers in 'dart:ffi' can't be ignored in pre-feature code. | 
|  | if (_isDartFfiLibrary(superLibrary)) { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | // Other platform libraries can ignore modifiers. | 
|  | if (_currentLibrary.isInSdk) return true; | 
|  |  | 
|  | // Libraries predating class modifiers can ignore platform modifiers. | 
|  | return !_currentLibrary.featureSet.isEnabled(Feature.class_modifiers); | 
|  | } | 
|  |  | 
|  | /// Return the name of the [parameter], or `null` if the parameter does not | 
|  | /// have a name. | 
|  | Token? _parameterName(FormalParameter parameter) { | 
|  | if (parameter is NormalFormalParameter) { | 
|  | return parameter.name; | 
|  | } else if (parameter is DefaultFormalParameter) { | 
|  | return parameter.parameter.name; | 
|  | } | 
|  | return null; | 
|  | } | 
|  |  | 
|  | void _reportForMultipleCombinators(NamespaceDirective node) { | 
|  | var combinators = node.combinators; | 
|  | if (combinators.length > 1) { | 
|  | var offset = combinators.beginToken!.offset; | 
|  | var length = combinators.endToken!.end - offset; | 
|  | errorReporter.atOffset( | 
|  | offset: offset, | 
|  | length: length, | 
|  | errorCode: WarningCode.MULTIPLE_COMBINATORS, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _withEnclosingExecutable( | 
|  | ExecutableElement2OrMember element, | 
|  | void Function() operation, { | 
|  | required bool isAsynchronous, | 
|  | required bool isGenerator, | 
|  | }) { | 
|  | var current = _enclosingExecutable; | 
|  | try { | 
|  | _enclosingExecutable = EnclosingExecutableContext(element, | 
|  | isAsynchronous: isAsynchronous, isGenerator: isGenerator); | 
|  | _returnTypeVerifier.enclosingExecutable = _enclosingExecutable; | 
|  | operation(); | 
|  | } finally { | 
|  | _enclosingExecutable = current; | 
|  | _returnTypeVerifier.enclosingExecutable = _enclosingExecutable; | 
|  | } | 
|  | } | 
|  |  | 
|  | void _withHiddenElements(List<Statement> statements, void Function() f) { | 
|  | _hiddenElements = HiddenElements(_hiddenElements, statements); | 
|  | try { | 
|  | f(); | 
|  | } finally { | 
|  | _hiddenElements = _hiddenElements!.outerElements; | 
|  | } | 
|  | } | 
|  |  | 
|  | void _withHiddenElementsGuardedPattern( | 
|  | GuardedPatternImpl guardedPattern, void Function() f) { | 
|  | _hiddenElements = | 
|  | HiddenElements.forGuardedPattern(_hiddenElements, guardedPattern); | 
|  | try { | 
|  | f(); | 
|  | } finally { | 
|  | _hiddenElements = _hiddenElements!.outerElements; | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Return [FieldElement2]s that are declared in the [ClassDeclaration] with | 
|  | /// the given [constructor], but are not initialized. | 
|  | static List<FieldElement2> computeNotInitializedFields( | 
|  | ConstructorDeclaration constructor) { | 
|  | var fields = <FieldElement2>{}; | 
|  | var classDeclaration = constructor.parent as ClassDeclaration; | 
|  | for (ClassMember fieldDeclaration in classDeclaration.members) { | 
|  | if (fieldDeclaration is FieldDeclaration) { | 
|  | for (VariableDeclaration field in fieldDeclaration.fields.variables) { | 
|  | if (field.initializer == null) { | 
|  | fields.add((field.declaredFragment as FieldFragment).element); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | List<FormalParameter> parameters = constructor.parameters.parameters; | 
|  | for (FormalParameter parameter in parameters) { | 
|  | parameter = parameter.notDefault; | 
|  | if (parameter is FieldFormalParameter) { | 
|  | var element = | 
|  | (parameter.declaredFragment as FieldFormalParameterFragment) | 
|  | .element; | 
|  | fields.remove(element.field2); | 
|  | } | 
|  | } | 
|  |  | 
|  | for (ConstructorInitializer initializer in constructor.initializers) { | 
|  | if (initializer is ConstructorFieldInitializer) { | 
|  | fields.remove(initializer.fieldName.element); | 
|  | } | 
|  | } | 
|  |  | 
|  | return fields.toList(); | 
|  | } | 
|  |  | 
|  | /// Checks whether the given [expression] is a reference to a class. If it is | 
|  | /// then the element representing the class is returned, otherwise `null` is | 
|  | /// returned. | 
|  | static InterfaceElement2? getTypeReference(Expression expression) { | 
|  | if (expression is Identifier) { | 
|  | var element = expression.element; | 
|  | if (element is InterfaceElement2) { | 
|  | return element; | 
|  | } else if (element is TypeAliasElement2) { | 
|  | var aliasedType = element.aliasedType; | 
|  | if (aliasedType is InterfaceType) { | 
|  | return aliasedType.element3; | 
|  | } | 
|  | } | 
|  | } | 
|  | return null; | 
|  | } | 
|  | } | 
|  |  | 
|  | /// A record of the elements that will be declared in some scope (block), but | 
|  | /// are not yet declared. | 
|  | class HiddenElements { | 
|  | /// The elements hidden in outer scopes, or `null` if this is the outermost | 
|  | /// scope. | 
|  | final HiddenElements? outerElements; | 
|  |  | 
|  | /// A set containing the elements that will be declared in this scope, but are | 
|  | /// not yet declared. | 
|  | final Set<Element2> _elements = {}; | 
|  |  | 
|  | /// Initialize a newly created set of hidden elements to include all of the | 
|  | /// elements defined in the set of [outerElements] and all of the elements | 
|  | /// declared in the given [statements]. | 
|  | HiddenElements(this.outerElements, List<Statement> statements) { | 
|  | _initializeElements(statements); | 
|  | } | 
|  |  | 
|  | /// Initialize a newly created set of hidden elements to include all of the | 
|  | /// elements defined in the set of [outerElements] and all of the elements | 
|  | /// declared in the given [guardedPattern]. | 
|  | HiddenElements.forGuardedPattern( | 
|  | this.outerElements, | 
|  | GuardedPatternImpl guardedPattern, | 
|  | ) { | 
|  | _elements.addAll(guardedPattern.variables.values); | 
|  | } | 
|  |  | 
|  | /// Return `true` if this set of elements contains the given [element]. | 
|  | bool contains(Element2 element) { | 
|  | if (_elements.contains(element)) { | 
|  | return true; | 
|  | } else if (outerElements != null) { | 
|  | return outerElements!.contains(element); | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /// Record that the given [element] has been declared, so it is no longer | 
|  | /// hidden. | 
|  | void declare(Element2 element) { | 
|  | _elements.remove(element); | 
|  | } | 
|  |  | 
|  | /// Initialize the list of elements that are not yet declared to be all of the | 
|  | /// elements declared somewhere in the given [statements]. | 
|  | void _initializeElements(List<Statement> statements) { | 
|  | _elements.addAll(BlockScope.elementsInStatements(statements)); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Information to pass from from the defining unit to augmentations. | 
|  | class LibraryVerificationContext { | 
|  | final duplicationDefinitionContext = DuplicationDefinitionContext(); | 
|  | final LibraryFileKind libraryKind; | 
|  | final ConstructorFieldsVerifier constructorFieldsVerifier; | 
|  | final Map<FileState, FileAnalysis> files; | 
|  |  | 
|  | /// A table mapping names to the exported elements. | 
|  | final Map<String, Element2> _exportedElements = {}; | 
|  |  | 
|  | /// Elements referenced in `implements` clauses. | 
|  | /// Key: the declaration element. | 
|  | final Map<InstanceElement2, Set<InstanceElement2>> _setOfImplementsMap = | 
|  | Map.identity(); | 
|  |  | 
|  | /// Elements referenced in `on` clauses. | 
|  | /// Key: the declaration element. | 
|  | final Map<MixinElement2, Set<InterfaceElement2>> _setOfOnMaps = | 
|  | Map.identity(); | 
|  |  | 
|  | LibraryVerificationContext({ | 
|  | required this.libraryKind, | 
|  | required this.constructorFieldsVerifier, | 
|  | required this.files, | 
|  | }); | 
|  |  | 
|  | bool libraryCycleContains(Uri uri) { | 
|  | return libraryKind.libraryCycle.libraryUris.contains(uri); | 
|  | } | 
|  |  | 
|  | Set<InstanceElement2> setOfImplements(InstanceElement2 declaration) { | 
|  | return _setOfImplementsMap[declaration] ??= Set.identity(); | 
|  | } | 
|  |  | 
|  | Set<InterfaceElement2> setOfOn(MixinElement2 declaration) { | 
|  | return _setOfOnMaps[declaration] ??= Set.identity(); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Signals the kind of the null-aware element or entry observed in list, set, | 
|  | /// or map literals. | 
|  | enum _NullAwareElementOrMapEntryKind { | 
|  | element, | 
|  | mapEntryKey, | 
|  | mapEntryValue, | 
|  | } | 
|  |  | 
|  | /// Recursively visits a type annotation, looking uninstantiated bounds. | 
|  | class _UninstantiatedBoundChecker extends RecursiveAstVisitor<void> { | 
|  | final ErrorReporter _errorReporter; | 
|  |  | 
|  | _UninstantiatedBoundChecker(this._errorReporter); | 
|  |  | 
|  | @override | 
|  | void visitNamedType(NamedType node) { | 
|  | var typeArgs = node.typeArguments; | 
|  | if (typeArgs != null) { | 
|  | typeArgs.accept(this); | 
|  | return; | 
|  | } | 
|  |  | 
|  | var element = node.element2; | 
|  | if (element is TypeParameterizedElement2 && !element.isSimplyBounded) { | 
|  | // TODO(srawlins): Don't report this if TYPE_ALIAS_CANNOT_REFERENCE_ITSELF | 
|  | //  has been reported. | 
|  | _errorReporter.atNode( | 
|  | node, | 
|  | CompileTimeErrorCode.NOT_INSTANTIATED_BOUND, | 
|  | ); | 
|  | } | 
|  | } | 
|  | } |