// 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.

library analyzer.test.src.summary.resynthesize_ast_test;

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/generated/engine.dart'
    show AnalysisContext, AnalysisOptionsImpl;
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/link.dart';
import 'package:analyzer/src/summary/prelink.dart';
import 'package:analyzer/src/summary/resynthesize.dart';
import 'package:analyzer/src/summary/summarize_ast.dart';
import 'package:analyzer/src/summary/summarize_elements.dart'
    show PackageBundleAssembler;
import 'package:analyzer/task/dart.dart' show PARSED_UNIT;
import 'package:unittest/unittest.dart';

import '../../reflective_tests.dart';
import '../context/abstract_context.dart';
import '../task/strong/inferred_type_test.dart';
import 'resynthesize_test.dart';
import 'summary_common.dart';

main() {
  groupSep = ' | ';
  runReflectiveTests(ResynthesizeAstTest);
  runReflectiveTests(AstInferredTypeTest);
}

@reflectiveTest
class AstInferredTypeTest extends AbstractResynthesizeTest
    with _AstResynthesizeTestMixin, InferredTypeMixin {
  bool get checkPropagatedTypes {
    // AST-based summaries do not yet handle propagated types.
    // TODO(paulberry): fix this.
    return false;
  }

  @override
  bool get mayCheckTypesOfLocals => false;

  @override
  bool get skipBrokenAstInference => true;

  @override
  void addFile(String content, {String name: '/main.dart'}) {
    addLibrarySource(name, content);
  }

  @override
  CompilationUnitElement checkFile(String content) {
    Source source = addSource('/main.dart', content);
    SummaryResynthesizer resynthesizer = _encodeLibrary(source);
    LibraryElementImpl resynthesized = _checkSource(resynthesizer, source);
    for (Source otherSource in otherLibrarySources) {
      _checkSource(resynthesizer, otherSource);
    }
    return resynthesized.definingCompilationUnit;
  }

  @override
  void compareLocalElementsOfExecutable(ExecutableElement resynthesized,
      ExecutableElement original, String desc) {
    // We don't resynthesize local elements during link.
    // So, we should not compare them.
  }

  @override
  DartSdk createDartSdk() => AbstractContextTest.SHARED_STRONG_MOCK_SDK;

  @override
  AnalysisOptionsImpl createOptions() => new AnalysisOptionsImpl()
    ..enableGenericMethods = true
    ..strongMode = true;

  @override
  @failingTest
  void test_blockBodiedLambdas_async_allReturnsAreFutures_topLevel() {
    super.test_blockBodiedLambdas_async_allReturnsAreFutures_topLevel();
  }

  @override
  @failingTest
  void test_blockBodiedLambdas_async_allReturnsAreValues_topLevel() {
    super.test_blockBodiedLambdas_async_allReturnsAreValues_topLevel();
  }

  @override
  @failingTest
  void test_blockBodiedLambdas_async_mixOfValuesAndFutures_topLevel() {
    super.test_blockBodiedLambdas_async_mixOfValuesAndFutures_topLevel();
  }

  @override
  @failingTest
  void test_blockBodiedLambdas_asyncStar_topLevel() {
    super.test_blockBodiedLambdas_asyncStar_topLevel();
  }

  @override
  @failingTest
  void test_blockBodiedLambdas_basic_topLevel() {
    super.test_blockBodiedLambdas_basic_topLevel();
  }

  @override
  @failingTest
  void test_blockBodiedLambdas_doesNotInferBottom_async_topLevel() {
    super.test_blockBodiedLambdas_doesNotInferBottom_async_topLevel();
  }

  @override
  @failingTest
  void test_blockBodiedLambdas_doesNotInferBottom_asyncStar_topLevel() {
    super.test_blockBodiedLambdas_doesNotInferBottom_asyncStar_topLevel();
  }

  @override
  @failingTest
  void test_blockBodiedLambdas_doesNotInferBottom_syncStar_topLevel() {
    super.test_blockBodiedLambdas_doesNotInferBottom_syncStar_topLevel();
  }

  @override
  @failingTest
  void test_blockBodiedLambdas_LUB_topLevel() {
    super.test_blockBodiedLambdas_LUB_topLevel();
  }

  @override
  @failingTest
  void test_blockBodiedLambdas_nestedLambdas_topLevel() {
    super.test_blockBodiedLambdas_nestedLambdas_topLevel();
  }

  @override
  @failingTest
  void test_blockBodiedLambdas_syncStar_topLevel() {
    super.test_blockBodiedLambdas_syncStar_topLevel();
  }

  @override
  void test_canInferAlsoFromStaticAndInstanceFieldsFlagOn() {
    variablesWithNotConstInitializers.add('a2');
    super.test_canInferAlsoFromStaticAndInstanceFieldsFlagOn();
  }

  @override
  @failingTest
  void test_genericMethods_inferJSBuiltin() {
    super.test_genericMethods_inferJSBuiltin();
  }

  void test_infer_extractIndex_custom() {
    var unit = checkFile('''
class A {
  String operator [](_) => null;
}
var a = new A();
var b = a[0];
  ''');
    expect(unit.topLevelVariables[1].type.toString(), 'String');
  }

  void test_infer_extractIndex_fromList() {
    var unit = checkFile('''
var a = <int>[1, 2, 3];
var b = a[0];
  ''');
    expect(unit.topLevelVariables[1].type.toString(), 'int');
  }

  void test_infer_extractIndex_fromMap() {
    var unit = checkFile('''
var a = <int, double>{};
var b = a[0];
  ''');
    expect(unit.topLevelVariables[1].type.toString(), 'double');
  }

  void test_infer_extractProperty_getter() {
    checkFile(r'''
var a = 1.isEven;
var b = 2.isNaN;
var c = 3.foo;
var d = foo.bar;
  ''');
  }

  void test_infer_extractProperty_getter_sequence() {
    var unit = checkFile(r'''
class A {
  B b = new B();
}
class B {
  C c = new C();
}
class C {
  int d;
}
var a = new A();
var v = a.b.c.d;
  ''');
    expect(unit.topLevelVariables[1].type.toString(), 'int');
  }

  void test_infer_extractProperty_getter_sequence_generic() {
    var unit = checkFile(r'''
class A<T> {
  B<T> b = new B<T>();
}
class B<K> {
  C<List<K>, int> c = new C<List<K>, int>();
}
class C<K, V> {
  Map<K, V> d;
}
var a = new A<double>();
var v = a.b.c.d;
  ''');
    expect(unit.topLevelVariables[1].type.toString(), 'Map<List<double>, int>');
  }

  void test_infer_extractProperty_getter_sequence_withUnresolved() {
    var unit = checkFile(r'''
class A {
  B b = new B();
}
class B {
  int c;
}
var a = new A();
var v = a.b.foo.c;
  ''');
    expect(unit.topLevelVariables[1].type.toString(), 'dynamic');
  }

  void test_infer_extractProperty_method() {
    var unit = checkFile(r'''
class A {
  int m(double p1, String p2) => 42;
}
var a = new A();
var v = a.m;
  ''');
    expect(unit.topLevelVariables[1].type.toString(), '(double, String) → int');
  }

  void test_infer_extractProperty_method2() {
    var unit = checkFile(r'''
var a = 1.round;
  ''');
    expect(unit.topLevelVariables[0].type.toString(), '() → int');
  }

  void test_infer_extractProperty_method_sequence() {
    var unit = checkFile(r'''
class A {
  B b = new B();
}
class B {
  C c = new C();
}
class C {
  int m(double p1, String p2) => 42;
}
var a = new A();
var v = a.b.c.m;
  ''');
    expect(unit.topLevelVariables[1].type.toString(), '(double, String) → int');
  }

  void test_infer_invokeConstructor_factoryRedirected() {
    checkFile(r'''
class A {
  factory A() = B;
}
class B implements A {}
var a = new A();
  ''');
  }

  void test_infer_invokeConstructor_named() {
    checkFile(r'''
class A {
  A.aaa();
}
class B<K, V> {
  B.bbb();
}
var a = new A.aaa();
var b1 = new B.bbb();
var b2 = new B<int, String>.bbb();
var b3 = new B<List<int>, Map<List<int>, Set<String>>>.bbb();
  ''');
  }

  void test_infer_invokeConstructor_named_importedWithPrefix() {
    addFile(
        r'''
class A {
  A.aaa();
}
class B<K, V> {
  B.bbb();
}
''',
        name: '/a.dart');
    checkFile(r'''
import 'a.dart' as p;
var a = new p.A.aaa();
var b1 = new p.B.bbb();
var b2 = new p.B<int, String>.bbb();
  ''');
  }

  void test_infer_invokeConstructor_unnamed() {
    checkFile(r'''
class A {
  A();
}
class B<T> {
  B();
}
var a = new A();
var b1 = new B();
var b2 = new B<int>();
  ''');
  }

  void test_infer_invokeConstructor_unnamed_synthetic() {
    checkFile(r'''
class A {}
class B<T> {}
var a = new A();
var b1 = new B();
var b2 = new B<int>();
  ''');
  }

  void test_infer_invokeMethodRef_function() {
    var unit = checkFile(r'''
int m() => 0;
var a = m();
  ''');
    expect(unit.topLevelVariables[0].type.toString(), 'int');
  }

  void test_infer_invokeMethodRef_function_generic() {
    var unit = checkFile(r'''
/*=Map<int, V>*/ m/*<V>*/(/*=V*/ a) => null;
var a = m(2.3);
  ''');
    expect(unit.topLevelVariables[0].type.toString(), 'Map<int, double>');
  }

  void test_infer_invokeMethodRef_function_importedWithPrefix() {
    addFile(
        r'''
int m() => 0;
''',
        name: '/a.dart');
    var unit = checkFile(r'''
import 'a.dart' as p;
var a = p.m();
  ''');
    expect(unit.topLevelVariables[0].type.toString(), 'int');
  }

  void test_infer_invokeMethodRef_method() {
    var unit = checkFile(r'''
class A {
  int m() => 0;
}
var a = new A();
var b = a.m();
  ''');
    expect(unit.topLevelVariables[1].type.toString(), 'int');
  }

  void test_infer_invokeMethodRef_method_g() {
    var unit = checkFile(r'''
class A {
  /*=T*/ m/*<T>*/(/*=T*/ a) => null;
}
var a = new A();
var b = a.m(1.0);
  ''');
    expect(unit.topLevelVariables[1].type.toString(), 'double');
  }

  void test_infer_invokeMethodRef_method_genericSequence() {
    var unit = checkFile(r'''
class A<T> {
  B<T> b = new B<T>();
}
class B<K> {
  C<List<K>, int> c = new C<List<K>, int>();
}
class C<K, V> {
  Map<K, V> m() => null;
}
var a = new A<double>();
var v = a.b.c.m();
  ''');
    expect(unit.topLevelVariables[1].type.toString(), 'Map<List<double>, int>');
  }

  void test_infer_invokeMethodRef_method_gg() {
    var unit = checkFile(r'''
class A<K> {
  /*=Map<K, V>*/ m/*<V>*/(/*=V*/ a) => null;
}
var a = new A<int>();
var b = a.m(1.0);
  ''');
    expect(unit.topLevelVariables[1].type.toString(), 'Map<int, double>');
  }

  void test_infer_invokeMethodRef_method_importedWithPrefix() {
    addFile(
        r'''
class A {
  int m() => 0;
}
var a = new A();
''',
        name: '/a.dart');
    var unit = checkFile(r'''
import 'a.dart' as p;
var b = p.a.m();
  ''');
    expect(unit.topLevelVariables[0].type.toString(), 'int');
  }

  void test_infer_invokeMethodRef_method_importedWithPrefix2() {
    addFile(
        r'''
class A {
  B b = new B();
}
class B {
  int m() => 0;
}
var a = new A();
''',
        name: '/a.dart');
    var unit = checkFile(r'''
import 'a.dart' as p;
var b = p.a.b.m();
  ''');
    expect(unit.topLevelVariables[0].type.toString(), 'int');
  }

  void test_infer_invokeMethodRef_method_withInferredTypeInLibraryCycle() {
    var unit = checkFile('''
class Base {
  int m() => 0;
}
class A extends Base {
  m() => 0; // Inferred return type: int
}
var a = new A();
var b = a.m();
    ''');
    // Type inference operates on static and top level variables prior to
    // instance members.  So at the time `b` is inferred, `A.m` still has return
    // type `dynamic`.
    expect(unit.topLevelVariables[1].type.toString(), 'dynamic');
  }

  void test_infer_invokeMethodRef_method_withInferredTypeOutsideLibraryCycle() {
    addFile(
        '''
class Base {
  int m() => 0;
}
class A extends Base {
  m() => 0; // Inferred return type: int
}
''',
        name: '/a.dart');
    var unit = checkFile('''
import 'a.dart';
var a = new A();
var b = a.m();
''');
    // Since a.dart is in a separate library file from the compilation unit
    // containing `a` and `b`, its types are inferred first; then `a` and `b`'s
    // types are inferred.  So the inferred return type of `int` should be
    // propagated to `b`.
    expect(unit.topLevelVariables[1].type.toString(), 'int');
  }

  @override
  @failingTest
  void test_inferCorrectlyOnMultipleVariablesDeclaredTogether() {
    super.test_inferCorrectlyOnMultipleVariablesDeclaredTogether();
  }

  @override
  @failingTest
  void test_inferenceInCyclesIsDeterministic() {
    super.test_inferenceInCyclesIsDeterministic();
  }

  void test_invokeMethod_notGeneric_genericClass() {
    var unit = checkFile(r'''
class C<T> {
  T m(int a, {String b, T c}) => null;
}
var v = new C<double>().m(1, b: 'bbb', c: 2.0);
  ''');
    expect(unit.topLevelVariables[0].type.toString(), 'double');
  }

  void test_invokeMethod_notGeneric_notGenericClass() {
    var unit = checkFile(r'''
class C {
  int m(int a, {String b, int c}) => null;
}
var v = new C().m(1, b: 'bbb', c: 2.0);
  ''');
    expect(unit.topLevelVariables[0].type.toString(), 'int');
  }

  LibraryElementImpl _checkSource(
      SummaryResynthesizer resynthesizer, Source source) {
    LibraryElementImpl resynthesized =
        resynthesizer.getLibraryElement(source.uri.toString());
    LibraryElementImpl original = context.computeLibraryElement(source);
    checkLibraryElements(original, resynthesized);
    return resynthesized;
  }
}

