// Copyright (c) 2014, 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 'dart:async';

import 'package:analysis_server/src/protocol_server.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/test_utilities/test_code_format.dart';
import 'package:analyzer/utilities/package_config_file_builder.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'analysis_server_base.dart';
import 'mocks.dart';
import 'services/completion/dart/completion_check.dart';
import 'services/completion/dart/completion_printer.dart' as printer;
import 'services/completion/dart/text_expectations.dart';

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(CompletionDomainHandlerGetSuggestionDetails2Test);
    defineReflectiveTests(CompletionDomainHandlerGetSuggestions2Test);
  });
}

@reflectiveTest
class CompletionDomainHandlerGetSuggestionDetails2Test
    extends PubPackageAnalysisServerTest {
  void assertDetailsText(
    CompletionGetSuggestionDetails2Result result,
    String expected, {
    bool printIfFailed = true,
  }) {
    var buffer = StringBuffer();
    _SuggestionDetailsPrinter(
      resourceProvider: resourceProvider,
      fileDisplayMap: {testFile: 'testFile'},
      buffer: buffer,
      result: result,
    ).writeResult();
    var actual = buffer.toString();

    if (actual != expected) {
      if (printIfFailed) {
        print(actual);
      }
      TextExpectationsCollector.add(actual);
    }
    expect(actual, expected);
  }

  Future<void> test_alreadyImported() async {
    await _configureWithWorkspaceRoot();

    var details = await _getTestCodeDetails(
      '''
import 'dart:math';
void f() {
  Rand^
}
''',
      completion: 'Random',
      libraryUri: 'dart:math',
    );

    assertDetailsText(details, r'''
completion: Random
  change
''');
  }

  Future<void> test_import_dart() async {
    await _configureWithWorkspaceRoot();

    var details = await _getTestCodeDetails(
      '''
void f() {
  R^
}
''',
      completion: 'Random',
      libraryUri: 'dart:math',
    );

    assertDetailsText(details, r'''
completion: Random
  change
    testFile
      offset: 0
      length: 0
      replacement: import 'dart:math';\n\n
''');
  }

  Future<void> test_import_package_dependencies() async {
    writeTestPackagePubspecYamlFile(r'''
name: test
dependencies:
  aaa: any
''');

    var aaaRoot = getFolder('$workspaceRootPath/packages/aaa');
    newFile('${aaaRoot.path}/lib/f.dart', '''
class Test {}
''');

    writeTestPackageConfig(
      config:
          PackageConfigFileBuilder()..add(name: 'aaa', rootPath: aaaRoot.path),
    );

    await _configureWithWorkspaceRoot();

    var details = await _getTestCodeDetails(
      '''
void f() {
  T^
}
''',
      completion: 'Test',
      libraryUri: 'package:aaa/a.dart',
    );

    assertDetailsText(details, r'''
completion: Test
  change
    testFile
      offset: 0
      length: 0
      replacement: import 'package:aaa/a.dart';\n\n
''');
  }

  Future<void> test_import_package_this() async {
    newFile('$testPackageLibPath/a.dart', '''
class Test {}
''');

    await _configureWithWorkspaceRoot();

    var details = await _getTestCodeDetails(
      '''
void f() {
  T^
}
''',
      completion: 'Test',
      libraryUri: 'package:test/a.dart',
    );

    assertDetailsText(details, r'''
completion: Test
  change
    testFile
      offset: 0
      length: 0
      replacement: import 'package:test/a.dart';\n\n
''');
  }

  Future<void> test_invalidLibraryUri() async {
    await _configureWithWorkspaceRoot();

    var request = CompletionGetSuggestionDetails2Params(
      testFile.path,
      0,
      'Random',
      '[foo]:bar',
    ).toRequest('0', clientUriConverter: server.uriConverter);

    var response = await handleRequest(request);
    expect(response.error?.code, RequestErrorCode.INVALID_PARAMETER);
    // TODO(scheglov): Check that says "libraryUri".
  }

  Future<void> test_invalidPath() async {
    await _configureWithWorkspaceRoot();

    var request = CompletionGetSuggestionDetails2Params(
      'foo',
      0,
      'Random',
      'dart:math',
    ).toRequest('0', clientUriConverter: server.uriConverter);

    var response = await handleRequest(request);
    expect(response.error?.code, RequestErrorCode.INVALID_FILE_PATH_FORMAT);
  }

  Future<void> _configureWithWorkspaceRoot() async {
    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;
  }

  Future<CompletionGetSuggestionDetails2Result> _getCodeDetails({
    required String path,
    required String content,
    required String completion,
    required String libraryUri,
  }) async {
    var code = TestCode.parse(content);
    var completionOffset = code.position.offset;

    newFile(path, code.code);

    return await _getDetails(
      path: path,
      completionOffset: completionOffset,
      completion: completion,
      libraryUri: libraryUri,
    );
  }

  Future<CompletionGetSuggestionDetails2Result> _getDetails({
    required String path,
    required int completionOffset,
    required String completion,
    required String libraryUri,
  }) async {
    var request = CompletionGetSuggestionDetails2Params(
      path,
      completionOffset,
      completion,
      libraryUri,
    ).toRequest('0', clientUriConverter: server.uriConverter);

    var response = await handleSuccessfulRequest(request);
    return CompletionGetSuggestionDetails2Result.fromResponse(
      response,
      clientUriConverter: server.uriConverter,
    );
  }

  Future<CompletionGetSuggestionDetails2Result> _getTestCodeDetails(
    String content, {
    required String completion,
    required String libraryUri,
  }) {
    return _getCodeDetails(
      path: convertPath(testFilePath),
      content: content,
      completion: completion,
      libraryUri: libraryUri,
    );
  }
}

