// Copyright (c) 2015, 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.

/// Defines static information collected by the type checker and used later by
/// emitters to generate code.
// TODO(jmesserly): this was ported from package:dev_compiler, and needs to be
// refactored to fit into analyzer.
library analyzer.src.task.strong.info;

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/type_system.dart';

/// A down cast due to a variable declaration to a ground type:
///
///     T x = expr;
///
/// where `T` is ground.  We exclude non-ground types as these behave
/// differently compared to standard Dart.
class AssignmentCast extends DownCast {
  AssignmentCast(TypeSystem rules, Expression expression, DartType fromType,
      DartType toType)
      : super._internal(rules, expression, fromType, toType);

  @override
  String get name => 'STRONG_MODE_ASSIGNMENT_CAST';

  toErrorCode() => new HintCode(name, message);
}

/// Implicitly injected expression conversion.
abstract class CoercionInfo extends StaticInfo {
  static const String _propertyName = 'dev_compiler.src.info.CoercionInfo';

  final TypeSystem rules;

  final Expression node;

  CoercionInfo(this.rules, this.node);

  DartType get baseType => node.staticType ?? DynamicTypeImpl.instance;
  DartType get convertedType;

  String get message;
  DartType get staticType => convertedType;

  toErrorCode() => new HintCode(name, message);

  /// Gets the coercion info associated with this node.
  static CoercionInfo get(AstNode node) => node.getProperty(_propertyName);

  /// Sets the coercion info associated with this node.
  static CoercionInfo set(AstNode node, CoercionInfo info) {
    node.setProperty(_propertyName, info);
    return info;
  }
}

/// Base class for all casts from base type to sub type.
abstract class DownCast extends CoercionInfo {
  final DartType _fromType;
  final DartType _toType;

  DownCast._internal(
      TypeSystem rules, Expression expression, this._fromType, this._toType)
      : super(rules, expression);

  @override
  List<Object> get arguments => [baseType, convertedType];

  /// The type being cast from.
  ///
  /// This is usually the static type of the associated expression, but may not
  /// be if the cast is attached to a variable in a for-in loop.
  @override
  DartType get baseType => _fromType;

  DartType get convertedType => _toType;

  @override
  String get message => 'Unsound implicit cast from {0} to {1}';

  /// Factory to create correct DownCast variant.
  static StaticInfo create(StrongTypeSystemImpl rules, Expression expression,
      DartType fromType, DartType toType) {
    // toT <:_R fromT => to <: fromT
    // NB: classes with call methods are subtypes of function
    // types, but the function type is not assignable to the class
    assert(toType.isSubtypeOf(fromType) || fromType.isAssignableTo(toType));

    // Inference "casts":
    if (expression is Literal || expression is FunctionExpression) {
      // fromT should be an exact type - this will almost certainly fail at
      // runtime.
      return new StaticTypeError(rules, expression, toType);
    }

    if (expression is InstanceCreationExpression) {
      ConstructorElement e = expression.staticElement;
      if (e == null || !e.isFactory) {
        // fromT should be an exact type - this will almost certainly fail at
        // runtime.
        return new StaticTypeError(rules, expression, toType);
      }
    }

    if (StaticInfo.isKnownFunction(expression)) {
      return new StaticTypeError(rules, expression, toType);
    }

    // TODO(vsm): Change this to an assert when we have generic methods and
    // fix TypeRules._coerceTo to disallow implicit sideways casts.
    if (!rules.isSubtypeOf(toType, fromType)) {
      assert(toType.isSubtypeOf(fromType) || fromType.isAssignableTo(toType));
      return new DownCastComposite(rules, expression, fromType, toType);
    }

    // Composite cast: these are more likely to fail.
    if (!rules.isGroundType(toType)) {
      // This cast is (probably) due to our different treatment of dynamic.
      // It may be more likely to fail at runtime.
      if (fromType is InterfaceType) {
        // For class types, we'd like to allow non-generic down casts, e.g.,
        // Iterable<T> to List<T>.  The intuition here is that raw (generic)
        // casts are problematic, and we should complain about those.
        var typeArgs = fromType.typeArguments;
        if (typeArgs.isEmpty || typeArgs.any((t) => t.isDynamic)) {
          return new DownCastComposite(rules, expression, fromType, toType);
        }
      } else {
        return new DownCastComposite(rules, expression, fromType, toType);
      }
    }

    // Dynamic cast
    if (fromType.isDynamic) {
      return new DynamicCast(rules, expression, fromType, toType);
    }

    // Assignment cast
    var parent = expression.parent;
    if (parent is VariableDeclaration && (parent.initializer == expression)) {
      return new AssignmentCast(rules, expression, fromType, toType);
    }

    // Other casts
    return new DownCastImplicit(rules, expression, fromType, toType);
  }
}

