// 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';
import 'package:meta/meta.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.
  ///
  /// The [receiverTypeObject] might be a [DartType] or [String], and when
  /// it 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 Object receiverTypeObject,
  }) {
    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 FunctionTypeAliasElement ||
        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 is SimpleIdentifier) {
      if (node.isSynthetic) {
        return;
      }
      if (receiverTypeObject != null) {
        _errorReporter.reportErrorForNode(
          CompileTimeErrorCode.UNDEFINED_SETTER,
          node,
          [node.name, receiverTypeObject],
        );
      } else {
        _errorReporter.reportErrorForNode(
          CompileTimeErrorCode.UNDEFINED_IDENTIFIER,
          node,
          [node.name],
        );
      }
    }
  }
}
