// Copyright (c) 2018, 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/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/ast/extensions.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:pub_semver/pub_semver.dart';

/// A visitor that finds code that assumes a later version of the SDK than the
/// minimum version required by the SDK constraints in `pubspec.yaml`.
class SdkConstraintVerifier extends RecursiveAstVisitor<void> {
  /// The error reporter to be used to report errors.
  final ErrorReporter _errorReporter;

  /// The element representing the library containing the unit to be verified.
  final LibraryElement _containingLibrary;

  /// The typ provider used to access SDK types.
  final TypeProvider _typeProvider;

  /// The version constraint for the SDK.
  final VersionConstraint _versionConstraint;

  /// A cached flag indicating whether references to the constant-update-2018
  /// features need to be checked. Use [checkConstantUpdate2018] to access this
  /// field.
  bool? _checkConstantUpdate2018;

  /// A cached flag indicating whether uses of extension method features need to
  /// be checked. Use [checkExtensionMethods] to access this field.
  bool? _checkExtensionMethods;

  /// A cached flag indicating whether references to Future and Stream need to
  /// be checked. Use [checkFutureAndStream] to access this field.
  bool? _checkFutureAndStream;

  /// A cached flag indicating whether references to set literals need to
  /// be checked. Use [checkSetLiterals] to access this field.
  bool? _checkSetLiterals;

  /// A flag indicating whether we are visiting code inside a set literal. Used
  /// to prevent over-reporting uses of set literals.
  bool _inSetLiteral = false;

  /// A cached flag indicating whether references to the ui-as-code features
  /// need to be checked. Use [checkUiAsCode] to access this field.
  bool? _checkUiAsCode;

  /// A flag indicating whether we are visiting code inside one of the
  /// ui-as-code features. Used to prevent over-reporting uses of these
  /// features.
  bool _inUiAsCode = false;

  /// Initialize a newly created verifier to use the given [_errorReporter] to
  /// report errors.
  SdkConstraintVerifier(this._errorReporter, this._containingLibrary,
      this._typeProvider, this._versionConstraint);

  /// Return a range covering every version up to, but not including, 2.1.0.
  VersionRange get before_2_1_0 =>
      VersionRange(max: Version.parse('2.1.0'), includeMax: false);

  /// Return a range covering every version up to, but not including, 2.2.0.
  VersionRange get before_2_2_0 =>
      VersionRange(max: Version.parse('2.2.0'), includeMax: false);

  /// Return a range covering every version up to, but not including, 2.2.2.
  VersionRange get before_2_2_2 =>
      VersionRange(max: Version.parse('2.2.2'), includeMax: false);

  /// Return a range covering every version up to, but not including, 2.5.0.
  VersionRange get before_2_5_0 =>
      VersionRange(max: Version.parse('2.5.0'), includeMax: false);

  /// Return a range covering every version up to, but not including, 2.6.0.
  VersionRange get before_2_6_0 =>
      VersionRange(max: Version.parse('2.6.0'), includeMax: false);

  /// Return `true` if references to the constant-update-2018 features need to
  /// be checked.
  bool get checkConstantUpdate2018 => _checkConstantUpdate2018 ??=
      !before_2_5_0.intersect(_versionConstraint).isEmpty;

  /// Return `true` if references to the extension method features need to
  /// be checked.
  bool get checkExtensionMethods => _checkExtensionMethods ??=
      !before_2_6_0.intersect(_versionConstraint).isEmpty;

  /// Return `true` if references to Future and Stream need to be checked.
  bool get checkFutureAndStream => _checkFutureAndStream ??=
      !before_2_1_0.intersect(_versionConstraint).isEmpty;

  /// Return `true` if references to the non-nullable features need to be
  /// checked.
  bool get checkNnbd => !_containingLibrary.isNonNullableByDefault;

  /// Return `true` if references to set literals need to be checked.
  bool get checkSetLiterals =>
      _checkSetLiterals ??= !before_2_2_0.intersect(_versionConstraint).isEmpty;

  /// Return `true` if references to the ui-as-code features (control flow and
  /// spread collections) need to be checked.
  bool get checkUiAsCode =>
      _checkUiAsCode ??= !before_2_2_2.intersect(_versionConstraint).isEmpty;

  @override
  void visitAsExpression(AsExpression node) {
    if (checkConstantUpdate2018 &&
        (node as AsExpressionImpl).inConstantContext) {
      _errorReporter.reportErrorForNode(
          HintCode.SDK_VERSION_AS_EXPRESSION_IN_CONST_CONTEXT, node);
    }
    super.visitAsExpression(node);
  }

  @override
  void visitBinaryExpression(BinaryExpression node) {
    if (checkConstantUpdate2018) {
      TokenType operatorType = node.operator.type;
      if (operatorType == TokenType.GT_GT_GT) {
        _errorReporter.reportErrorForToken(
            HintCode.SDK_VERSION_GT_GT_GT_OPERATOR, node.operator);
      } else if ((operatorType == TokenType.AMPERSAND ||
              operatorType == TokenType.BAR ||
              operatorType == TokenType.CARET) &&
          (node as BinaryExpressionImpl).inConstantContext) {
        if (node.leftOperand.typeOrThrow.isDartCoreBool) {
          _errorReporter.reportErrorForToken(
              HintCode.SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT,
              node.operator,
              [node.operator.lexeme]);
        }
      } else if (operatorType == TokenType.EQ_EQ &&
          (node as BinaryExpressionImpl).inConstantContext) {
        bool primitive(Expression node) {
          DartType type = node.typeOrThrow;
          return type.isDartCoreBool ||
              type.isDartCoreDouble ||
              type.isDartCoreInt ||
              type.isDartCoreNull ||
              type.isDartCoreString;
        }

        if (!primitive(node.leftOperand) || !primitive(node.rightOperand)) {
          _errorReporter.reportErrorForToken(
              HintCode.SDK_VERSION_EQ_EQ_OPERATOR_IN_CONST_CONTEXT,
              node.operator);
        }
      }
    }
    super.visitBinaryExpression(node);
  }

