// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/error/codes.dart';

/// Helper for verifying resolution of assignments, in form of explicit
/// an [AssignmentExpression], or a [PrefixExpression] or [PostfixExpression]
/// when the operator is an increment operator.
class AssignmentVerifier {
  final LibraryElement _definingLibrary;
  final ErrorReporter _errorReporter;

  AssignmentVerifier(this._definingLibrary, this._errorReporter);

  /// We resolved [node] and found that it references the [requested] element.
  /// Verify that this element is actually writable.
  ///
  /// If the [requested] element is `null`, we might have the [recovery]
  /// element, which is definitely not a valid write target. We want to report
  /// a good error about this.
  ///
  /// When the [receiverType] is not `null`, we report
  /// [CompileTimeErrorCode.UNDEFINED_SETTER] instead of a more generic
  /// [CompileTimeErrorCode.UNDEFINED_IDENTIFIER].
  void verify({
    required SimpleIdentifier node,
    required Element? requested,
    required Element? recovery,
    required DartType? receiverType,
  }) {
    if (requested != null) {
      if (requested is VariableElement) {
        if (requested.isConst) {
          _errorReporter.reportErrorForNode(
            CompileTimeErrorCode.ASSIGNMENT_TO_CONST,
            node,
          );
        } else if (requested.isFinal) {
          if (_definingLibrary.isNonNullableByDefault) {
            // Handled during resolution, with flow analysis.
          } else {
            _errorReporter.reportErrorForNode(
              CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL,
              node,
              [requested.name],
            );
          }
        }
      }
      return;
    }

    if (recovery is ClassElement ||
        recovery is DynamicElementImpl ||
        recovery is TypeAliasElement ||
        recovery is TypeParameterElement) {
      _errorReporter.reportErrorForNode(
        CompileTimeErrorCode.ASSIGNMENT_TO_TYPE,
        node,
      );
    } else if (recovery is FunctionElement) {
      _errorReporter.reportErrorForNode(
        CompileTimeErrorCode.ASSIGNMENT_TO_FUNCTION,
        node,
      );
    } else if (recovery is MethodElement) {
      _errorReporter.reportErrorForNode(
        CompileTimeErrorCode.ASSIGNMENT_TO_METHOD,
        node,
      );
    } else if (recovery is PrefixElement) {
      _errorReporter.reportErrorForNode(
        CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
        node,
        [recovery.name],
      );
    } else if (recovery is PropertyAccessorElement && recovery.isGetter) {
      var variable = recovery.variable;
      if (variable.isConst) {
        _errorReporter.reportErrorForNode(
          CompileTimeErrorCode.ASSIGNMENT_TO_CONST,
          node,
        );
      } else if (variable is FieldElement && variable.isSynthetic) {
        _errorReporter.reportErrorForNode(
          CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_NO_SETTER,
          node,
          [variable.name, variable.enclosingElement.displayName],
        );
      } else {
        _errorReporter.reportErrorForNode(
          CompileTimeErrorCode.ASSIGNMENT_TO_FINAL,
          node,
          [variable.name],
        );
      }
    } else if (recovery is MultiplyDefinedElementImpl) {
      // Will be reported in ErrorVerifier.
    } else {
      if (node.isSynthetic) {
        return;
      }
      if (receiverType != null) {
        _errorReporter.reportErrorForNode(
          CompileTimeErrorCode.UNDEFINED_SETTER,
          node,
          [node.name, receiverType],
        );
      } else {
        _errorReporter.reportErrorForNode(
          CompileTimeErrorCode.UNDEFINED_IDENTIFIER,
          node,
          [node.name],
        );
      }
    }
  }
}