@reflectiveTest
class ResynthesizeAstTest extends ResynthesizeTest
    with _AstResynthesizeTestMixin {
  @override
  bool get checkPropagatedTypes => false;

  @override
  LibraryElementImpl checkLibrary(String text,
      {bool allowErrors: false, bool dumpSummaries: false}) {
    Source source = addTestSource(text);
    LibraryElementImpl resynthesized = _encodeDecodeLibraryElement(source);
    LibraryElementImpl original = context.computeLibraryElement(source);
    checkLibraryElements(original, resynthesized);
    return resynthesized;
  }

  @override
  DartSdk createDartSdk() => AbstractContextTest.SHARED_MOCK_SDK;

  @override
  TestSummaryResynthesizer encodeDecodeLibrarySource(Source source) {
    return _encodeLibrary(source);
  }
}

/**
 * Abstract mixin for serializing ASTs and resynthesizing elements from it.
 */
abstract class _AstResynthesizeTestMixin {
  final Set<Source> serializedSources = new Set<Source>();
  final PackageBundleAssembler bundleAssembler = new PackageBundleAssembler();
  final Map<String, UnlinkedUnitBuilder> uriToUnit =
      <String, UnlinkedUnitBuilder>{};

  AnalysisContext get context;

  LibraryElementImpl _encodeDecodeLibraryElement(Source source) {
    SummaryResynthesizer resynthesizer = _encodeLibrary(source);
    return resynthesizer.getLibraryElement(source.uri.toString());
  }