/// Implicit down casts.  These are only injected by the compiler by flag.
///
/// A down cast to a non-ground type.  These behave differently from standard
/// Dart and may be more likely to fail at runtime.
class DownCastComposite extends DownCast {
  DownCastComposite(TypeSystem rules, Expression expression, DartType fromType,
      DartType toType)
      : super._internal(rules, expression, fromType, toType);

  @override
  String get name => 'STRONG_MODE_DOWN_CAST_COMPOSITE';

  toErrorCode() => new StaticWarningCode(name, message);
}

/// A down cast to a non-ground type.  These behave differently from standard
/// Dart and may be more likely to fail at runtime.
class DownCastImplicit extends DownCast {
  DownCastImplicit(TypeSystem rules, Expression expression, DartType fromType,
      DartType toType)
      : super._internal(rules, expression, fromType, toType);

  @override
  String get name => 'STRONG_MODE_DOWN_CAST_IMPLICIT';

  toErrorCode() => new HintCode(name, message);
}

/// A down cast from dynamic to T.
class DynamicCast extends DownCast {
  DynamicCast(TypeSystem rules, Expression expression, DartType fromType,
      DartType toType)
      : super._internal(rules, expression, fromType, toType);

  @override
  String get name => 'STRONG_MODE_DYNAMIC_CAST';

  toErrorCode() => new HintCode(name, message);
}

class DynamicInvoke extends CoercionInfo {
  static const String _propertyName = 'dev_compiler.src.info.DynamicInvoke';

  DynamicInvoke(TypeSystem rules, Expression expression)
      : super(rules, expression);
  DartType get convertedType => DynamicTypeImpl.instance;
  String get message => '{0} requires dynamic invoke';

  @override
  String get name => 'STRONG_MODE_DYNAMIC_INVOKE';

  toErrorCode() => new HintCode(name, message);

  /// Whether this [node] is the target of a dynamic operation.
  static bool get(AstNode node) => node.getProperty(_propertyName) ?? false;

  /// Sets whether this node is the target of a dynamic operation.
  static bool set(AstNode node, bool value) {
    // Free the storage for things that aren't dynamic.
    if (value == false) value = null;
    node.setProperty(_propertyName, value);
    return value;
  }
}

/// Standard / unspecialized inferred type.
class InferredType extends InferredTypeBase {
  InferredType(TypeSystem rules, Expression expression, DartType type)
      : super._internal(rules, expression, type);

  @override
  String get name => 'STRONG_MODE_INFERRED_TYPE';

  /// Factory to create correct InferredType variant.
  static InferredTypeBase create(
      TypeSystem rules, Expression expression, DartType type) {
    // Specialized inference:
    if (expression is Literal) {
      return new InferredTypeLiteral(rules, expression, type);
    }
    if (expression is InstanceCreationExpression) {
      return new InferredTypeAllocation(rules, expression, type);
    }
    if (expression is FunctionExpression) {
      return new InferredTypeClosure(rules, expression, type);
    }
    return new InferredType(rules, expression, type);
  }
}

/// An inferred type for a non-literal allocation site.
class InferredTypeAllocation extends InferredTypeBase {
  InferredTypeAllocation(TypeSystem rules, Expression expression, DartType type)
      : super._internal(rules, expression, type);

  @override
  String get name => 'STRONG_MODE_INFERRED_TYPE_ALLOCATION';
}

/// An inferred type for the wrapped expression, which may need to be
/// reified into the term.
abstract class InferredTypeBase extends CoercionInfo {
  final DartType _type;

  InferredTypeBase._internal(
      TypeSystem rules, Expression expression, this._type)
      : super(rules, expression);

  @override
  List get arguments => [node, type];
  DartType get convertedType => type;
  @override
  String get message => '{0} has inferred type {1}';
  DartType get type => _type;

  toErrorCode() => new HintCode(name, message);
}

/// An inferred type for a closure expression.
class InferredTypeClosure extends InferredTypeBase {
  InferredTypeClosure(TypeSystem rules, Expression expression, DartType type)
      : super._internal(rules, expression, type);