@reflectiveTest
class CompletionDomainHandlerGetSuggestions2Test
    extends PubPackageAnalysisServerTest {
  printer.Configuration printerConfiguration = printer.Configuration(
    filter: (suggestion) {
      var completion = suggestion.completion;
      if (completion.startsWith('A0')) {
        return suggestion.isClass;
      }
      return const {'foo0'}.any(completion.startsWith);
    },
    withIsNotImported: true,
    withLibraryUri: true,
  );

  /// Asserts that the [response] has the [expected] textual dump produced
  /// using [printerConfiguration].
  void assertResponseText(
    CompletionResponseForTesting response,
    String expected, {
    bool printIfFailed = true,
  }) {
    var buffer = StringBuffer();
    printer.CompletionResponsePrinter(
      buffer: buffer,
      configuration: printerConfiguration,
      response: response,
    ).writeResponse();
    var actual = buffer.toString();

    if (actual != expected) {
      if (printIfFailed) {
        print(actual);
      }
      TextExpectationsCollector.add(actual);
    }
    expect(actual, expected);
  }

  @override
  void setUp() {
    super.setUp();
    server.completionState.budgetDuration = const Duration(seconds: 30);
  }

  Future<void> test_abort_onAnotherCompletionRequest() async {
    var abortedIdSet = <String>{};
    server.discardedRequests.stream.listen((request) {
      abortedIdSet.add(request.id);
    });

    newFile(testFilePath, '');

    await _configureWithWorkspaceRoot();

    // Send three requests, the first two should be aborted.
    var request0 = _sendTestCompletionRequest('0', 0);
    var request1 = _sendTestCompletionRequest('1', 0);
    var request2 = _sendTestCompletionRequest('2', 0);

    // Wait for all three.
    var response0 = await request0.toResponse();
    var response1 = await request1.toResponse();
    var response2 = await request2.toResponse();

    // The first two should be aborted.
    expect(abortedIdSet, {'0', '1'});

    printerConfiguration.filter = (suggestion) {
      if (suggestion.isClass) {
        return const {'int'}.contains(suggestion.completion);
      }
      return false;
    };

    assertResponseText(response0, r'''
suggestions
''');

    assertResponseText(response1, r'''
suggestions
''');

    assertResponseText(response2, r'''
suggestions
  int
    kind: class
    isNotImported: null
    libraryUri: dart:core
''');
  }

  Future<void> test_abort_onUpdateContent() async {
    var abortedIdSet = <String>{};
    server.discardedRequests.stream.listen((request) {
      abortedIdSet.add(request.id);
    });

    newFile(testFilePath, '');

    await _configureWithWorkspaceRoot();

    // Schedule a completion request.
    var request = _sendTestCompletionRequest('0', 0);

    // Simulate typing in the IDE.
    await handleSuccessfulRequest(
      AnalysisUpdateContentParams({
        testFile.path: AddContentOverlay('void f() {}'),
      }).toRequest('1', clientUriConverter: server.uriConverter),
    );

    // The request should be aborted.
    var response = await request.toResponse();
    expect(abortedIdSet, {'0'});

    assertResponseText(response, r'''
suggestions
''');
  }

  Future<void> test_applyPendingFileChanges() async {
    await _configureWithWorkspaceRoot();

    // Request with the empty content.
    await _getTestCodeSuggestions('^');

    // Change the file, and request again.
    // Should apply pending file changes before resolving.
    var response = await _getTestCodeSuggestions('Str^');

    printerConfiguration.filter = (suggestion) {
      if (suggestion.isClass) {
        return const {'String'}.contains(suggestion.completion);
      }
      return false;
    };

    assertResponseText(response, r'''
replacement
  left: 3
suggestions
  String
    kind: class
    isNotImported: null
    libraryUri: dart:core
''');
  }

  Future<void> test_isNotImportedFeature_prefixed_classInstanceMethod() async {
    newFile('$testPackageLibPath/a.dart', '''
class A {
  void foo01() {}
}
''');

    newFile('$testPackageLibPath/b.dart', '''
import 'a.dart';

class B extends A {
  void foo02() {}
}
''');

    await _configureWithWorkspaceRoot();

    var response = await _getTestCodeSuggestions('''
import 'b.dart';

void f(B b) {
  b.foo0^
}
''');

    // The fact that `b.dart` is imported, and `a.dart` is not, does not affect
    // the order of suggestions added with an expression prefix. We are not
    // going to import anything, so this does not matter.
    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo01
    kind: methodInvocation
    isNotImported: null
    libraryUri: null
  foo02
    kind: methodInvocation
    isNotImported: null
    libraryUri: null
''');
  }

  Future<void> test_notImported_dart() async {
    await _configureWithWorkspaceRoot();

    var response = await _getTestCodeSuggestions('''
void f() {
  Rand^
}
''');

    printerConfiguration.filter = (suggestion) {
      return suggestion.isClass;
    };

    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  Random
    kind: class
    isNotImported: true
    libraryUri: dart:math
''');
  }

  Future<void> test_notImported_emptyBudget() async {
    await _configureWithWorkspaceRoot();

    // Empty budget, so no not yet imported libraries.
    server.completionState.budgetDuration = const Duration();

    var response = await _getTestCodeSuggestions('''
void f() {
  Rand^
}
''');

    printerConfiguration.filter = (_) => true;

    assertResponseText(response, r'''
replacement
  left: 4
suggestions
''');
  }

  Future<void> test_notImported_lowerRelevance_extension_getter() async {
    await _configureWithWorkspaceRoot();
    printerConfiguration.sorting =
        printer.Sorting.relevanceThenCompletionThenKind;

    newFile('$testPackageLibPath/a.dart', '''
extension E1 on int {
  int get foo01 => 0;
}
''');

    newFile('$testPackageLibPath/b.dart', '''
extension E2 on int {
  int get foo02 => 0;
}
''');

    var response = await _getTestCodeSuggestions(r'''
import 'b.dart';

void f() {
  0.foo0^
}
''');

    // `foo01` relevance is decreased because it is not yet imported.
    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo02
    kind: getter
    isNotImported: null
    libraryUri: null
  foo01
    kind: getter
    isNotImported: true
    libraryUri: package:test/a.dart
''');
  }

  Future<void> test_notImported_lowerRelevance_extension_method() async {
    await _configureWithWorkspaceRoot();
    printerConfiguration.sorting =
        printer.Sorting.relevanceThenCompletionThenKind;

    newFile('$testPackageLibPath/a.dart', '''
extension E1 on int {
  void foo01() {}
}
''');

    newFile('$testPackageLibPath/b.dart', '''
extension E2 on int {
  void foo02() {}
}
''');

    var response = await _getTestCodeSuggestions(r'''
import 'b.dart';

void f() {
  0.foo0^
}
''');

    // `foo01` relevance is decreased because it is not yet imported.
    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo02
    kind: methodInvocation
    isNotImported: null
    libraryUri: null
  foo01
    kind: methodInvocation
    isNotImported: true
    libraryUri: package:test/a.dart
''');
  }

  Future<void> test_notImported_lowerRelevance_extension_setter() async {
    await _configureWithWorkspaceRoot();
    printerConfiguration.sorting =
        printer.Sorting.relevanceThenCompletionThenKind;

    newFile('$testPackageLibPath/a.dart', '''
extension E1 on int {
  set foo01(int _) {}
}
''');

    newFile('$testPackageLibPath/b.dart', '''
extension E2 on int {
  set foo02(int _) {}
}
''');

    var response = await _getTestCodeSuggestions(r'''
import 'b.dart';

void f() {
  0.foo0^
}
''');

    // `foo01` relevance is decreased because it is not yet imported.
    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo02
    kind: setter
    isNotImported: null
    libraryUri: null
  foo01
    kind: setter
    isNotImported: true
    libraryUri: package:test/a.dart
''');
  }

  Future<void> test_notImported_lowerRelevance_topLevel_class() async {
    newFile('$testPackageLibPath/a.dart', '''
class A01 {}
''');

    newFile('$testPackageLibPath/b.dart', '''
class A02 {}
''');

    await _configureWithWorkspaceRoot();
    printerConfiguration.sorting =
        printer.Sorting.relevanceThenCompletionThenKind;

    var response = await _getTestCodeSuggestions('''
import 'b.dart';

void f() {
  A0^
}
''');

    // `A01` relevance is decreased because it is not yet imported.
    assertResponseText(response, r'''
replacement
  left: 2
suggestions
  A02
    kind: class
    isNotImported: null
    libraryUri: package:test/b.dart
  A01
    kind: class
    isNotImported: true
    libraryUri: package:test/a.dart
''');
  }

  Future<void> test_notImported_lowerRelevance_topLevel_getter() async {
    newFile('$testPackageLibPath/a.dart', '''
int get foo01 => 0;
''');

    newFile('$testPackageLibPath/b.dart', '''
int get foo02 => 0;
''');

    await _configureWithWorkspaceRoot();
    printerConfiguration.sorting =
        printer.Sorting.relevanceThenCompletionThenKind;

    var response = await _getTestCodeSuggestions('''
import 'b.dart';

void f() {
  foo0^
}
''');

    // `foo01` relevance is decreased because it is not yet imported.
    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo02
    kind: getter
    isNotImported: null
    libraryUri: package:test/b.dart
  foo01
    kind: getter
    isNotImported: true
    libraryUri: package:test/a.dart
''');
  }

  Future<void> test_notImported_lowerRelevance_topLevel_setter() async {
    newFile('$testPackageLibPath/a.dart', '''
set foo01(int _) {}
''');

    newFile('$testPackageLibPath/b.dart', '''
set foo02(int _) {}
''');

    await _configureWithWorkspaceRoot();
    printerConfiguration.sorting =
        printer.Sorting.relevanceThenCompletionThenKind;

    var response = await _getTestCodeSuggestions('''
import 'b.dart';

void f() {
  foo0^
}
''');

    // `foo01` relevance is decreased because it is not yet imported.
    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo02
    kind: setter
    isNotImported: null
    libraryUri: package:test/b.dart
  foo01
    kind: setter
    isNotImported: true
    libraryUri: package:test/a.dart
''');
  }

  Future<void> test_notImported_lowerRelevance_topLevel_variable() async {
    newFile('$testPackageLibPath/a.dart', '''
var foo01 = 0;
''');

    newFile('$testPackageLibPath/b.dart', '''
var foo02 = 0;
''');

    await _configureWithWorkspaceRoot();
    printerConfiguration.sorting =
        printer.Sorting.relevanceThenCompletionThenKind;

    var response = await _getTestCodeSuggestions('''
import 'b.dart';

void f() {
  foo0^
}
''');

    // `foo01` relevance is decreased because it is not yet imported.
    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo02
    kind: topLevelVariable
    isNotImported: null
    libraryUri: package:test/b.dart
  foo01
    kind: topLevelVariable
    isNotImported: true
    libraryUri: package:test/a.dart
''');
  }

  Future<void> test_notImported_pub_dependencies_inBin() async {
    writeTestPackagePubspecYamlFile(r'''
name: test
dependencies:
  aaa: any
dev_dependencies:
  bbb: any
''');

    var aaaRoot = getFolder('$workspaceRootPath/packages/aaa');
    newFile('${aaaRoot.path}/lib/f.dart', '''
class A01 {}
''');

    var bbbRoot = getFolder('$workspaceRootPath/packages/bbb');
    newFile('${bbbRoot.path}/lib/f.dart', '''
class A02 {}
''');

    writeTestPackageConfig(
      config:
          PackageConfigFileBuilder()
            ..add(name: 'aaa', rootPath: aaaRoot.path)
            ..add(name: 'bbb', rootPath: bbbRoot.path),
    );

    await _configureWithWorkspaceRoot();

    var binPath = convertPath('$testPackageRootPath/bin/main.dart');
    var response = await _getCodeSuggestions(
      path: binPath,
      content: '''
void f() {
  A0^
}
''',
    );

    assertResponseText(response, r'''
replacement
  left: 2
suggestions
  A01
    kind: class
    isNotImported: true
    libraryUri: package:aaa/f.dart
''');
  }

  Future<void> test_notImported_pub_dependencies_inLib() async {
    writeTestPackagePubspecYamlFile(r'''
name: test
dependencies:
  aaa: any
dev_dependencies:
  bbb: any
''');

    var aaaRoot = getFolder('$workspaceRootPath/packages/aaa');
    newFile('${aaaRoot.path}/lib/f.dart', '''
class A01 {}
''');
    newFile('${aaaRoot.path}/lib/src/f.dart', '''
class A02 {}
''');

    var bbbRoot = getFolder('$workspaceRootPath/packages/bbb');
    newFile('${bbbRoot.path}/lib/f.dart', '''
class A03 {}
''');
    newFile('${bbbRoot.path}/lib/src/f.dart', '''
class A04 {}
''');

    writeTestPackageConfig(
      config:
          PackageConfigFileBuilder()
            ..add(name: 'aaa', rootPath: aaaRoot.path)
            ..add(name: 'bbb', rootPath: bbbRoot.path),
    );

    await _configureWithWorkspaceRoot();

    var response = await _getTestCodeSuggestions('''
void f() {
  A0^
}
''');

    assertResponseText(response, r'''
replacement
  left: 2
suggestions
  A01
    kind: class
    isNotImported: true
    libraryUri: package:aaa/f.dart
''');
  }

  Future<void> test_notImported_pub_dependencies_inTest() async {
    writeTestPackagePubspecYamlFile(r'''
name: test
dependencies:
  aaa: any
dev_dependencies:
  bbb: any
''');

    var aaaRoot = getFolder('$workspaceRootPath/packages/aaa');
    newFile('${aaaRoot.path}/lib/f.dart', '''
class A01 {}
''');
    newFile('${aaaRoot.path}/lib/src/f.dart', '''
class A02 {}
''');

    var bbbRoot = getFolder('$workspaceRootPath/packages/bbb');
    newFile('${bbbRoot.path}/lib/f.dart', '''
class A03 {}
''');
    newFile('${bbbRoot.path}/lib/src/f.dart', '''
class A04 {}
''');

    writeTestPackageConfig(
      config:
          PackageConfigFileBuilder()
            ..add(name: 'aaa', rootPath: aaaRoot.path)
            ..add(name: 'bbb', rootPath: bbbRoot.path),
    );

    await _configureWithWorkspaceRoot();

    var test_path = convertPath('$testPackageTestPath/test.dart');
    var response = await _getCodeSuggestions(
      path: test_path,
      content: '''
void f() {
  A0^
}
''',
    );

    assertResponseText(response, r'''
replacement
  left: 2
suggestions
  A01
    kind: class
    isNotImported: true
    libraryUri: package:aaa/f.dart
  A03
    kind: class
    isNotImported: true
    libraryUri: package:bbb/f.dart
''');
  }

  Future<void> test_notImported_pub_dependencies_inWeb() async {
    writeTestPackagePubspecYamlFile(r'''
name: test
dependencies:
  aaa: any
dev_dependencies:
  bbb: any
''');

    var aaaRoot = getFolder('$workspaceRootPath/packages/aaa');
    newFile('${aaaRoot.path}/lib/f.dart', '''
class A01 {}
''');

    var bbbRoot = getFolder('$workspaceRootPath/packages/bbb');
    newFile('${bbbRoot.path}/lib/f.dart', '''
class A02 {}
''');

    writeTestPackageConfig(
      config:
          PackageConfigFileBuilder()
            ..add(name: 'aaa', rootPath: aaaRoot.path)
            ..add(name: 'bbb', rootPath: bbbRoot.path),
    );

    await _configureWithWorkspaceRoot();

    var webPath = convertPath('$testPackageRootPath/web/main.dart');
    var response = await _getCodeSuggestions(
      path: webPath,
      content: '''
void f() {
  A0^
}
''',
    );

    assertResponseText(response, r'''
replacement
  left: 2
suggestions
  A01
    kind: class
    isNotImported: true
    libraryUri: package:aaa/f.dart
''');
  }

  Future<void> test_notImported_pub_this() async {
    newFile('$testPackageLibPath/a.dart', '''
class A01 {}
''');

    newFile('$testPackageLibPath/b.dart', '''
class A02 {}
''');

    await _configureWithWorkspaceRoot();

    var response = await _getTestCodeSuggestions('''
void f() {
  A0^
}
''');

    assertResponseText(response, r'''
replacement
  left: 2
suggestions
  A01
    kind: class
    isNotImported: true
    libraryUri: package:test/a.dart
  A02
    kind: class
    isNotImported: true
    libraryUri: package:test/b.dart
''');
  }

  Future<void> test_notImported_pub_this_hasImport() async {
    newFile('$testPackageLibPath/a.dart', '''
class A01 {}
class A02 {}
''');

    newFile('$testPackageLibPath/b.dart', '''
class A03 {}
''');

    await _configureWithWorkspaceRoot();

    var response = await _getTestCodeSuggestions('''
import 'a.dart';

void f() {
  A0^
}
''');

    assertResponseText(response, r'''
replacement
  left: 2
suggestions
  A01
    kind: class
    isNotImported: null
    libraryUri: package:test/a.dart
  A02
    kind: class
    isNotImported: null
    libraryUri: package:test/a.dart
  A03
    kind: class
    isNotImported: true
    libraryUri: package:test/b.dart
''');
  }

  Future<void> test_notImported_pub_this_hasImport_hasShow() async {
    newFile('$testPackageLibPath/a.dart', '''
class A01 {}
class A02 {}
''');

    newFile('$testPackageLibPath/b.dart', '''
class A03 {}
''');

    await _configureWithWorkspaceRoot();
    printerConfiguration.sorting =
        printer.Sorting.relevanceThenCompletionThenKind;

    var response = await _getTestCodeSuggestions('''
import 'a.dart' show A02;

void f() {
  A0^
}
''');

    // Note:
    // 1. A02 is the first, because it is already imported.
    // 2. A01 is still suggested, but with lower relevance.
    // 3. A03 has the same relevance (not tested), but sorted by name.
    assertResponseText(response, r'''
replacement
  left: 2
suggestions
  A02
    kind: class
    isNotImported: null
    libraryUri: package:test/a.dart
  A01
    kind: class
    isNotImported: true
    libraryUri: package:test/a.dart
  A03
    kind: class
    isNotImported: true
    libraryUri: package:test/b.dart
''');
  }

  Future<void> test_notImported_pub_this_inLib_excludesTest() async {
    writeTestPackagePubspecYamlFile(r'''
name: test
''');

    newFile('$testPackageLibPath/a.dart', '''
class A01 {}
''');

    newFile('$testPackageTestPath/b.dart', '''
class A02 {}
''');

    await _configureWithWorkspaceRoot();

    var response = await _getTestCodeSuggestions('''
void f() {
  A0^
}
''');

    assertResponseText(response, r'''
replacement
  left: 2
suggestions
  A01
    kind: class
    isNotImported: true
    libraryUri: package:test/a.dart
''');
  }

  Future<void> test_notImported_pub_this_inLib_includesThisSrc() async {
    writeTestPackagePubspecYamlFile(r'''
name: test
''');

    newFile('$testPackageLibPath/f.dart', '''
class A01 {}
''');

    newFile('$testPackageLibPath/src/f.dart', '''
class A02 {}
''');

    await _configureWithWorkspaceRoot();

    var response = await _getTestCodeSuggestions('''
void f() {
  A0^
}
''');

    assertResponseText(response, r'''
replacement
  left: 2
suggestions
  A01
    kind: class
    isNotImported: true
    libraryUri: package:test/f.dart
  A02
    kind: class
    isNotImported: true
    libraryUri: package:test/src/f.dart
''');
  }

  Future<void> test_notImported_pub_this_inTest_includesTest() async {
    writeTestPackagePubspecYamlFile(r'''
name: test
''');

    newFile('$testPackageLibPath/a.dart', '''
class A01 {}
''');

    var b = newFile('$testPackageTestPath/b.dart', '''
class A02 {}
''');
    var b_uriStr = toUriStr(b.path);

    await _configureWithWorkspaceRoot();

    var test_path = convertPath('$testPackageTestPath/test.dart');
    var response = await _getCodeSuggestions(
      path: test_path,
      content: '''
void f() {
  A0^
}
''',
    );

    assertResponseText(response, '''
replacement
  left: 2
suggestions
  A01
    kind: class
    isNotImported: true
    libraryUri: package:test/a.dart
  A02
    kind: class
    isNotImported: true
    libraryUri: $b_uriStr
''');
  }

  Future<void> test_notImported_pub_this_inTest_includesThisSrc() async {
    writeTestPackagePubspecYamlFile(r'''
name: test
''');

    newFile('$testPackageLibPath/f.dart', '''
class A01 {}
''');

    newFile('$testPackageLibPath/src/f.dart', '''
class A02 {}
''');

    await _configureWithWorkspaceRoot();

    var test_path = convertPath('$testPackageTestPath/test.dart');
    var response = await _getCodeSuggestions(
      path: test_path,
      content: '''
void f() {
  A0^
}
''',
    );

    assertResponseText(response, r'''
replacement
  left: 2
suggestions
  A01
    kind: class
    isNotImported: true
    libraryUri: package:test/f.dart
  A02
    kind: class
    isNotImported: true
    libraryUri: package:test/src/f.dart
''');
  }

  Future<void> test_numResults_class_methods() async {
    await _configureWithWorkspaceRoot();

    var response = await _getTestCodeSuggestions('''
class A {
  void foo01() {}
  void foo02() {}
  void foo03() {}
}

void f(A a) {
  a.foo0^
}
''', maxResults: 2);

    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo01
    kind: methodInvocation
    isNotImported: null
    libraryUri: null
  foo02
    kind: methodInvocation
    isNotImported: null
    libraryUri: null
''');
  }

  Future<void> test_numResults_topLevelVariables() async {
    await _configureWithWorkspaceRoot();

    var response = await _getTestCodeSuggestions('''
var foo01 = 0;
var foo02 = 0;
var foo03 = 0;

void f() {
  foo0^
}
''', maxResults: 2);

    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo01
    kind: topLevelVariable
    isNotImported: null
    libraryUri: null
  foo02
    kind: topLevelVariable
    isNotImported: null
    libraryUri: null
''');
  }

  Future<void> test_numResults_topLevelVariables_imported_withPrefix() async {
    await _configureWithWorkspaceRoot();

    newFile('$testPackageLibPath/a.dart', '''
var foo01 = 0;
var foo02 = 0;
var foo03 = 0;
''');

    var response = await _getTestCodeSuggestions('''
import 'a.dart' as prefix;

void f() {
  prefix.^
}
''', maxResults: 2);

    assertResponseText(response, r'''
suggestions
  foo01
    kind: topLevelVariable
    isNotImported: null
    libraryUri: package:test/a.dart
  foo02
    kind: topLevelVariable
    isNotImported: null
    libraryUri: package:test/a.dart
''');
  }

  Future<void> test_prefixed_class_constructors() async {
    await _configureWithWorkspaceRoot();

    var response = await _getTestCodeSuggestions('''
class A {
  A.foo01();
  A.foo02();
}

void f() {
  A.foo0^
}
''');

    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo01
    kind: constructorInvocation
    isNotImported: null
    libraryUri: null
  foo02
    kind: constructorInvocation
    isNotImported: null
    libraryUri: null
''');
  }

  Future<void> test_prefixed_class_getters() async {
    await _configureWithWorkspaceRoot();

    var response = await _getTestCodeSuggestions('''
class A {
  int get foo01 => 0;
  int get foo02 => 0;
}

void f(A a) {
  a.foo0^
}
''');

    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo01
    kind: getter
    isNotImported: null
    libraryUri: null
  foo02
    kind: getter
    isNotImported: null
    libraryUri: null
''');
  }

  Future<void> test_prefixed_class_methods_instance() async {
    await _configureWithWorkspaceRoot();

    var response = await _getTestCodeSuggestions('''
class A {
  void foo01() {}
  void foo02() {}
}

void f(A a) {
  a.foo0^
}
''');

    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo01
    kind: methodInvocation
    isNotImported: null
    libraryUri: null
  foo02
    kind: methodInvocation
    isNotImported: null
    libraryUri: null
''');
  }

  Future<void> test_prefixed_class_methods_static() async {
    await _configureWithWorkspaceRoot();

    var response = await _getTestCodeSuggestions('''
class A {
  static void foo01() {}
  static void foo02() {}
}

void f() {
  A.foo0^
}
''');

    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo01
    kind: methodInvocation
    isNotImported: null
    libraryUri: null
  foo02
    kind: methodInvocation
    isNotImported: null
    libraryUri: null
''');
  }

  Future<void> test_prefixed_expression_extensionGetters() async {
    await _configureWithWorkspaceRoot();

    var response = await _getTestCodeSuggestions(r'''
extension E1 on int {
  int get foo01 => 0;
  int get foo02 => 0;
  int get bar => 0;
}

extension E2 on double {
  int get foo03 => 0;
}

void f() {
  0.foo0^
}
''');

    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo01
    kind: getter
    isNotImported: null
    libraryUri: null
  foo02
    kind: getter
    isNotImported: null
    libraryUri: null
''');
  }

  Future<void> test_prefixed_expression_extensionGetters_notImported() async {
    await _configureWithWorkspaceRoot();

    newFile('$testPackageLibPath/a.dart', '''
extension E1 on int {
  int get foo01 => 0;
  int get bar => 0;
}

extension E2 on int {
  int get foo02 => 0;
}

extension E3 on double {
  int get foo03 => 0;
}
''');

    var response = await _getTestCodeSuggestions(r'''
void f() {
  0.foo0^
}
''');

    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo01
    kind: getter
    isNotImported: true
    libraryUri: package:test/a.dart
  foo02
    kind: getter
    isNotImported: true
    libraryUri: package:test/a.dart
''');
  }

  Future<void>
  test_prefixed_expression_extensionGetters_notImported_private() async {
    await _configureWithWorkspaceRoot();

    newFile('$testPackageLibPath/a.dart', '''
extension E1 on int {
  int get foo01 => 0;
}

extension _E2 on int {
  int get foo02 => 0;
}

extension on int {
  int get foo03 => 0;
}
''');

    var response = await _getTestCodeSuggestions(r'''
void f() {
  0.foo0^
}
''');

    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo01
    kind: getter
    isNotImported: true
    libraryUri: package:test/a.dart
''');
  }

  Future<void> test_prefixed_expression_extensionMethods() async {
    await _configureWithWorkspaceRoot();

    var response = await _getTestCodeSuggestions(r'''
extension E1 on int {
  void foo01() {}
  void foo02() {}
  void bar() {}
}

extension E2 on double {
  void foo03() {}
}

void f() {
  0.foo0^
}
''');

    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo01
    kind: methodInvocation
    isNotImported: null
    libraryUri: null
  foo02
    kind: methodInvocation
    isNotImported: null
    libraryUri: null
''');
  }

  Future<void> test_prefixed_expression_extensionMethods_notImported() async {
    await _configureWithWorkspaceRoot();

    newFile('$testPackageLibPath/a.dart', '''
extension E1 on int {
  void foo01() {}
  void bar() {}
}

extension E2 on int {
  void foo02() {}
}

extension E3 on double {
  void foo03() {}
}
''');

    var response = await _getTestCodeSuggestions(r'''
void f() {
  0.foo0^
}
''');

    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo01
    kind: methodInvocation
    isNotImported: true
    libraryUri: package:test/a.dart
  foo02
    kind: methodInvocation
    isNotImported: true
    libraryUri: package:test/a.dart
''');
  }

  Future<void> test_prefixed_expression_extensionSetters() async {
    await _configureWithWorkspaceRoot();

    var response = await _getTestCodeSuggestions(r'''
extension E1 on int {
  set foo01(int _) {}
  set foo02(int _) {}
  set bar(int _) {}
}

extension E2 on double {
  set foo03(int _) {}
}

void f() {
  0.foo0^
}
''');

    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo01
    kind: setter
    isNotImported: null
    libraryUri: null
  foo02
    kind: setter
    isNotImported: null
    libraryUri: null
''');
  }

  Future<void> test_prefixed_expression_extensionSetters_notImported() async {
    await _configureWithWorkspaceRoot();

    newFile('$testPackageLibPath/a.dart', '''
extension E1 on int {
  set foo01(int _) {}
  set bar(int _) {}
}

extension E2 on int {
  set foo02(int _) {}
}

extension E3 on double {
  set foo03(int _) {}
}
''');

    var response = await _getTestCodeSuggestions(r'''
void f() {
  0.foo0^
}
''');

    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo01
    kind: setter
    isNotImported: true
    libraryUri: package:test/a.dart
  foo02
    kind: setter
    isNotImported: true
    libraryUri: package:test/a.dart
''');
  }

  Future<void>
  test_prefixed_expression_extensionSetters_notImported_private() async {
    await _configureWithWorkspaceRoot();

    newFile('$testPackageLibPath/a.dart', '''
extension E1 on int {
  set foo01(int _) {}
}

extension _E2 on int {
  set foo02(int _) {}
}

extension on int {
  set foo03(int _) {}
}
''');

    var response = await _getTestCodeSuggestions(r'''
void f() {
  0.foo0^
}
''');

    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo01
    kind: setter
    isNotImported: true
    libraryUri: package:test/a.dart
''');
  }

  Future<void> test_prefixed_extensionGetters_imported() async {
    await _configureWithWorkspaceRoot();

    newFile('$testPackageLibPath/a.dart', '''
extension E1 on int {
  int get foo01 => 0;
  int get foo02 => 0;
  int get bar => 0;
}

extension E2 on double {
  int get foo03 => 0;
}
''');

    var response = await _getTestCodeSuggestions(r'''
import 'a.dart';

void f() {
  0.foo0^
}
''');

    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo01
    kind: getter
    isNotImported: null
    libraryUri: null
  foo02
    kind: getter
    isNotImported: null
    libraryUri: null
''');
  }

  Future<void> test_prefixed_extensionOverride_extensionGetters() async {
    await _configureWithWorkspaceRoot();

    var response = await _getTestCodeSuggestions(r'''
extension E1 on int {
  int get foo01 => 0;
}

extension E2 on int {
  int get foo02 => 0;
}

void f() {
  E1(0).foo0^
}
''');

    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo01
    kind: getter
    isNotImported: null
    libraryUri: null
''');
  }

  Future<void> test_prefixed_extensionOverride_extensionMethods() async {
    await _configureWithWorkspaceRoot();

    var response = await _getTestCodeSuggestions(r'''
extension E1 on int {
  void foo01() {}
}

extension E2 on int {
  void foo01() {}
}

void f() {
  E1(0).foo0^
}
''');

    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo01
    kind: methodInvocation
    isNotImported: null
    libraryUri: null
''');
  }

  Future<void> test_prefixed_importPrefix_class() async {
    await _configureWithWorkspaceRoot();

    var response = await _getTestCodeSuggestions('''
import 'dart:math' as math;

void f() {
  math.Rand^
}
''');

    printerConfiguration.filter = (_) => true;

    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  Random
    kind: class
    isNotImported: null
    libraryUri: dart:math
  Random
    kind: constructorInvocation
    isNotImported: null
    libraryUri: dart:math
''');
  }

  Future<void> test_unprefixed_filters() async {
    await _configureWithWorkspaceRoot();

    var response = await _getTestCodeSuggestions(r'''
var foo01 = 0;
var foo02 = 0;
var bar01 = 0;
var bar02 = 0;

void f() {
  foo0^
}
''');

    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo01
    kind: topLevelVariable
    isNotImported: null
    libraryUri: null
  foo02
    kind: topLevelVariable
    isNotImported: null
    libraryUri: null
''');
  }

  Future<void> test_unprefixed_imported_class() async {
    await _configureWithWorkspaceRoot();

    newFile('$testPackageLibPath/a.dart', '''
class A01 {}
''');

    newFile('$testPackageLibPath/b.dart', '''
class A02 {}
''');

    var response = await _getTestCodeSuggestions('''
import 'a.dart';
import 'b.dart';

void f() {
  A0^
}
''');

    assertResponseText(response, r'''
replacement
  left: 2
suggestions
  A01
    kind: class
    isNotImported: null
    libraryUri: package:test/a.dart
  A02
    kind: class
    isNotImported: null
    libraryUri: package:test/b.dart
''');
  }

  Future<void> test_unprefixed_imported_topLevelVariable() async {
    await _configureWithWorkspaceRoot();

    newFile('$testPackageLibPath/a.dart', '''
var foo01 = 0;
''');

    newFile('$testPackageLibPath/b.dart', '''
var foo02 = 0;
''');

    var response = await _getTestCodeSuggestions('''
import 'a.dart';
import 'b.dart';

void f() {
  foo0^
}
''');

    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo01
    kind: topLevelVariable
    isNotImported: null
    libraryUri: package:test/a.dart
  foo02
    kind: topLevelVariable
    isNotImported: null
    libraryUri: package:test/b.dart
''');
  }

  Future<void> test_unprefixed_imported_withPrefix_class() async {
    await _configureWithWorkspaceRoot();

    var response = await _getTestCodeSuggestions('''
import 'dart:math' as math;

void f() {
  Rand^
}
''');

    printerConfiguration.filter = (suggestion) {
      return suggestion.isClass;
    };

    // No suggestion without the `math` prefix.
    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  math.Random
    kind: class
    isNotImported: null
    libraryUri: dart:math
''');
  }

  Future<void> test_unprefixed_sorts_byScore() async {
    await _configureWithWorkspaceRoot();

    var response = await _getTestCodeSuggestions(r'''
var fooAB = 0;
var fooBB = 0;

void f() {
  fooB^
}
''');

    printerConfiguration
      ..filter = (suggestion) {
        return suggestion.completion.startsWith('foo');
      }
      ..sorting = printer.Sorting.asIs
      ..withRelevance = true;

    // `fooBB` has better score than `fooAB` - prefix match
    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  fooBB
    kind: topLevelVariable
    isNotImported: null
    libraryUri: null
    relevance: 503
  fooAB
    kind: topLevelVariable
    isNotImported: null
    libraryUri: null
    relevance: 503
''');
  }

  Future<void> test_unprefixed_sorts_byType() async {
    await _configureWithWorkspaceRoot();

    var response = await _getTestCodeSuggestions(r'''
var foo01 = 0.0;
var foo02 = 0;

void f() {
  int v = foo0^
}
''');

    printerConfiguration
      ..sorting = printer.Sorting.asIs
      ..withRelevance = true;

    assertResponseText(response, r'''
replacement
  left: 4
suggestions
  foo01
    kind: topLevelVariable
    isNotImported: null
    libraryUri: null
    relevance: 510
  foo02
    kind: topLevelVariable
    isNotImported: null
    libraryUri: null
    relevance: 558
''');
  }

  Future<void> test_yaml_analysisOptions_formatter() async {
    await _configureWithWorkspaceRoot();

    var path = convertPath('$testPackageRootPath/analysis_options.yaml');
    var response = await _getCodeSuggestions(
      path: path,
      content: '''
formatter:
  ^
''',
    );

    printerConfiguration
      ..filter = ((_) => true)
      ..withIsNotImported = false
      ..withLibraryUri = false;

    assertResponseText(response, r'''
suggestions
  |page_width: |
    kind: identifier
  |trailing_commas: |
    kind: identifier
''');
  }

  Future<void> test_yaml_analysisOptions_root() async {
    await _configureWithWorkspaceRoot();

    var path = convertPath('$testPackageRootPath/analysis_options.yaml');
    var response = await _getCodeSuggestions(path: path, content: '^');

    printerConfiguration
      ..filter = ((_) => true)
      ..withIsNotImported = false
      ..withLibraryUri = false;

    assertResponseText(response, r'''
suggestions
  |analyzer: |
    kind: identifier
  |code-style: |
    kind: identifier
  |formatter: |
    kind: identifier
  |include: |
    kind: identifier
  |linter: |
    kind: identifier
''');
  }

  Future<void> test_yaml_fixData_root() async {
    await _configureWithWorkspaceRoot();

    var path = convertPath('$testPackageRootPath/fix_data.yaml');
    var response = await _getCodeSuggestions(path: path, content: '^');

    printerConfiguration
      ..filter = ((_) => true)
      ..withIsNotImported = false
      ..withLibraryUri = false;

    assertResponseText(response, r'''
suggestions
  transforms:
    kind: identifier
  |version: |
    kind: identifier
''');
  }

  Future<void> test_yaml_pubspec_root() async {
    await _configureWithWorkspaceRoot();

    var path = convertPath('$testPackageRootPath/pubspec.yaml');
    var response = await _getCodeSuggestions(path: path, content: '^');

    printerConfiguration
      ..filter = ((_) => true)
      ..withIsNotImported = false
      ..withLibraryUri = false;

    assertResponseText(response, r'''
suggestions
  |dependencies: |
    kind: identifier
  |dependency_overrides: |
    kind: identifier
  |description: |
    kind: identifier
  |dev_dependencies: |
    kind: identifier
  |documentation: |
    kind: identifier
  |environment: |
    kind: identifier
  |executables: |
    kind: identifier
  |flutter: |
    kind: identifier
  |homepage: |
    kind: identifier
  |issue_tracker: |
    kind: identifier
  |name: |
    kind: identifier
  |publish_to: |
    kind: identifier
  |repository: |
    kind: identifier
  |resolution: |
    kind: identifier
  screenshots:
    kind: identifier
  |topics: |
    kind: identifier
  |version: |
    kind: identifier
  workspace:
    kind: identifier
''');
  }

  Future<void> _configureWithWorkspaceRoot() async {
    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;
  }

  Future<CompletionResponseForTesting> _getCodeSuggestions({
    required String path,
    required String content,
    int maxResults = 1 << 10,
  }) async {
    var code = TestCode.parse(content);
    var completionOffset = code.position.offset;

    newFile(path, code.code);

    return await _getSuggestions(
      path: path,
      completionOffset: completionOffset,
      maxResults: maxResults,
    );
  }

  Future<CompletionResponseForTesting> _getSuggestions({
    required String path,
    required int completionOffset,
    required int maxResults,
  }) async {
    var request = CompletionGetSuggestions2Params(
      path,
      completionOffset,
      maxResults,
    ).toRequest('0', clientUriConverter: server.uriConverter);

    var response = await handleSuccessfulRequest(request);
    var result = CompletionGetSuggestions2Result.fromResponse(
      response,
      clientUriConverter: server.uriConverter,
    );

    // Extract the internal request object.
    var dartRequest = server.completionState.currentRequest;

    return CompletionResponseForTesting(
      requestOffset: completionOffset,
      requestLocationName: dartRequest?.collectorLocationName,
      opTypeLocationName: dartRequest?.opType.completionLocation,
      replacementOffset: result.replacementOffset,
      replacementLength: result.replacementLength,
      isIncomplete: result.isIncomplete,
      suggestions: result.suggestions,
    );
  }

  Future<CompletionResponseForTesting> _getTestCodeSuggestions(
    String content, {
    int maxResults = 1 << 10,
  }) {
    return _getCodeSuggestions(
      path: convertPath(testFilePath),
      content: content,
      maxResults: maxResults,
    );
  }

  RequestWithFutureResponse _sendTestCompletionRequest(String id, int offset) {
    var request = CompletionGetSuggestions2Params(
      testFile.path,
      0,
      1 << 10,
    ).toRequest(id, clientUriConverter: server.uriConverter);
    var futureResponse = handleRequest(request);
    return RequestWithFutureResponse(offset, request, futureResponse);
  }
}

