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

@deprecated
library analyzer.test.constant_test;

import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/constant.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../src/dart/resolution/context_collection_resolution.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(ConstantEvaluatorTest);
  });
}

@reflectiveTest
class ConstantEvaluatorTest extends PubPackageResolutionTest {
  void assertTypeArguments(DartObject value, List<String>? typeArgumentNames) {
    var typeArguments = (value as DartObjectImpl).typeArguments;
    if (typeArguments == null) {
      expect(typeArguments, typeArgumentNames);
      return;
    }
    expect(
      typeArguments.map((arg) => arg.getDisplayString(withNullability: true)),
      equals(typeArgumentNames),
    );
  }

  test_bitAnd_int_int() async {
    await _assertValueInt(74 & 42, "74 & 42");
  }

  test_bitNot() async {
    await _assertValueInt(~42, "~42");
  }

  test_bitOr_int_int() async {
    await _assertValueInt(74 | 42, "74 | 42");
  }

  test_bitXor_int_int() async {
    await _assertValueInt(74 ^ 42, "74 ^ 42");
  }

  test_conditionalExpression_unknownCondition_dynamic() async {
    await assertErrorsInCode('''
const bool kIsWeb = identical(0, 0.0);
const x = kIsWeb ? a : b;
''', [
      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 58,
          1),
      error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 58, 1),
      error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 62, 1),
      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 62,
          1),
    ]);

    var x_result = findElement.topVar('x').evaluationResult;
    assertDartObjectText(x_result.value, r'''
dynamic <unknown>
''');
  }

  test_constructorInvocation_fieldInitializer() async {
    var result = await _getExpressionValue("const C(2)", context: '''
class C {
  final int x;
  const C(this.x);
}
''');
    expect(result.isValid, isTrue);
    DartObject value = result.value!;
    assertType(value.type, 'C');
    DartObject x = value.getField('x')!;
    assertType(x.type, 'int');
    expect(x.toIntValue(), 2);
  }

  test_constructorInvocation_noArgs() async {
    var result = await _getExpressionValue(
      "const C()",
      context: 'class C {const C();}',
    );
    expect(result.isValid, isTrue);
    DartObject value = result.value!;
    assertType(value.type, 'C');
  }

  test_constructorInvocation_noConstConstructor() async {
    var result = await _getExpressionValue(
      "const C()",
      context: 'class C {}',
    );
    expect(result.isValid, isFalse);
    var value = result.value;
    expect(value, isNull);
  }

  test_constructorInvocation_simpleArgs() async {
    var result = await _getExpressionValue("const C(1)", context: '''
class C {
  const C(int x);
}
''');
    expect(result.isValid, isTrue);
    DartObject value = result.value!;
    assertType(value.type, 'C');
  }

  test_constructorReference_generic_named() async {
    var result = await _getExpressionValue("C<int>.foo", context: '''
class C<T> {
  C.foo();
}
''');
    expect(result.isValid, isTrue);
    DartObject value = result.value!;
    assertType(value.type, 'C<int> Function()');
  }

  test_constructorReference_generic_unnamed() async {
    var result = await _getExpressionValue("C<int>.new", context: '''
class C<T> {
  C.new();
}
''');
    expect(result.isValid, isTrue);
    DartObject value = result.value!;
    assertType(value.type, 'C<int> Function()');
  }

  test_constructorReference_nonGeneric_named() async {
    var result = await _getExpressionValue("C.foo", context: '''
class C {
  const C.foo();
}
''');
    expect(result.isValid, isTrue);
    DartObject value = result.value!;
    assertType(value.type, 'C Function()');
  }

  test_constructorReference_nonGeneric_unnamed() async {
    var result = await _getExpressionValue("C.new", context: '''
class C {
  const C();
}
''');
    expect(result.isValid, isTrue);
    DartObject value = result.value!;
    assertType(value.type, 'C Function()');
  }

  test_divide_double_double() async {
    await _assertValueDouble(3.2 / 2.3, "3.2 / 2.3");
  }

  test_divide_double_double_byZero() async {
    var result = await _getExpressionValue("3.2 / 0.0");
    expect(result.isValid, isTrue);
    DartObject value = result.value!;
    assertType(value.type, "double");
    expect(value.toDoubleValue()!.isInfinite, isTrue);
  }

  test_divide_int_int() async {
    await _assertValueDouble(1.5, "3 / 2");
  }

  test_divide_int_int_byZero() async {
    var result = await _getExpressionValue("3 / 0");
    expect(result.isValid, isTrue);
  }

  test_equal_boolean_boolean() async {
    await _assertValueBool(false, "true == false");
  }

  test_equal_int_int() async {
    await _assertValueBool(false, "2 == 3");
  }

  test_equal_invalidLeft() async {
    var result = await _getExpressionValue("a == 3");
    expect(result.isValid, isFalse);
  }

  test_equal_invalidRight() async {
    var result = await _getExpressionValue("2 == a");
    expect(result.isValid, isFalse);
  }

  test_equal_string_string() async {
    await _assertValueBool(false, "'a' == 'b'");
  }

  test_greaterThan_int_int() async {
    await _assertValueBool(false, "2 > 3");
  }

  test_greaterThanOrEqual_int_int() async {
    await _assertValueBool(false, "2 >= 3");
  }

  @failingTest
  test_identifier_class() async {
    var result = await _getExpressionValue("?");
    expect(result.isValid, isTrue);
    var value = result.value;
    expect(value, null);
  }

  @failingTest
  test_identifier_function() async {
    var result = await _getExpressionValue("?");
    expect(result.isValid, isTrue);
    var value = result.value;
    expect(value, null);
  }

  @failingTest
  test_identifier_static() async {
    var result = await _getExpressionValue("?");
    expect(result.isValid, isTrue);
    var value = result.value;
    expect(value, null);
  }

  @failingTest
  test_identifier_staticMethod() async {
    var result = await _getExpressionValue("?");
    expect(result.isValid, isTrue);
    var value = result.value;
    expect(value, null);
  }

  @failingTest
  test_identifier_topLevel() async {
    var result = await _getExpressionValue("?");
    expect(result.isValid, isTrue);
    var value = result.value;
    expect(value, null);
  }

  @failingTest
  test_identifier_typeParameter() async {
    var result = await _getExpressionValue("?");
    expect(result.isValid, isTrue);
    var value = result.value;
    expect(value, null);
  }

  test_lessThan_int_int() async {
    await _assertValueBool(true, "2 < 3");
  }

  test_lessThanOrEqual_int_int() async {
    await _assertValueBool(true, "2 <= 3");
  }

  test_literal_boolean_false() async {
    await _assertValueBool(false, "false");
  }

  test_literal_boolean_true() async {
    await _assertValueBool(true, "true");
  }

  test_literal_list() async {
    var result = await _getExpressionValue("const ['a', 'b', 'c']");
    expect(result.isValid, isTrue);
  }

  test_literal_list_explicitType() async {
    var result = await _getExpressionValue("const <String>['a', 'b', 'c']");
    expect(result.isValid, isTrue);
  }

  test_literal_list_explicitType_functionType() async {
    var result = await _getExpressionValue("const <void Function()>[]");
    expect(result.isValid, isTrue);
  }

  test_literal_list_forElement() async {
    var result = await _getExpressionValue('''
const [for (var i = 0; i < 4; i++) i]
''');
    expect(result.isValid, isFalse);
    expect(result.errors, isNotEmpty);
  }

  test_literal_map() async {
    var result = await _getExpressionValue(
      "const {'a' : 'm', 'b' : 'n', 'c' : 'o'}",
    );
    expect(result.isValid, isTrue);
    var map = result.value!.toMapValue()!;
    expect(map.keys.map((k) => k!.toStringValue()), ['a', 'b', 'c']);
  }

  test_literal_null() async {
    var result = await _getExpressionValue("null");
    expect(result.isValid, isTrue);
    DartObject value = result.value!;
    expect(value.isNull, isTrue);
  }

  test_literal_number_double() async {
    await _assertValueDouble(3.45, "3.45");
  }

  test_literal_number_integer() async {
    await _assertValueInt(42, "42");
  }

  test_literal_string_adjacent() async {
    await _assertValueString("abcdef", "'abc' 'def'");
  }

  test_literal_string_interpolation_invalid() async {
    var result = await _getExpressionValue("'a\${f()}c'");
    expect(result.isValid, isFalse);
  }

  test_literal_string_interpolation_valid() async {
    await _assertValueString("a3c", "'a\${3}c'");
  }

  test_literal_string_simple() async {
    await _assertValueString("abc", "'abc'");
  }

  test_logicalAnd() async {
    await _assertValueBool(false, "true && false");
  }

  test_logicalNot() async {
    await _assertValueBool(false, "!true");
  }

  test_logicalOr() async {
    await _assertValueBool(true, "true || false");
  }

  test_minus_double_double() async {
    await _assertValueDouble(3.2 - 2.3, "3.2 - 2.3");
  }

  test_minus_int_int() async {
    await _assertValueInt(1, "3 - 2");
  }

  test_negated_boolean() async {
    var result = await _getExpressionValue("-true");
    expect(result.isValid, isFalse);
  }

  test_negated_double() async {
    await _assertValueDouble(-42.3, "-42.3");
  }

  test_negated_integer() async {
    await _assertValueInt(-42, "-42");
  }

  test_notEqual_boolean_boolean() async {
    await _assertValueBool(true, "true != false");
  }

  test_notEqual_int_int() async {
    await _assertValueBool(true, "2 != 3");
  }

  test_notEqual_invalidLeft() async {
    var result = await _getExpressionValue("a != 3");
    expect(result.isValid, isFalse);
  }

  test_notEqual_invalidRight() async {
    var result = await _getExpressionValue("2 != a");
    expect(result.isValid, isFalse);
  }

  test_notEqual_string_string() async {
    await _assertValueBool(true, "'a' != 'b'");
  }

  test_object_enum() async {
    await resolveTestCode('''
enum E { v1, v2 }
const x1 = E.v1;
const x2 = E.v2;
''');

    _assertTopVarConstValue('x1', r'''
E
  _name: String v1
  index: int 0
''');

    _assertTopVarConstValue('x2', r'''
E
  _name: String v2
  index: int 1
''');
  }

  /// Enum constants can reference other constants.
  test_object_enum_enhanced_constants() async {
    await assertNoErrorsInCode('''
enum E {
  v1(42), v2(v1);
  final Object? a;
  const E([this.a]);
}
''');

    assertDartObjectText(findElement.field('v2').evaluationResult.value, r'''
E
  _name: String v2
  a: E
    _name: String v1
    a: int 42
    index: int 0
  index: int 1
''');
  }

  test_object_enum_enhanced_named() async {
    await resolveTestCode('''
enum E<T> {
  v1<double>.named(10),
  v2.named(20);
  final T f;
  const E.named(this.f);
}

const x1 = E.v1;
const x2 = E.v2;
''');

    _assertTopVarConstValue('x1', r'''
E<double>
  _name: String v1
  f: double 10.0
  index: int 0
''');

    _assertTopVarConstValue('x2', r'''
E<int>
  _name: String v2
  f: int 20
  index: int 1
''');
  }

  test_object_enum_enhanced_unnamed() async {
    await resolveTestCode('''
enum E<T> {
  v1<int>(10),
  v2(20),
  v3('abc');
  final T f;
  const E(this.f);
}

const x1 = E.v1;
const x2 = E.v2;
const x3 = E.v3;
''');

    _assertTopVarConstValue('x1', r'''
E<int>
  _name: String v1
  f: int 10
  index: int 0
''');

    _assertTopVarConstValue('x2', r'''
E<int>
  _name: String v2
  f: int 20
  index: int 1
''');

    _assertTopVarConstValue('x3', r'''
E<String>
  _name: String v3
  f: String abc
  index: int 2
''');
  }

  test_parenthesizedExpression() async {
    await _assertValueString("a", "('a')");
  }

  test_plus_double_double() async {
    await _assertValueDouble(2.3 + 3.2, "2.3 + 3.2");
  }

  test_plus_int_int() async {
    await _assertValueInt(5, "2 + 3");
  }

  test_plus_string_string() async {
    await _assertValueString("ab", "'a' + 'b'");
  }

  @failingTest
  test_prefixedIdentifier_invalid() async {
    var result = await _getExpressionValue("?");
    expect(result.isValid, isTrue);
    var value = result.value;
    expect(value, null);
  }

  @failingTest
  test_prefixedIdentifier_valid() async {
    var result = await _getExpressionValue("?");
    expect(result.isValid, isTrue);
    var value = result.value;
    expect(value, null);
  }

  @failingTest
  test_propertyAccess_invalid() async {
    var result = await _getExpressionValue("?");
    expect(result.isValid, isTrue);
    var value = result.value;
    expect(value, null);
  }

  @failingTest
  test_propertyAccess_valid() async {
    var result = await _getExpressionValue("?");
    expect(result.isValid, isTrue);
    var value = result.value;
    expect(value, null);
  }

  @failingTest
  test_simpleIdentifier_invalid() async {
    var result = await _getExpressionValue("?");
    expect(result.isValid, isTrue);
    var value = result.value;
    expect(value, null);
  }

  @failingTest
  test_simpleIdentifier_valid() async {
    var result = await _getExpressionValue("?");
    expect(result.isValid, isTrue);
    var value = result.value;
    expect(value, null);
  }

  test_stringLength_complex() async {
    await _assertValueInt(6, "('qwe' + 'rty').length");
  }

  test_stringLength_simple() async {
    await _assertValueInt(6, "'Dvorak'.length");
  }

  test_superFormalParameter_explicitSuper_hasNamedArgument_requiredNamed() async {
    await assertNoErrorsInCode('''
class A {
  final int a;
  final int b;
  const A({required this.a, required this.b});
}

class B extends A {
  final int c;
  const B(this.c, {required super.b}) : super(a: 1);
}

const x = B(3, b: 2);
''');

    var value = findElement.topVar('x').evaluationResult.value;
    assertDartObjectText(value, r'''
B
  (super): A
    a: int 1
    b: int 2
  c: int 3
''');
  }

  test_superFormalParameter_explicitSuper_hasNamedArgument_requiredPositional() async {
    await assertNoErrorsInCode('''
class A {
  final int a;
  final int b;
  const A(this.a, {required this.b});
}

class B extends A {
  final int c;
  const B(super.a, {required this.c}) : super(b: 2);
}

const x = B(1, c: 3);
''');

    var value = findElement.topVar('x').evaluationResult.value;
    assertDartObjectText(value, r'''
B
  (super): A
    a: int 1
    b: int 2
  c: int 3
''');
  }

  test_superFormalParameter_explicitSuper_requiredNamed() async {
    await assertNoErrorsInCode('''
class A {
  final int a;
  const A({required this.a});
}

class B extends A {
  final int b;
  const B(this.b, {required super.a}) : super();
}

const x = B(2, a: 1);
''');

    var value = findElement.topVar('x').evaluationResult.value;
    assertDartObjectText(value, r'''
B
  (super): A
    a: int 1
  b: int 2
''');
  }

  test_superFormalParameter_explicitSuper_requiredPositional() async {
    await assertNoErrorsInCode('''
class A {
  final int a;
  const A(this.a);
}

class B extends A {
  final int b;
  const B(super.a, this.b) : super();
}

const x = B(1, 2);
''');

    var value = findElement.topVar('x').evaluationResult.value;
    assertDartObjectText(value, r'''
B
  (super): A
    a: int 1
  b: int 2
''');
  }

  test_superFormalParameter_implicitSuper_requiredNamed() async {
    await assertNoErrorsInCode('''
class A {
  final int a;
  const A({required this.a});
}

class B extends A {
  final int b;
  const B(this.b, {required super.a});
}

const x = B(2, a: 1);
''');

    var value = findElement.topVar('x').evaluationResult.value;
    assertDartObjectText(value, r'''
B
  (super): A
    a: int 1
  b: int 2
''');
  }

  test_superFormalParameter_implicitSuper_requiredPositional() async {
    await assertNoErrorsInCode('''
class A {
  final int a;
  const A(this.a);
}

class B extends A {
  final int b;
  const B(super.a, this.b);
}

const x = B(1, 2);
''');

    var value = findElement.topVar('x').evaluationResult.value;
    assertDartObjectText(value, r'''
B
  (super): A
    a: int 1
  b: int 2
''');
  }

  void _assertTopVarConstValue(String name, String expected) {
    assertDartObjectText(_topVarConstResult(name).value, expected);
  }

  Future<void> _assertValueBool(bool expectedValue, String contents) async {
    var result = await _getExpressionValue(contents);
    DartObject value = result.value!;
    assertType(value.type, "bool");
    expect(value.toBoolValue(), expectedValue);
  }

  Future<void> _assertValueDouble(double expectedValue, String contents) async {
    var result = await _getExpressionValue(contents);
    expect(result.isValid, isTrue);
    DartObject value = result.value!;
    assertType(value.type, "double");
    expect(value.toDoubleValue(), expectedValue);
  }

  Future<void> _assertValueInt(int expectedValue, String contents) async {
    var result = await _getExpressionValue(contents);
    expect(result.isValid, isTrue);
    DartObject value = result.value!;
    assertType(value.type, "int");
    expect(value.toIntValue(), expectedValue);
  }

  Future<void> _assertValueString(String expectedValue, String contents) async {
    var result = await _getExpressionValue(contents);
    DartObject value = result.value!;
    assertType(value.type, 'String');
  }

  Future<EvaluationResult> _getExpressionValue(String expressionCode,
      {String context = ''}) async {
    await resolveTestCode('''
var x = $expressionCode;

$context
''');

    var expression = findNode.variableDeclaration('x =').initializer!;

    var file = getFile(result.path);
    var evaluator = ConstantEvaluator(
      file.createSource(result.uri),
      result.libraryElement as LibraryElementImpl,
    );

    return evaluator.evaluate(expression);
  }

  EvaluationResultImpl _topVarConstResult(String name) {
    var element = findElement.topVar(name) as ConstTopLevelVariableElementImpl;
    return element.evaluationResult!;
  }
}

extension on VariableElement {
  EvaluationResultImpl get evaluationResult {
    var constVariable = this as ConstVariableElement;
    var evaluationResult = constVariable.evaluationResult;
    if (evaluationResult == null) {
      fail('Not evaluated: $this');
    }
    return evaluationResult;
  }
}