  @override
  String get name => 'STRONG_MODE_INFERRED_TYPE_CLOSURE';
}

/// An inferred type for a literal expression.
class InferredTypeLiteral extends InferredTypeBase {
  InferredTypeLiteral(TypeSystem rules, Expression expression, DartType type)
      : super._internal(rules, expression, type);

  @override
  String get name => 'STRONG_MODE_INFERRED_TYPE_LITERAL';
}

class InvalidFieldOverride extends InvalidOverride {
  InvalidFieldOverride(AstNode node, ExecutableElement element,
      InterfaceType base, DartType subType, DartType baseType)
      : super(node, element, base, subType, baseType);

  String get message => 'Field declaration {3}.{1} cannot be '
      'overridden in {0}.';

  @override
  String get name => 'STRONG_MODE_INVALID_FIELD_OVERRIDE';
}

/// Invalid override due to incompatible type.  I.e., the overridden signature
/// is not compatible with the original.
class InvalidMethodOverride extends InvalidOverride {
  InvalidMethodOverride(AstNode node, ExecutableElement element,
      InterfaceType base, FunctionType subType, FunctionType baseType)
      : super(node, element, base, subType, baseType);

  String get message => _messageHelper('Invalid override');

  @override
  String get name => 'STRONG_MODE_INVALID_METHOD_OVERRIDE';
}

/// Invalid override of an instance member of a class.
abstract class InvalidOverride extends StaticError {
  /// Member declaration with the invalid override.
  final ExecutableElement element;

  /// Type (class or interface) that provides the base declaration.
  final InterfaceType base;

  /// Actual type of the overridden member.
  final DartType subType;

  /// Actual type of the base member.
  final DartType baseType;

  /// Whether the error comes from combining a base class and an interface
  final bool fromBaseClass;

  /// Whether the error comes from a mixin (either overriding a base class or an
  /// interface declaration).
  final bool fromMixin;

  InvalidOverride(
      AstNode node, this.element, this.base, this.subType, this.baseType)
      : fromBaseClass = node is ExtendsClause,
        fromMixin = node.parent is WithClause,
        super(node);

  @override
  List<Object> get arguments =>
      [parent.name, element.name, subType, base, baseType];

  ClassElement get parent => element.enclosingElement;

  String _messageHelper(String errorName) {
    var lcErrorName = errorName.toLowerCase();
    var intro = fromBaseClass
        ? 'Base class introduces an $lcErrorName'
        : (fromMixin ? 'Mixin introduces an $lcErrorName' : errorName);
    return '$intro. The type of {0}.{1} ({2}) is not a '
        'subtype of {3}.{1} ({4}).';
  }
}

class InvalidParameterDeclaration extends StaticError {
  final DartType expectedType;

  InvalidParameterDeclaration(
      TypeSystem rules, FormalParameter declaration, this.expectedType)
      : super(declaration);

  @override
  List<Object> get arguments => [node, expectedType];
  @override
  String get message => 'Type check failed: {0} is not of type {1}';
  @override
  String get name => 'STRONG_MODE_INVALID_PARAMETER_DECLARATION';
}

/// Dart constructors have one weird quirk, illustrated with this example:
///
///     class Base {
///       var x;
///       Base() : x = print('Base.1') {
///         print('Base.2');
///       }
///     }
///
///     class Derived extends Base {
///       var y, z;
///       Derived()
///           : y = print('Derived.1'),
///             super(),
///             z = print('Derived.2') {
///         print('Derived.3');
///       }
///     }
///
/// The order will be Derived.1, Base.1, Derived.2, Base.2, Derived.3; this
/// ordering preserves the invariant that code can't observe uninitialized
/// state, however it results in super constructor body not being run
/// immediately after super initializers. Normally this isn't observable, but it
/// could be if initializers have side effects.
///
/// Better to have `super` at the end, as required by the Dart style guide:
/// <https://goo.gl/EY6hDP>
///
/// For now this is the only pattern we support.
class InvalidSuperInvocation extends StaticError {
  InvalidSuperInvocation(SuperConstructorInvocation node) : super(node);

  @override
  String get message => "super call must be last in an initializer "
      "list (see https://goo.gl/EY6hDP): {0}";

  @override
  String get name => 'STRONG_MODE_INVALID_SUPER_INVOCATION';
}