  TestSummaryResynthesizer _encodeLibrary(Source source) {
    _serializeLibrary(source);

    PackageBundle bundle =
        new PackageBundle.fromBuffer(bundleAssembler.assemble().toBuffer());

    Map<String, UnlinkedUnit> unlinkedSummaries = <String, UnlinkedUnit>{};
    for (int i = 0; i < bundle.unlinkedUnitUris.length; i++) {
      String uri = bundle.unlinkedUnitUris[i];
      unlinkedSummaries[uri] = bundle.unlinkedUnits[i];
    }

    LinkedLibrary getDependency(String absoluteUri) {
      Map<String, LinkedLibrary> sdkLibraries =
          SerializedMockSdk.instance.uriToLinkedLibrary;
      LinkedLibrary linkedLibrary = sdkLibraries[absoluteUri];
      if (linkedLibrary == null) {
        fail('Linker unexpectedly requested LinkedLibrary for "$absoluteUri".'
            '  Libraries available: ${sdkLibraries.keys}');
      }
      return linkedLibrary;
    }

    UnlinkedUnit getUnit(String absoluteUri) {
      UnlinkedUnit unit = uriToUnit[absoluteUri] ??
          SerializedMockSdk.instance.uriToUnlinkedUnit[absoluteUri];
      if (unit == null) {
        fail('Linker unexpectedly requested unit for "$absoluteUri".');
      }
      return unit;
    }

    Set<String> nonSdkLibraryUris = context.sources
        .where((Source source) =>
            !source.isInSystemLibrary &&
            context.computeKindOf(source) == SourceKind.LIBRARY)
        .map((Source source) => source.uri.toString())
        .toSet();

    Map<String, LinkedLibrary> linkedSummaries = link(nonSdkLibraryUris,
        getDependency, getUnit, context.analysisOptions.strongMode);

    return new TestSummaryResynthesizer(
        null,
        context,
        new Map<String, UnlinkedUnit>()
          ..addAll(SerializedMockSdk.instance.uriToUnlinkedUnit)
          ..addAll(unlinkedSummaries),
        new Map<String, LinkedLibrary>()
          ..addAll(SerializedMockSdk.instance.uriToLinkedLibrary)
          ..addAll(linkedSummaries));
  }