class RequestWithFutureResponse {
  final int offset;
  final Request request;
  final Future<Response> futureResponse;

  RequestWithFutureResponse(this.offset, this.request, this.futureResponse);

  Future<CompletionResponseForTesting> toResponse() async {
    var response = await futureResponse;
    expect(response, isResponseSuccess(request.id));
    var result = CompletionGetSuggestions2Result.fromResponse(
      response,
      clientUriConverter: null,
    );
    return CompletionResponseForTesting(
      requestOffset: offset,
      requestLocationName: null,
      opTypeLocationName: null,
      replacementOffset: result.replacementOffset,
      replacementLength: result.replacementLength,
      isIncomplete: result.isIncomplete,
      suggestions: result.suggestions,
    );
  }
}

class _SuggestionDetailsPrinter {
  final StringBuffer buffer;
  final CompletionGetSuggestionDetails2Result result;
  final ResourceProvider resourceProvider;
  final Map<File, String> fileDisplayMap;

  String _indent = '';

  _SuggestionDetailsPrinter({
    required this.buffer,
    required this.result,
    required this.resourceProvider,
    required this.fileDisplayMap,
  });

  void writeResult() {
    _writelnWithIndent('completion: ${result.completion}');
    _withIndent(() {
      _writeChange(result.change);
    });
  }