class InvalidVariableDeclaration extends StaticError {
  final DartType expectedType;

  InvalidVariableDeclaration(
      TypeSystem rules, AstNode declaration, this.expectedType)
      : super(declaration);

  @override
  List<Object> get arguments => [expectedType];
  @override
  String get message => 'Type check failed: null is not of type {0}';

  @override
  String get name => 'STRONG_MODE_INVALID_VARIABLE_DECLARATION';
}

class NonGroundTypeCheckInfo extends StaticInfo {
  final DartType type;
  final AstNode node;

  NonGroundTypeCheckInfo(this.node, this.type) {
    assert(node is IsExpression || node is AsExpression);
  }

  @override
  List<Object> get arguments => [type];
  String get message =>
      "Runtime check on non-ground type {0} may throw StrongModeError";

  @override
  String get name => 'STRONG_MODE_NON_GROUND_TYPE_CHECK_INFO';

  toErrorCode() => new HintCode(name, message);
}

abstract class StaticError extends StaticInfo {
  final AstNode node;

  StaticError(this.node);

  String get message;

  toErrorCode() => new CompileTimeErrorCode(name, message);
}

// TODO(jmesserly): this could use some refactoring. These are essentially
// like ErrorCodes in analyzer, but we're including some details in our message.
// Analyzer instead has template strings, and replaces '{0}' with the first
// argument.
abstract class StaticInfo {
  /// Strong-mode error code names.
  ///
  /// Used for error code configuration validation in an analysis options file.
  static const List<String> names = const [
    //
    // Manually populated.
    //
    'STRONG_MODE_ASSIGNMENT_CAST',
    'STRONG_MODE_DOWN_CAST_COMPOSITE',
    'STRONG_MODE_DOWN_CAST_IMPLICIT',
    'STRONG_MODE_DYNAMIC_CAST',
    'STRONG_MODE_DYNAMIC_INVOKE',
    'STRONG_MODE_INFERRED_TYPE',
    'STRONG_MODE_INFERRED_TYPE_ALLOCATION',
    'STRONG_MODE_INFERRED_TYPE_CLOSURE',
    'STRONG_MODE_INFERRED_TYPE_LITERAL',
    'STRONG_MODE_INVALID_FIELD_OVERRIDE',
    'STRONG_MODE_INVALID_METHOD_OVERRIDE',
    'STRONG_MODE_INVALID_PARAMETER_DECLARATION',
    'STRONG_MODE_INVALID_SUPER_INVOCATION',
    'STRONG_MODE_INVALID_VARIABLE_DECLARATION',
    'STRONG_MODE_NON_GROUND_TYPE_CHECK_INFO',
    'STRONG_MODE_STATIC_TYPE_ERROR',
    'STRONG_MODE_UNINFERRED_CLOSURE',
  ];

  List<Object> get arguments => [node];

  String get name;

  /// AST Node this info is attached to.
  AstNode get node;

  AnalysisError toAnalysisError() {
    int begin = node is AnnotatedNode
        ? (node as AnnotatedNode).firstTokenAfterCommentAndMetadata.offset
        : node.offset;
    int length = node.end - begin;
    var source = (node.root as CompilationUnit).element.source;
    return new AnalysisError(source, begin, length, toErrorCode(), arguments);
  }

  // TODO(jmesserly): review the usage of error codes. We probably want our own,
  // as well as some DDC specific [ErrorType]s.
  ErrorCode toErrorCode();

  static bool isKnownFunction(Expression expression) {
    Element element = null;
    if (expression is FunctionExpression) {
      return true;
    } else if (expression is PropertyAccess) {
      element = expression.propertyName.staticElement;
    } else if (expression is Identifier) {
      element = expression.staticElement;
    }
    // First class functions and static methods, where we know the original
    // declaration, will have an exact type, so we know a downcast will fail.
    return element is FunctionElement ||
        element is MethodElement && element.isStatic;
  }
}

class StaticTypeError extends StaticError {
  final DartType baseType;
  final DartType expectedType;

  StaticTypeError(TypeSystem rules, Expression expression, this.expectedType)
      : baseType = expression.staticType ?? DynamicTypeImpl.instance,
        super(expression);

  @override
  List<Object> get arguments => [node, baseType, expectedType];
  @override
  String get message => 'Type check failed: {0} ({1}) is not of type {2}';

  @override
  String get name => 'STRONG_MODE_STATIC_TYPE_ERROR';
}