  UnlinkedUnit _getUnlinkedUnit(Source source) {
    String uriStr = source.uri.toString();
    {
      UnlinkedUnit unlinkedUnitInSdk =
          SerializedMockSdk.instance.uriToUnlinkedUnit[uriStr];
      if (unlinkedUnitInSdk != null) {
        return unlinkedUnitInSdk;
      }
    }
    return uriToUnit.putIfAbsent(uriStr, () {
      CompilationUnit unit = context.computeResult(source, PARSED_UNIT);
      UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit);
      bundleAssembler.addUnlinkedUnit(source, unlinkedUnit);
      return unlinkedUnit;
    });
  }

  void _serializeLibrary(Source librarySource) {
    if (librarySource.isInSystemLibrary) {
      return;
    }
    if (!serializedSources.add(librarySource)) {
      return;
    }

    Source resolveRelativeUri(String relativeUri) {
      Source resolvedSource =
          context.sourceFactory.resolveUri(librarySource, relativeUri);
      if (resolvedSource == null) {
        throw new StateError('Could not resolve $relativeUri in the context of '
            '$librarySource (${librarySource.runtimeType})');
      }
      return resolvedSource;
    }

    UnlinkedUnit getPart(String relativeUri) {
      return _getUnlinkedUnit(resolveRelativeUri(relativeUri));
    }

    UnlinkedPublicNamespace getImport(String relativeUri) {
      return getPart(relativeUri).publicNamespace;
    }

    UnlinkedUnit definingUnit = _getUnlinkedUnit(librarySource);
    LinkedLibraryBuilder linkedLibrary =
        prelink(definingUnit, getPart, getImport);
    linkedLibrary.dependencies.skip(1).forEach((LinkedDependency d) {
      _serializeLibrary(resolveRelativeUri(d.uri));
    });
  }
}