  @override
  void visitExtensionDeclaration(ExtensionDeclaration node) {
    if (checkExtensionMethods) {
      _errorReporter.reportErrorForToken(
          HintCode.SDK_VERSION_EXTENSION_METHODS, node.extensionKeyword);
    }
    super.visitExtensionDeclaration(node);
  }

  @override
  void visitExtensionOverride(ExtensionOverride node) {
    if (checkExtensionMethods) {
      _errorReporter.reportErrorForNode(
          HintCode.SDK_VERSION_EXTENSION_METHODS, node.extensionName);
    }
    super.visitExtensionOverride(node);
  }

  @override
  void visitForElement(ForElement node) {
    _validateUiAsCode(node);
    _validateUiAsCodeInConstContext(node);
    bool wasInUiAsCode = _inUiAsCode;
    _inUiAsCode = true;
    super.visitForElement(node);
    _inUiAsCode = wasInUiAsCode;
  }

  @override
  void visitHideCombinator(HideCombinator node) {
    // Don't flag references to either `Future` or `Stream` within a combinator.
  }

  @override
  void visitIfElement(IfElement node) {
    _validateUiAsCode(node);
    _validateUiAsCodeInConstContext(node);
    bool wasInUiAsCode = _inUiAsCode;
    _inUiAsCode = true;
    super.visitIfElement(node);
    _inUiAsCode = wasInUiAsCode;
  }

  @override
  void visitIsExpression(IsExpression node) {
    if (checkConstantUpdate2018 &&
        (node as IsExpressionImpl).inConstantContext) {
      _errorReporter.reportErrorForNode(
          HintCode.SDK_VERSION_IS_EXPRESSION_IN_CONST_CONTEXT, node);
    }
    super.visitIsExpression(node);
  }

  @override
  void visitMethodDeclaration(MethodDeclaration node) {
    if (checkConstantUpdate2018 && node.isOperator && node.name.name == '>>>') {
      _errorReporter.reportErrorForNode(
          HintCode.SDK_VERSION_GT_GT_GT_OPERATOR, node.name);
    }
    super.visitMethodDeclaration(node);
  }

  @override
  void visitSetOrMapLiteral(SetOrMapLiteral node) {
    if (node.isSet && checkSetLiterals && !_inSetLiteral) {
      _errorReporter.reportErrorForNode(HintCode.SDK_VERSION_SET_LITERAL, node);
    }
    bool wasInSetLiteral = _inSetLiteral;
    _inSetLiteral = true;
    super.visitSetOrMapLiteral(node);
    _inSetLiteral = wasInSetLiteral;
  }

  @override
  void visitShowCombinator(ShowCombinator node) {
    // Don't flag references to either `Future` or `Stream` within a combinator.
  }

  @override
  void visitSimpleIdentifier(SimpleIdentifier node) {
    if (node.inDeclarationContext()) {
      return;
    }
    var element = node.staticElement;
    if (checkFutureAndStream &&
        element is ClassElement &&
        (element == _typeProvider.futureElement ||
            element == _typeProvider.streamElement)) {
      for (LibraryElement importedLibrary
          in _containingLibrary.importedLibraries) {
        if (!importedLibrary.isDartCore) {
          var namespace = importedLibrary.exportNamespace;
          if (namespace.get(element.name) != null) {
            return;
          }
        }
      }
      _errorReporter.reportErrorForNode(
          HintCode.SDK_VERSION_ASYNC_EXPORTED_FROM_CORE, node, [element.name]);
    } else if (checkNnbd && element == _typeProvider.neverType.element) {
      _errorReporter.reportErrorForNode(HintCode.SDK_VERSION_NEVER, node);
    }
  }

  @override
  void visitSpreadElement(SpreadElement node) {
    _validateUiAsCode(node);
    _validateUiAsCodeInConstContext(node);
    bool wasInUiAsCode = _inUiAsCode;
    _inUiAsCode = true;
    super.visitSpreadElement(node);
    _inUiAsCode = wasInUiAsCode;
  }

  /// Given that the [node] is only valid when the ui-as-code feature is
  /// enabled, check that the code will not be executed with a version of the
  /// SDK that does not support the feature.
  void _validateUiAsCode(AstNode node) {
    if (checkUiAsCode && !_inUiAsCode) {
      _errorReporter.reportErrorForNode(HintCode.SDK_VERSION_UI_AS_CODE, node);
    }
  }

  /// Given that the [node] is only valid when the ui-as-code feature is
  /// enabled in a const context, check that the code will not be executed with
  /// a version of the SDK that does not support the feature.
  void _validateUiAsCodeInConstContext(AstNode node) {
    if (checkConstantUpdate2018 &&
        !_inUiAsCode &&
        node.thisOrAncestorOfType<TypedLiteral>()!.isConst) {
      _errorReporter.reportErrorForNode(
          HintCode.SDK_VERSION_UI_AS_CODE_IN_CONST_CONTEXT, node);
    }
  }
}
