// 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/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 completionOffset = content.indexOf('^');
    expect(completionOffset, isNot(equals(-1)), reason: 'missing ^');

    var nextOffset = content.indexOf('^', completionOffset + 1);
    expect(nextOffset, equals(-1), reason: 'too many ^');

    newFile(
        path,
        content.substring(0, completionOffset) +
            content.substring(completionOffset + 1));

    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,
  }) async {
    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
  foo02
    kind: topLevelVariable
    isNotImported: null
    libraryUri: null
    relevance: 558
  foo01
    kind: topLevelVariable
    isNotImported: null
    libraryUri: null
    relevance: 510
''');
  }

  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
  |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 completionOffset = content.indexOf('^');
    expect(completionOffset, isNot(equals(-1)), reason: 'missing ^');

    var nextOffset = content.indexOf('^', completionOffset + 1);
    expect(nextOffset, equals(-1), reason: 'too many ^');

    newFile(
      path,
      content.substring(0, completionOffset) +
          content.substring(completionOffset + 1),
    );

    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;
  }
}