  void _withIndent(void Function() f) {
    var indent = _indent;
    _indent = '$_indent  ';
    f();
    _indent = indent;
  }

  void _writeChange(SourceChange change) {
    _writelnWithIndent('change');
    _withIndent(() {
      for (var fileEdit in change.edits) {
        _writeSourceFileEdit(fileEdit);
      }
    });
  }

  void _writelnWithIndent(String line) {
    buffer.write(_indent);
    buffer.writeln(line);
  }

  void _writeSourceEdit(SourceEdit edit) {
    _writelnWithIndent('offset: ${edit.offset}');
    _writelnWithIndent('length: ${edit.length}');

    var replacementStr = edit.replacement.replaceAll('\n', r'\n');
    _writelnWithIndent('replacement: $replacementStr');
  }

  void _writeSourceFileEdit(SourceFileEdit fileEdit) {
    var file = resourceProvider.getFile(fileEdit.file);
    var fileStr = fileDisplayMap[file] ?? fail('No display name: $file');
    _writelnWithIndent(fileStr);

    _withIndent(() {
      for (var edit in fileEdit.edits) {
        _writeSourceEdit(edit);
      }
    });
  }
}

extension on CompletionSuggestion {
  bool get isClass {
    return kind == CompletionSuggestionKind.IDENTIFIER &&
        element?.kind == ElementKind.CLASS;
  }
}
