| // 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 'package:analysis_server/protocol/protocol_generated.dart'; | |
| import 'package:analysis_server/src/protocol_server.dart'; | |
| import 'package:analyzer/file_system/file_system.dart'; | |
| import 'package:test/test.dart'; | |
| import 'package:test_reflective_loader/test_reflective_loader.dart'; | |
| import '../analysis_server_base.dart'; | |
| void main() { | |
| defineReflectiveSuite(() { | |
| defineReflectiveTests(AnalysisHoverBlazeTest); | |
| defineReflectiveTests(AnalysisHoverTest); | |
| }); | |
| } | |
| @reflectiveTest | |
| class AnalysisHoverBlazeTest extends BlazeWorkspaceAnalysisServerTest { | |
| Future<void> test_blaze_notOwnedUri() async { | |
| newFile( | |
| '$workspaceRootPath/blaze-genfiles/dart/my/lib/test.dart', | |
| '// generated', | |
| ); | |
| await setRoots(included: [workspaceRootPath], excluded: []); | |
| var testFile = newFile('$myPackageLibPath/test.dart', ''' | |
| class A {} | |
| '''); | |
| var request = AnalysisGetHoverParams( | |
| testFile.path, | |
| 0, | |
| ).toRequest('0', clientUriConverter: server.uriConverter); | |
| var response = await handleRequest(request); | |
| assertResponseFailure( | |
| response, | |
| requestId: '0', | |
| errorCode: RequestErrorCode.FILE_NOT_ANALYZED, | |
| ); | |
| } | |
| } | |
| @reflectiveTest | |
| class AnalysisHoverTest extends PubPackageAnalysisServerTest { | |
| Future<HoverInformation> prepareHover(String search, {File? inFile}) async { | |
| return (await prepareHoverOrNull(search, inFile: inFile))!; | |
| } | |
| Future<HoverInformation?> prepareHoverAt(int offset, {File? inFile}) async { | |
| inFile ??= testFile; | |
| await waitForTasksFinished(); | |
| var request = AnalysisGetHoverParams( | |
| inFile.path, | |
| offset, | |
| ).toRequest('0', clientUriConverter: server.uriConverter); | |
| var response = await handleSuccessfulRequest(request); | |
| var result = AnalysisGetHoverResult.fromResponse( | |
| response, | |
| clientUriConverter: server.uriConverter, | |
| ); | |
| return result.hovers.firstOrNull; | |
| } | |
| Future<HoverInformation?> prepareHoverOrNull(String search, {File? inFile}) { | |
| inFile ??= testFile; | |
| var offset = offsetInFile(inFile, search); | |
| return prepareHoverAt(offset, inFile: inFile); | |
| } | |
| @override | |
| Future<void> setUp() async { | |
| super.setUp(); | |
| await setRoots(included: [workspaceRootPath], excluded: []); | |
| } | |
| Future<void> test_binaryOperator() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| /// doc op | |
| A operator +(A other) => this; | |
| } | |
| var a = A() + A(); | |
| '''); | |
| var hover = await prepareHover('+ A()'); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.dartdoc, 'doc op'); | |
| expect(hover.elementDescription, 'A +(A other)'); | |
| expect(hover.elementKind, 'method'); | |
| // types | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| // no parameter. | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_binaryOperator_leftHandSide() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| /// doc aaa | |
| A(); | |
| A operator +(int other) => this; | |
| } | |
| var a = A() + A(); | |
| '''); | |
| var hover = await prepareHover('A() +'); | |
| // element | |
| expect(hover.elementDescription, '(new) A()'); | |
| // don't show parameter information for binary operators | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_binaryOperator_rightHandSide() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| A(); | |
| A operator +(int other) => this; | |
| } | |
| var a = A() + A(); // 1 | |
| '''); | |
| var hover = await prepareHover('A(); // 1'); | |
| // element | |
| expect(hover.elementDescription, '(new) A()'); | |
| // don't show parameter information for binary operators | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_class_constructor_factory() async { | |
| newFile(testFilePath, ''' | |
| class C { | |
| new (); | |
| /// my doc | |
| factory (int x) => C(); | |
| } | |
| '''); | |
| var hover = await prepareHover('factory'); | |
| // range | |
| expect(hover.offset, findOffset('factory')); | |
| expect(hover.length, 'factory'.length); | |
| // element | |
| expect(hover.dartdoc, 'my doc'); | |
| expect(hover.elementDescription, 'C(int x)'); | |
| expect(hover.elementKind, 'constructor'); | |
| } | |
| Future<void> test_class_constructor_named() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| /// my doc | |
| A.named() {} | |
| } | |
| void f() { | |
| new A.named(); | |
| } | |
| '''); | |
| void onConstructor(HoverInformation hover) { | |
| // range | |
| expect(hover.offset, findOffset('new A') + 'new '.length); | |
| expect(hover.length, 'A.named'.length); | |
| // element | |
| expect(hover.dartdoc, 'my doc'); | |
| expect(hover.elementDescription, 'A.named()'); | |
| expect(hover.elementKind, 'constructor'); | |
| } | |
| { | |
| var hover = await prepareHover('new A'); | |
| onConstructor(hover); | |
| } | |
| { | |
| var hover = await prepareHover('named();'); | |
| onConstructor(hover); | |
| } | |
| } | |
| Future<void> test_class_constructor_named_declaration() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| /// my doc | |
| A.named() {} | |
| } | |
| '''); | |
| void onConstructor(HoverInformation hover) { | |
| // range | |
| expect(hover.offset, findOffset('A.named')); | |
| expect(hover.length, 'A.named'.length); | |
| // element | |
| expect(hover.dartdoc, 'my doc'); | |
| expect(hover.elementDescription, 'A.named()'); | |
| expect(hover.elementKind, 'constructor'); | |
| } | |
| { | |
| var hover = await prepareHover('A.'); | |
| onConstructor(hover); | |
| } | |
| { | |
| var hover = await prepareHover('named()'); | |
| onConstructor(hover); | |
| } | |
| } | |
| Future<void> test_class_constructor_new() async { | |
| newFile(testFilePath, ''' | |
| class C { | |
| /// my doc | |
| new (int x); | |
| } | |
| '''); | |
| var hover = await prepareHover('new'); | |
| // range | |
| expect(hover.offset, findOffset('new')); | |
| expect(hover.length, 'new'.length); | |
| // element | |
| expect(hover.dartdoc, 'my doc'); | |
| expect(hover.elementDescription, 'C(int x)'); | |
| expect(hover.elementKind, 'constructor'); | |
| } | |
| Future<void> test_class_constructor_noKeyword_const() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| const A(int i); | |
| } | |
| void f() { | |
| const a = A(0); | |
| } | |
| '''); | |
| var hover = await prepareHover('A(0)'); | |
| // range | |
| expect(hover.offset, findOffset('A(0)')); | |
| expect(hover.length, 'A'.length); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.dartdoc, isNull); | |
| expect(hover.elementDescription, '(const) A(int i)'); | |
| expect(hover.elementKind, 'constructor'); | |
| // types | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| // no parameter | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_class_constructor_noKeyword_new() async { | |
| newFile(testFilePath, ''' | |
| class A {} | |
| void f() { | |
| var a = A(); | |
| } | |
| '''); | |
| var hover = await prepareHover('A()'); | |
| // range | |
| expect(hover.offset, findOffset('A()')); | |
| expect(hover.length, 'A'.length); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.dartdoc, isNull); | |
| expect(hover.elementDescription, '(new) A()'); | |
| expect(hover.elementKind, 'constructor'); | |
| // types | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| // no parameter | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_class_constructor_primary_declaration() async { | |
| newFile(testFilePath, ''' | |
| /// my class | |
| class A(var int x){ | |
| /// my doc | |
| this; | |
| } | |
| '''); | |
| // Hover on the class name shows hover for class not constructor | |
| var hover = await prepareHover('A'); | |
| expect(hover.offset, findOffset('A')); | |
| expect(hover.length, 'A'.length); | |
| // element | |
| expect(hover.dartdoc, 'my class'); | |
| expect(hover.elementDescription, 'class A'); | |
| expect(hover.elementKind, 'class'); | |
| } | |
| Future<void> test_class_constructor_primary_declaration_body() async { | |
| newFile(testFilePath, ''' | |
| class A(var int x){ | |
| /// my doc | |
| this { | |
| print(x); | |
| } | |
| } | |
| '''); | |
| var hover = await prepareHover('this'); | |
| // range | |
| expect(hover.offset, findOffset('A')); | |
| expect(hover.length, 'A'.length); | |
| // element | |
| expect(hover.dartdoc, 'my doc'); | |
| expect(hover.elementDescription, 'A(int x)'); | |
| expect(hover.elementKind, 'constructor'); | |
| } | |
| Future<void> test_class_constructor_primary_named_declaration() async { | |
| newFile(testFilePath, ''' | |
| class A.named(var int x){ | |
| /// my doc | |
| this; | |
| } | |
| '''); | |
| var hover = await prepareHover('named(var int x)'); | |
| // range | |
| expect(hover.offset, findOffset('named')); | |
| expect(hover.length, 'named'.length); | |
| // element | |
| expect(hover.dartdoc, 'my doc'); | |
| expect(hover.elementDescription, 'A.named(int x)'); | |
| expect(hover.elementKind, 'constructor'); | |
| } | |
| Future<void> test_class_constructor_synthetic() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| } | |
| void f() { | |
| new A(); | |
| } | |
| '''); | |
| var hover = await prepareHover('new A'); | |
| // range | |
| expect(hover.offset, findOffset('new A') + 'new '.length); | |
| expect(hover.length, 'A'.length); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.dartdoc, isNull); | |
| expect(hover.elementDescription, 'A()'); | |
| expect(hover.elementKind, 'constructor'); | |
| // types | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| // no parameter | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_class_constructor_synthetic_withTypeArgument() async { | |
| newFile(testFilePath, ''' | |
| class A<T> {} | |
| void f() { | |
| new A<String>(); | |
| } | |
| '''); | |
| void onConstructor(HoverInformation hover) { | |
| // range | |
| expect(hover.offset, findOffset('A<String>')); | |
| expect(hover.length, 'A<String>'.length); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.dartdoc, isNull); | |
| expect(hover.elementDescription, 'A<String>()'); | |
| expect(hover.elementKind, 'constructor'); | |
| // types | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| // no parameter | |
| expect(hover.parameter, isNull); | |
| } | |
| { | |
| var hover = await prepareHover('new A'); | |
| onConstructor(hover); | |
| } | |
| { | |
| var hover = await prepareHover('A<String>()'); | |
| onConstructor(hover); | |
| } | |
| { | |
| var hover = await prepareHover('String>'); | |
| expect(hover.containingLibraryName, 'dart:core'); | |
| expect(hover.offset, findOffset('String>')); | |
| expect(hover.length, 'String'.length); | |
| expect(hover.elementKind, 'class'); | |
| } | |
| } | |
| Future<void> test_class_constructorReference_named() async { | |
| newFile(testFilePath, ''' | |
| class A<T> { | |
| /// doc aaa | |
| /// doc bbb | |
| A.named(); | |
| } | |
| void f() { | |
| A<double>.named; | |
| } | |
| '''); | |
| var hover = await prepareHover('named;'); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, 'A'); | |
| expect(hover.dartdoc, 'doc aaa\ndoc bbb'); | |
| expect(hover.elementDescription, 'A<double>.named()'); | |
| expect(hover.elementKind, 'constructor'); | |
| // types | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| // no parameter | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_class_constructorReference_new() async { | |
| newFile(testFilePath, ''' | |
| class C { | |
| /// my doc | |
| new (int x); | |
| } | |
| void f() { | |
| C.new; | |
| } | |
| '''); | |
| var hover = await prepareHover('new;'); | |
| // range | |
| expect(hover.offset, findOffset('new;')); | |
| expect(hover.length, 'new'.length); | |
| // element | |
| expect(hover.dartdoc, 'my doc'); | |
| expect(hover.elementDescription, 'C(int x)'); | |
| expect(hover.elementKind, 'constructor'); | |
| } | |
| Future<void> test_class_constructorReference_primary() async { | |
| newFile(testFilePath, ''' | |
| class A(final int x, var int y){ | |
| /// doc aaa | |
| this; | |
| } | |
| void f() { | |
| A(3,2); | |
| } | |
| '''); | |
| var hover = await prepareHover('A(3,2)'); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, 'A'); | |
| expect(hover.dartdoc, 'doc aaa'); | |
| expect(hover.elementDescription, '(new) A(int x, int y)'); | |
| expect(hover.elementKind, 'constructor'); | |
| // types | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| // no parameter | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_class_constructorReference_primary_named() async { | |
| newFile(testFilePath, ''' | |
| class C.someName({required var int x, required this._y}){ | |
| int _y; | |
| /// doc aaa | |
| this; | |
| } | |
| void f() { | |
| C.someName(x: 3, y: 4); | |
| } | |
| '''); | |
| var hover = await prepareHover('C.someName(x'); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, 'C'); | |
| expect(hover.dartdoc, 'doc aaa'); | |
| expect( | |
| hover.elementDescription, | |
| '(new) C.someName({required int x, required int y})', | |
| ); | |
| expect(hover.elementKind, 'constructor'); | |
| // types | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| // no parameter | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_class_constructorReference_unnamed_declared() async { | |
| newFile(testFilePath, ''' | |
| class A<T> { | |
| /// doc aaa | |
| /// doc bbb | |
| A(); | |
| } | |
| void f() { | |
| A<double>.new; | |
| } | |
| '''); | |
| var hover = await prepareHover('new;'); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, 'A'); | |
| expect(hover.dartdoc, 'doc aaa\ndoc bbb'); | |
| expect(hover.elementDescription, 'A<double>()'); | |
| expect(hover.elementKind, 'constructor'); | |
| // types | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| // no parameter | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_class_constructorReference_unnamed_declared_new() async { | |
| newFile(testFilePath, ''' | |
| class A<T> { | |
| /// doc aaa | |
| /// doc bbb | |
| A.new(); | |
| } | |
| void f() { | |
| A<double>.new; | |
| } | |
| '''); | |
| var hover = await prepareHover('new;'); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, 'A'); | |
| expect(hover.dartdoc, 'doc aaa\ndoc bbb'); | |
| expect(hover.elementDescription, 'A<double>()'); | |
| expect(hover.elementKind, 'constructor'); | |
| // types | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| // no parameter | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_class_constructorReference_unnamed_synthetic() async { | |
| newFile(testFilePath, ''' | |
| class A<T> {} | |
| void f() { | |
| A<double>.new; | |
| } | |
| '''); | |
| var hover = await prepareHover('new;'); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, 'A'); | |
| expect(hover.dartdoc, isNull); | |
| expect(hover.elementDescription, 'A<double>()'); | |
| expect(hover.elementKind, 'constructor'); | |
| // types | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| // no parameter | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_class_declaration() async { | |
| newFile(testFilePath, ''' | |
| class A<E> {} | |
| class I1<K, V> {} | |
| class I2<E> {} | |
| class M1 {} | |
| class M2<E> {} | |
| class B<T> extends A<T> with M1, M2<int> implements I1<int, String>, I2 {} | |
| '''); | |
| var hover = await prepareHover('B<T>'); | |
| expect(hover.containingClassDescription, null); | |
| expect( | |
| hover.elementDescription, | |
| 'class B<T> extends A<T> with M1, M2<int> ' | |
| 'implements I1<int, String>, I2<dynamic>', | |
| ); | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| } | |
| Future<void> test_class_declaration_abstract() async { | |
| newFile(testFilePath, ''' | |
| class A {} | |
| abstract class B extends A {} | |
| '''); | |
| var hover = await prepareHover('B extends'); | |
| expect(hover.containingClassDescription, null); | |
| expect(hover.elementDescription, 'abstract class B extends A'); | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| } | |
| Future<void> test_class_declaration_base() async { | |
| newFile(testFilePath, ''' | |
| base class A {} | |
| '''); | |
| var hover = await prepareHover('A'); | |
| expect(hover.containingClassDescription, null); | |
| expect(hover.elementDescription, 'base class A'); | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| } | |
| Future<void> test_class_declaration_base_abstract() async { | |
| newFile(testFilePath, ''' | |
| abstract base class A {} | |
| '''); | |
| var hover = await prepareHover('A'); | |
| expect(hover.containingClassDescription, null); | |
| expect(hover.elementDescription, 'abstract base class A'); | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| } | |
| Future<void> test_class_declaration_final() async { | |
| newFile(testFilePath, ''' | |
| final class A {} | |
| '''); | |
| var hover = await prepareHover('A'); | |
| expect(hover.containingClassDescription, null); | |
| expect(hover.elementDescription, 'final class A'); | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| } | |
| Future<void> test_class_declaration_final_abstract() async { | |
| newFile(testFilePath, ''' | |
| abstract final class A {} | |
| '''); | |
| var hover = await prepareHover('A'); | |
| expect(hover.containingClassDescription, null); | |
| expect(hover.elementDescription, 'abstract final class A'); | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| } | |
| Future<void> test_class_declaration_interface() async { | |
| newFile(testFilePath, ''' | |
| interface class A {} | |
| '''); | |
| var hover = await prepareHover('A'); | |
| expect(hover.containingClassDescription, null); | |
| expect(hover.elementDescription, 'interface class A'); | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| } | |
| Future<void> test_class_declaration_interface_abstract() async { | |
| newFile(testFilePath, ''' | |
| abstract interface class A {} | |
| '''); | |
| var hover = await prepareHover('A'); | |
| expect(hover.containingClassDescription, null); | |
| expect(hover.elementDescription, 'abstract interface class A'); | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| } | |
| Future<void> test_class_declaration_mixin() async { | |
| newFile(testFilePath, ''' | |
| mixin class A {} | |
| '''); | |
| var hover = await prepareHover('A'); | |
| expect(hover.containingClassDescription, null); | |
| expect(hover.elementDescription, 'mixin class A'); | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| } | |
| Future<void> test_class_declaration_mixin_base() async { | |
| newFile(testFilePath, ''' | |
| base mixin class A {} | |
| '''); | |
| var hover = await prepareHover('A'); | |
| expect(hover.containingClassDescription, null); | |
| expect(hover.elementDescription, 'base mixin class A'); | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| } | |
| Future<void> test_class_declaration_sealed() async { | |
| newFile(testFilePath, ''' | |
| sealed class A {} | |
| '''); | |
| var hover = await prepareHover('A'); | |
| expect(hover.containingClassDescription, null); | |
| expect(hover.elementDescription, 'sealed class A'); | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| } | |
| Future<void> test_class_getter() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| /// doc aaa | |
| /// doc bbb | |
| String get fff => ''; | |
| } | |
| void f(A a) { | |
| print(a.fff); | |
| } | |
| '''); | |
| var hover = await prepareHover('fff);'); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, 'A'); | |
| expect(hover.dartdoc, '''doc aaa\ndoc bbb'''); | |
| expect(hover.elementDescription, 'String get fff'); | |
| expect(hover.elementKind, 'getter'); | |
| // types | |
| expect(hover.staticType, 'String'); | |
| expect(hover.propagatedType, isNull); | |
| } | |
| Future<void> test_class_getter_generic() async { | |
| newFile(testFilePath, ''' | |
| class A<T> { | |
| /// doc aaa | |
| /// doc bbb | |
| T get fff => throw ''; | |
| } | |
| void f(A<String> a) { | |
| print(a.fff); | |
| } | |
| '''); | |
| var hover = await prepareHover('fff);'); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, 'A'); | |
| expect(hover.dartdoc, '''doc aaa\ndoc bbb'''); | |
| expect(hover.elementDescription, 'String get fff'); | |
| expect(hover.elementKind, 'getter'); | |
| // types | |
| expect(hover.staticType, 'String'); | |
| } | |
| Future<void> test_class_getter_synthetic() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| /// doc aaa | |
| /// doc bbb | |
| String fff; | |
| } | |
| void f(A a) { | |
| print(a.fff); | |
| } | |
| '''); | |
| var hover = await prepareHover('fff);'); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, 'A'); | |
| expect(hover.dartdoc, '''doc aaa\ndoc bbb'''); | |
| // Synthetic getters are now shown as getters to avoid confusing | |
| // users by hiding them. | |
| // https://github.com/dart-lang/sdk/issues/55956 | |
| expect(hover.elementDescription, 'String get fff'); | |
| expect(hover.elementKind, 'getter'); | |
| // types | |
| expect(hover.staticType, 'String'); | |
| expect(hover.propagatedType, isNull); | |
| } | |
| Future<void> test_class_method_declaration() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| /// doc aaa | |
| /// doc bbb | |
| List<String> mmm(int a, String b) { | |
| } | |
| } | |
| '''); | |
| var hover = await prepareHover('mmm(int a'); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, 'A'); | |
| expect(hover.dartdoc, '''doc aaa\ndoc bbb'''); | |
| expect(hover.elementDescription, 'List<String> mmm(int a, String b)'); | |
| expect(hover.elementKind, 'method'); | |
| // types | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| // no parameter | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_class_method_reference() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| List<String> mmm(int a, String b) { | |
| } | |
| } | |
| void f(A a) { | |
| a.mmm(42, 'foo'); | |
| } | |
| '''); | |
| var hover = await prepareHover('mm(42, '); | |
| // range | |
| expect(hover.offset, findOffset('mmm(42, ')); | |
| expect(hover.length, 'mmm'.length); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.elementDescription, 'List<String> mmm(int a, String b)'); | |
| expect(hover.elementKind, 'method'); | |
| expect(hover.isDeprecated, isFalse); | |
| // types | |
| expect(hover.staticType, 'List<String> Function(int, String)'); | |
| expect(hover.propagatedType, isNull); | |
| // no parameter | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_class_method_reference_deprecated() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| @deprecated | |
| static void test() {} | |
| } | |
| void f() { | |
| A.test(); | |
| } | |
| '''); | |
| var hover = await prepareHover('test();'); | |
| // element | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.elementDescription, 'void test()'); | |
| expect(hover.elementKind, 'method'); | |
| expect(hover.isDeprecated, isTrue); | |
| } | |
| Future<void> test_class_method_reference_genericMethod() async { | |
| newFile(testFilePath, ''' | |
| abstract class Stream<T> { | |
| Stream<S> transform<S>(StreamTransformer<T, S> streamTransformer); | |
| } | |
| abstract class StreamTransformer<T, S> {} | |
| f(Stream<int> s) { | |
| s.transform(null); | |
| } | |
| '''); | |
| var hover = await prepareHover('nsform(n'); | |
| // range | |
| expect(hover.offset, findOffset('transform(n')); | |
| expect(hover.length, 'transform'.length); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect( | |
| hover.elementDescription, | |
| 'Stream<S> transform<S>(StreamTransformer<int, S> streamTransformer)', | |
| ); | |
| expect(hover.elementKind, 'method'); | |
| expect(hover.isDeprecated, isFalse); | |
| // types | |
| expect( | |
| hover.staticType, | |
| 'Stream<dynamic> Function(StreamTransformer<int, dynamic>)', | |
| ); | |
| expect(hover.propagatedType, isNull); | |
| // no parameter | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_class_setter() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| /// doc aaa | |
| /// doc bbb | |
| set fff(String value) {} | |
| } | |
| void f(A a) { | |
| a.fff = ''; | |
| } | |
| '''); | |
| var hover = await prepareHover('fff ='); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, 'A'); | |
| expect(hover.dartdoc, '''doc aaa\ndoc bbb'''); | |
| expect(hover.elementDescription, 'set fff(String value)'); | |
| expect(hover.elementKind, 'setter'); | |
| // types | |
| expect(hover.staticType, 'String'); | |
| expect(hover.propagatedType, isNull); | |
| } | |
| Future<void> test_class_setter_generic() async { | |
| newFile(testFilePath, ''' | |
| class A<T> { | |
| /// doc aaa | |
| /// doc bbb | |
| set fff(T value) {} | |
| } | |
| void f(A<String> a) { | |
| a.fff = ''; | |
| } | |
| '''); | |
| var hover = await prepareHover('fff ='); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, 'A'); | |
| expect(hover.dartdoc, '''doc aaa\ndoc bbb'''); | |
| expect(hover.elementDescription, 'set fff(String value)'); | |
| expect(hover.elementKind, 'setter'); | |
| // types | |
| expect(hover.staticType, 'String'); | |
| } | |
| Future<void> test_class_setter_hasDocumentation() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| /// getting | |
| int get foo => 42; | |
| /// setting | |
| set foo(int x) {} | |
| } | |
| void f(A a) { | |
| a.foo = 123; | |
| } | |
| '''); | |
| var hover = await prepareHover('foo = 1'); | |
| expect(hover.containingClassDescription, 'A'); | |
| expect(hover.dartdoc, 'setting'); | |
| expect(hover.elementDescription, 'set foo(int x)'); | |
| expect(hover.elementKind, 'setter'); | |
| } | |
| Future<void> test_class_setter_noDocumentation() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| /// getting | |
| int get foo => 42; | |
| set foo(int x) {} | |
| } | |
| void f(A a) { | |
| a.foo = 123; | |
| } | |
| '''); | |
| var hover = await prepareHover('foo = 1'); | |
| expect(hover.containingClassDescription, 'A'); | |
| expect(hover.dartdoc, '''getting'''); | |
| expect(hover.elementDescription, 'set foo(int x)'); | |
| expect(hover.elementKind, 'setter'); | |
| } | |
| Future<void> test_class_setter_super_hasDocumentation() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| /// pgetting | |
| int get foo => 42; | |
| /// psetting | |
| set foo(int x) {} | |
| } | |
| class B extends A { | |
| /// getting | |
| int get foo => 42; | |
| set foo(int x) {} | |
| } | |
| void f(B b) { | |
| b.foo = 123; | |
| } | |
| '''); | |
| var hover = await prepareHover('foo = '); | |
| expect(hover.containingClassDescription, 'B'); | |
| expect(hover.dartdoc, '''psetting\n\nCopied from `A`.'''); | |
| expect(hover.elementDescription, 'set foo(int x)'); | |
| expect(hover.elementKind, 'setter'); | |
| } | |
| Future<void> test_class_setter_super_noDocumentation() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| /// pgetting | |
| int get foo => 42; | |
| set foo(int x) {} | |
| } | |
| class B extends A { | |
| int get foo => 42; | |
| set foo(int x) {} | |
| } | |
| void f(B b) { | |
| b.foo = 123; | |
| } | |
| '''); | |
| var hover = await prepareHover('foo = '); | |
| expect(hover.containingClassDescription, 'B'); | |
| expect(hover.dartdoc, '''pgetting\n\nCopied from `A`.'''); | |
| expect(hover.elementDescription, 'set foo(int x)'); | |
| expect(hover.elementKind, 'setter'); | |
| } | |
| @failingTest | |
| Future<void> test_class_setter_super_noSetter() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| /// pgetting | |
| int get foo => 42; | |
| } | |
| class B extends A { | |
| set foo(int x) {} | |
| } | |
| void f(B b) { | |
| b.foo = 123; | |
| } | |
| '''); | |
| var hover = await prepareHover('foo = '); | |
| expect(hover.containingClassDescription, 'B'); | |
| expect(hover.dartdoc, '''pgetting'''); | |
| expect(hover.elementDescription, 'set foo(int x)'); | |
| expect(hover.elementKind, 'setter'); | |
| } | |
| Future<void> test_class_setter_synthetic() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| /// doc aaa | |
| /// doc bbb | |
| String fff; | |
| } | |
| void f(A a) { | |
| a.fff = ''; | |
| } | |
| '''); | |
| var hover = await prepareHover('fff ='); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, 'A'); | |
| expect(hover.dartdoc, '''doc aaa\ndoc bbb'''); | |
| // Synthetic getters are now shown as getters to avoid confusing | |
| // users by hiding them. | |
| // https://github.com/dart-lang/sdk/issues/55956 | |
| expect(hover.elementDescription, 'set fff(String value)'); | |
| expect(hover.elementKind, 'setter'); | |
| // types | |
| expect(hover.staticType, 'String'); | |
| expect(hover.propagatedType, isNull); | |
| } | |
| @FailingTest() // TODO(scheglov): implement augmentation | |
| Future<void> | |
| test_constructorInvocation_referenceFromAugmentation_default() async { | |
| var file = newFile('$testPackageLibPath/a.dart', ''' | |
| part of 'test.dart'; | |
| augment class C { | |
| void m() { | |
| C(); | |
| } | |
| } | |
| '''); | |
| newFile(testFilePath, ''' | |
| part 'a.dart'; | |
| class C { | |
| /// default | |
| C(); | |
| } | |
| '''); | |
| var hover = await prepareHover('C();', inFile: file); | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, 'C'); | |
| expect(hover.dartdoc, 'default'); | |
| expect(hover.elementDescription, '(new) C C()'); | |
| expect(hover.elementKind, 'constructor'); | |
| expect(hover.staticType, isNull); | |
| } | |
| @FailingTest() // TODO(scheglov): implement augmentation | |
| Future<void> | |
| test_constructorInvocation_referenceFromAugmentation_named() async { | |
| var file = newFile('$testPackageLibPath/a.dart', ''' | |
| part of 'test.dart'; | |
| augment class C { | |
| void m() { | |
| C.named(); | |
| } | |
| } | |
| '''); | |
| newFile(testFilePath, ''' | |
| part 'a.dart'; | |
| class C { | |
| /// named | |
| C.named(); | |
| } | |
| '''); | |
| var hover = await prepareHover('C.named();', inFile: file); | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, 'C'); | |
| expect(hover.dartdoc, 'named'); | |
| expect(hover.elementDescription, '(new) C C.named()'); | |
| expect(hover.elementKind, 'constructor'); | |
| expect(hover.staticType, isNull); | |
| } | |
| Future<void> test_dartdoc_block() async { | |
| newFile(testFilePath, ''' | |
| /** | |
| * doc aaa | |
| * doc bbb | |
| */ | |
| void f() { | |
| } | |
| '''); | |
| var hover = await prepareHover('f() {'); | |
| expect(hover.dartdoc, '''doc aaa\ndoc bbb'''); | |
| } | |
| Future<void> test_dartdoc_inherited_fromInterface() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| /// my doc | |
| m() {} // in A | |
| } | |
| class B implements A { | |
| m() {} // in B | |
| } | |
| '''); | |
| var hover = await prepareHover('m() {} // in B'); | |
| expect(hover.dartdoc, '''my doc\n\nCopied from `A`.'''); | |
| } | |
| Future<void> test_dartdoc_inherited_fromSuper_direct() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| /// my doc | |
| m() {} // in A | |
| } | |
| class B extends A { | |
| m() {} // in B | |
| } | |
| '''); | |
| var hover = await prepareHover('m() {} // in B'); | |
| expect(hover.dartdoc, '''my doc\n\nCopied from `A`.'''); | |
| } | |
| Future<void> test_dartdoc_inherited_fromSuper_indirect() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| /// my doc | |
| m() {} | |
| } | |
| class B extends A { | |
| m() {} | |
| } | |
| class C extends B { | |
| m() {} // in C | |
| }'''); | |
| var hover = await prepareHover('m() {} // in C'); | |
| expect(hover.dartdoc, '''my doc\n\nCopied from `A`.'''); | |
| } | |
| Future<void> test_dartdoc_inherited_preferSuper() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| /// my doc | |
| m() {} | |
| } | |
| class B extends A { | |
| } | |
| class I { | |
| // wrong doc | |
| m() {} | |
| } | |
| class C extends B implements I { | |
| m() {} // in C | |
| }'''); | |
| var hover = await prepareHover('m() {} // in C'); | |
| expect(hover.dartdoc, '''my doc\n\nCopied from `A`.'''); | |
| } | |
| Future<void> test_dartdoc_line() async { | |
| newFile(testFilePath, ''' | |
| /// doc aaa | |
| /// doc bbb | |
| void f() { | |
| } | |
| '''); | |
| var hover = await prepareHover('f() {'); | |
| expect(hover.dartdoc, '''doc aaa\ndoc bbb'''); | |
| } | |
| Future<void> test_enum_constructor_primary_declaration() async { | |
| newFile(testFilePath, ''' | |
| /// my enum | |
| enum E(int x) { | |
| v(1); | |
| } | |
| '''); | |
| var hover = await prepareHover('E'); | |
| expect(hover.offset, findOffset('E')); | |
| expect(hover.length, 'E'.length); | |
| // element | |
| expect(hover.dartdoc, 'my enum'); | |
| expect(hover.elementDescription, 'enum E'); | |
| expect(hover.elementKind, 'enum'); | |
| } | |
| Future<void> test_enum_constructor_primary_named_declaration() async { | |
| newFile(testFilePath, ''' | |
| /// my enum | |
| enum E.named(int x) { | |
| v(1); | |
| } | |
| '''); | |
| var hover = await prepareHover('named'); | |
| expect(hover.offset, findOffset('named')); | |
| expect(hover.length, 'named'.length); | |
| // element | |
| expect(hover.dartdoc, null); | |
| expect(hover.elementDescription, 'E.named(int x)'); | |
| expect(hover.elementKind, 'constructor'); | |
| } | |
| Future<void> test_enum_declaration() async { | |
| newFile(testFilePath, ''' | |
| enum MyEnum {AAA, BBB, CCC} | |
| '''); | |
| var hover = await prepareHover('MyEnum'); | |
| expect(hover.containingClassDescription, null); | |
| expect(hover.elementDescription, 'enum MyEnum'); | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| } | |
| Future<void> test_enum_getter() async { | |
| newFile(testFilePath, ''' | |
| enum E { | |
| v; | |
| /// doc aaa | |
| /// doc bbb | |
| int get foo => 0; | |
| } | |
| void f(E e) { | |
| print(e.foo); | |
| } | |
| '''); | |
| var hover = await prepareHover('foo);'); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, 'E'); | |
| expect(hover.dartdoc, '''doc aaa\ndoc bbb'''); | |
| expect(hover.elementDescription, 'int get foo'); | |
| expect(hover.elementKind, 'getter'); | |
| } | |
| Future<void> test_enum_getter_synthetic() async { | |
| newFile(testFilePath, ''' | |
| enum E { | |
| v; | |
| /// doc aaa | |
| /// doc bbb | |
| final String fff; | |
| } | |
| void f(E e) { | |
| print(e.fff); | |
| } | |
| '''); | |
| var hover = await prepareHover('fff);'); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, 'E'); | |
| expect(hover.dartdoc, '''doc aaa\ndoc bbb'''); | |
| expect(hover.elementDescription, 'String get fff'); | |
| expect(hover.elementKind, 'getter'); | |
| // types | |
| expect(hover.staticType, 'String'); | |
| expect(hover.propagatedType, isNull); | |
| } | |
| Future<void> test_enum_method_declaration() async { | |
| newFile(testFilePath, ''' | |
| enum E { | |
| v; | |
| /// doc aaa | |
| /// doc bbb | |
| List<String> mmm(int a, String b) { | |
| } | |
| } | |
| '''); | |
| var hover = await prepareHover('mmm(int a'); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, 'E'); | |
| expect(hover.dartdoc, '''doc aaa\ndoc bbb'''); | |
| expect(hover.elementDescription, 'List<String> mmm(int a, String b)'); | |
| expect(hover.elementKind, 'method'); | |
| // types | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| // no parameter | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_enum_method_reference() async { | |
| newFile(testFilePath, ''' | |
| enum E { | |
| v; | |
| List<String> mmm(int a, String b) { | |
| } | |
| } | |
| void f(E e) { | |
| e.mmm(42, 'foo'); | |
| } | |
| '''); | |
| var hover = await prepareHover('mm(42, '); | |
| // range | |
| expect(hover.offset, findOffset('mmm(42, ')); | |
| expect(hover.length, 'mmm'.length); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, 'E'); | |
| expect(hover.elementDescription, 'List<String> mmm(int a, String b)'); | |
| expect(hover.elementKind, 'method'); | |
| expect(hover.isDeprecated, isFalse); | |
| // types | |
| expect(hover.staticType, 'List<String> Function(int, String)'); | |
| expect(hover.propagatedType, isNull); | |
| // no parameter | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_enum_setter_hasDocumentation() async { | |
| newFile(testFilePath, ''' | |
| enum E { | |
| v; | |
| /// getting | |
| int get foo => 42; | |
| /// setting | |
| set foo(int x) {} | |
| } | |
| void f(E e) { | |
| e.foo = 123; | |
| } | |
| '''); | |
| var hover = await prepareHover('foo = '); | |
| expect(hover.containingClassDescription, 'E'); | |
| expect(hover.dartdoc, '''setting'''); | |
| expect(hover.elementDescription, 'set foo(int x)'); | |
| expect(hover.elementKind, 'setter'); | |
| } | |
| Future<void> test_extensionDeclaration() async { | |
| newFile(testFilePath, ''' | |
| class A {} | |
| /// Comment | |
| extension E on A {} | |
| '''); | |
| var hover = await prepareHover('E'); | |
| expect(hover.containingClassDescription, null); | |
| expect(hover.elementDescription, 'extension E on A'); | |
| expect(hover.dartdoc, 'Comment'); | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| } | |
| Future<void> test_extensionType_constructor_primary_declaration() async { | |
| newFile(testFilePath, ''' | |
| /// my extension type | |
| extension type A(var int x){ | |
| } | |
| '''); | |
| var hover = await prepareHover('A'); | |
| expect(hover.offset, findOffset('A')); | |
| expect(hover.length, 'A'.length); | |
| // element | |
| expect(hover.dartdoc, 'my extension type'); | |
| expect(hover.elementDescription, 'extension type A(int x)'); | |
| expect(hover.elementKind, 'extension type'); | |
| } | |
| Future<void> test_extensionType_constructor_primary_declaration_body() async { | |
| newFile(testFilePath, ''' | |
| extension type A(var int x){ | |
| /// my doc | |
| this { | |
| print(x); | |
| } | |
| } | |
| '''); | |
| var hover = await prepareHover('this'); | |
| // range | |
| expect(hover.offset, findOffset('A')); | |
| expect(hover.length, 'A'.length); | |
| // element | |
| expect(hover.dartdoc, 'my doc'); | |
| expect(hover.elementDescription, 'A(int x)'); | |
| expect(hover.elementKind, 'constructor'); | |
| } | |
| Future<void> | |
| test_extensionType_constructor_primary_named_declaration() async { | |
| newFile(testFilePath, ''' | |
| /// my extension type | |
| extension type A.named(int x) { | |
| } | |
| '''); | |
| var hover = await prepareHover('named'); | |
| expect(hover.offset, findOffset('named')); | |
| expect(hover.length, 'named'.length); | |
| // element | |
| expect(hover.dartdoc, null); | |
| expect(hover.elementDescription, 'A.named(int x)'); | |
| expect(hover.elementKind, 'constructor'); | |
| } | |
| Future<void> test_function_multilineElementDescription() async { | |
| // Functions with at least 3 params will have element descriptions formatted | |
| // across multiple lines. | |
| newFile(testFilePath, ''' | |
| List<String> fff(int a, [String b = 'b', String c = 'c']) { | |
| } | |
| '''); | |
| var hover = await prepareHover('fff(int a'); | |
| expect(hover.elementDescription, ''' | |
| List<String> fff( | |
| int a, [ | |
| String b = 'b', | |
| String c = 'c', | |
| ])'''); | |
| } | |
| Future<void> test_function_topLevel_declaration() async { | |
| newFile(testFilePath, ''' | |
| /// doc aaa | |
| /// doc bbb | |
| List<String> fff(int a, [String b = 'b']) { | |
| } | |
| '''); | |
| var hover = await prepareHover('fff(int a'); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, isNull); | |
| expect(hover.dartdoc, '''doc aaa\ndoc bbb'''); | |
| expect( | |
| hover.elementDescription, | |
| "List<String> fff(int a, [String b = 'b'])", | |
| ); | |
| expect(hover.elementKind, 'function'); | |
| // types | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| // no parameter | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_functionReference_classMethod_instance() async { | |
| newFile(testFilePath, ''' | |
| class A<T> { | |
| /// doc aaa | |
| /// doc bbb | |
| int foo<U>(T t, U u) => 0; | |
| } | |
| void f(A<int> a) { | |
| a.foo<double>; | |
| } | |
| '''); | |
| var hover = await prepareHover('foo<double>'); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, 'A'); | |
| expect(hover.dartdoc, '''doc aaa\ndoc bbb'''); | |
| expect(hover.elementDescription, 'int foo<U>(int t, U u)'); | |
| expect(hover.elementKind, 'method'); | |
| // types | |
| expect(hover.staticType, 'int Function<U>(int, U)'); | |
| expect(hover.propagatedType, isNull); | |
| // no parameter | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_functionReference_classMethod_static() async { | |
| newFile(testFilePath, ''' | |
| class A<T> { | |
| /// doc aaa | |
| /// doc bbb | |
| static int foo<U>(U u) => 0; | |
| } | |
| void f() { | |
| A.foo<double>; | |
| } | |
| '''); | |
| var hover = await prepareHover('foo<double>'); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, 'A'); | |
| expect(hover.dartdoc, '''doc aaa\ndoc bbb'''); | |
| expect(hover.elementDescription, 'int foo<U>(U u)'); | |
| expect(hover.elementKind, 'method'); | |
| // types | |
| expect(hover.staticType, 'int Function<U>(U)'); | |
| expect(hover.propagatedType, isNull); | |
| // no parameter | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_functionReference_topLevelFunction() async { | |
| newFile(testFilePath, ''' | |
| /// doc aaa | |
| /// doc bbb | |
| int foo<T>(T a) => 0; | |
| void f() { | |
| foo<double>; | |
| } | |
| '''); | |
| var hover = await prepareHover('foo<double>'); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, isNull); | |
| expect(hover.dartdoc, '''doc aaa\ndoc bbb'''); | |
| expect(hover.elementDescription, 'int foo<T>(T a)'); | |
| expect(hover.elementKind, 'function'); | |
| // types | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| // no parameter | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_integerLiteral() async { | |
| newFile(testFilePath, ''' | |
| void f() { | |
| foo(123); | |
| } | |
| foo(Object myParameter) {} | |
| '''); | |
| var hover = await prepareHover('123'); | |
| // range | |
| expect(hover.offset, findOffset('123')); | |
| expect(hover.length, 3); | |
| // element | |
| expect(hover.containingClassDescription, isNull); | |
| expect(hover.containingLibraryName, isNull); | |
| expect(hover.containingLibraryPath, isNull); | |
| expect(hover.dartdoc, isNull); | |
| expect(hover.elementDescription, isNull); | |
| expect(hover.elementKind, isNull); | |
| // types | |
| expect(hover.staticType, 'int'); | |
| expect(hover.propagatedType, isNull); | |
| // parameter | |
| expect(hover.parameter, 'Object myParameter'); | |
| } | |
| Future<void> test_integerLiteral_promoted() async { | |
| newFile(testFilePath, ''' | |
| void f() { | |
| foo(123); | |
| } | |
| foo(double myParameter) {} | |
| '''); | |
| var hover = await prepareHover('123'); | |
| // range | |
| expect(hover.offset, findOffset('123')); | |
| expect(hover.length, 3); | |
| // element | |
| expect(hover.containingClassDescription, isNull); | |
| expect(hover.containingLibraryName, isNull); | |
| expect(hover.containingLibraryPath, isNull); | |
| expect(hover.dartdoc, isNull); | |
| expect(hover.elementDescription, isNull); | |
| expect(hover.elementKind, isNull); | |
| // types | |
| expect(hover.staticType, 'double'); | |
| expect(hover.propagatedType, isNull); | |
| // parameter | |
| expect(hover.parameter, 'double myParameter'); | |
| } | |
| Future<void> test_invalidFilePathFormat_notAbsolute() async { | |
| var request = AnalysisGetHoverParams( | |
| 'test.dart', | |
| 0, | |
| ).toRequest('0', clientUriConverter: server.uriConverter); | |
| var response = await handleRequest(request); | |
| assertResponseFailure( | |
| response, | |
| requestId: '0', | |
| errorCode: RequestErrorCode.INVALID_FILE_PATH_FORMAT, | |
| ); | |
| } | |
| Future<void> test_invalidFilePathFormat_notNormalized() async { | |
| var request = AnalysisGetHoverParams( | |
| convertPath('/foo/../bar/test.dart'), | |
| 0, | |
| ).toRequest('0', clientUriConverter: server.uriConverter); | |
| var response = await handleRequest(request); | |
| assertResponseFailure( | |
| response, | |
| requestId: '0', | |
| errorCode: RequestErrorCode.INVALID_FILE_PATH_FORMAT, | |
| ); | |
| } | |
| Future<void> test_localVariable_declaration() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| m() { | |
| num vvv = 42; | |
| } | |
| } | |
| '''); | |
| var hover = await prepareHover('vvv = 42'); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, isNotNull); | |
| expect(hover.containingClassDescription, 'A'); | |
| expect(hover.containingExecutableDescriptions, ['m']); | |
| expect(hover.dartdoc, isNull); | |
| expect(hover.elementDescription, 'num vvv'); | |
| expect(hover.elementKind, 'local variable'); | |
| // types | |
| expect(hover.staticType, 'num'); | |
| expect(hover.propagatedType, null); | |
| // no parameter | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_localVariable_reference_withPropagatedType() async { | |
| newFile(testFilePath, ''' | |
| void f() { | |
| var vvv = 123; | |
| print(vvv); | |
| } | |
| '''); | |
| var hover = await prepareHover('vvv);'); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, isNotNull); | |
| expect(hover.containingClassDescription, isNull); | |
| expect(hover.dartdoc, isNull); | |
| expect(hover.elementDescription, 'int vvv'); | |
| expect(hover.elementKind, 'local variable'); | |
| // types | |
| expect(hover.staticType, 'int'); | |
| expect(hover.propagatedType, null); | |
| } | |
| Future<void> test_methodInvocation_recordType() async { | |
| newFile(testFilePath, ''' | |
| class C { | |
| List<int> m(int i, (int, String) r) => []; | |
| } | |
| void f(C c) { | |
| c.m((1, '1')); | |
| } | |
| '''); | |
| var hover = await prepareHover('m((1'); | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, 'C'); | |
| expect(hover.dartdoc, isNull); | |
| expect(hover.elementDescription, 'List<int> m(int i, (int, String) r)'); | |
| expect(hover.elementKind, 'method'); | |
| expect(hover.staticType, 'List<int> Function(int, (int, String))'); | |
| } | |
| Future<void> test_methodInvocation_referenceFromAugmentation() async { | |
| var file = newFile('$testPackageLibPath/a.dart', ''' | |
| part of 'test.dart'; | |
| augment class C { | |
| void m(C c) { | |
| c.n(); | |
| } | |
| } | |
| '''); | |
| newFile(testFilePath, ''' | |
| part 'a.dart'; | |
| class C { | |
| /// method n | |
| void n() {} | |
| } | |
| '''); | |
| var hover = await prepareHover('n();', inFile: file); | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, 'C'); | |
| expect(hover.dartdoc, 'method n'); | |
| expect(hover.elementDescription, 'void n()'); | |
| expect(hover.elementKind, 'method'); | |
| expect(hover.staticType, 'void Function()'); | |
| } | |
| Future<void> test_mixin_declaration() async { | |
| newFile(testFilePath, ''' | |
| mixin A on B, C implements D, E {} | |
| class B {} | |
| class C {} | |
| class D {} | |
| class E {} | |
| '''); | |
| var hover = await prepareHover('A'); | |
| expect(hover.elementDescription, 'mixin A on B, C implements D, E'); | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| } | |
| Future<void> test_mixin_declaration_base() async { | |
| newFile(testFilePath, ''' | |
| base mixin A {} | |
| '''); | |
| var hover = await prepareHover('A'); | |
| expect(hover.elementDescription, 'base mixin A on Object'); | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| } | |
| @failingTest | |
| Future<void> test_mixin_reference() async { | |
| newFile(testFilePath, ''' | |
| mixin A {} | |
| abstract class B {} | |
| class C with A implements B {} | |
| '''); | |
| var hover = await prepareHover('A i'); | |
| expect(hover.elementDescription, 'mixin A'); | |
| expect(hover.staticType, isNull); | |
| expect(hover.propagatedType, isNull); | |
| } | |
| Future<void> test_noHoverInfo() async { | |
| newFile(testFilePath, ''' | |
| void f() { | |
| // nothing | |
| } | |
| '''); | |
| var hover = await prepareHoverOrNull('nothing'); | |
| expect(hover, isNull); | |
| } | |
| Future<void> test_nonNullable() async { | |
| newFile(testFilePath, ''' | |
| int? f(double? a) => null; | |
| void f() { | |
| f(null); | |
| } | |
| '''); | |
| var hover = await prepareHover('f(null)'); | |
| expect(hover.elementDescription, 'int? f(double? a)'); | |
| expect(hover.staticType, 'int? Function(double?)'); | |
| } | |
| Future<void> test_nullAwareElement_inList() async { | |
| newFile(testFilePath, ''' | |
| void f(int? x) { | |
| [?x]; | |
| } | |
| '''); | |
| var hover = await prepareHover('x];'); | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, isNotNull); | |
| expect(hover.containingClassDescription, isNull); | |
| expect(hover.dartdoc, isNull); | |
| expect(hover.elementDescription, 'int? x'); | |
| expect(hover.elementKind, 'parameter'); | |
| expect(hover.staticType, 'int?'); | |
| } | |
| Future<void> test_nullAwareElement_inSet() async { | |
| newFile(testFilePath, ''' | |
| void f(int? x) { | |
| {?x}; | |
| } | |
| '''); | |
| var hover = await prepareHover('x};'); | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, isNotNull); | |
| expect(hover.containingClassDescription, isNull); | |
| expect(hover.dartdoc, isNull); | |
| expect(hover.elementDescription, 'int? x'); | |
| expect(hover.elementKind, 'parameter'); | |
| expect(hover.staticType, 'int?'); | |
| } | |
| Future<void> test_nullAwareKey_inMap() async { | |
| newFile(testFilePath, ''' | |
| void f(int? x) { | |
| {?x: ""}; | |
| } | |
| '''); | |
| var hover = await prepareHover('x: '); | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, isNotNull); | |
| expect(hover.containingClassDescription, isNull); | |
| expect(hover.dartdoc, isNull); | |
| expect(hover.elementDescription, 'int? x'); | |
| expect(hover.elementKind, 'parameter'); | |
| expect(hover.staticType, 'int?'); | |
| } | |
| Future<void> test_nullAwareValue_inMap() async { | |
| newFile(testFilePath, ''' | |
| void f(int? x) { | |
| {"": ?x}; | |
| } | |
| '''); | |
| var hover = await prepareHover('x};'); | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, isNotNull); | |
| expect(hover.containingClassDescription, isNull); | |
| expect(hover.dartdoc, isNull); | |
| expect(hover.elementDescription, 'int? x'); | |
| expect(hover.elementKind, 'parameter'); | |
| expect(hover.staticType, 'int?'); | |
| } | |
| Future<void> test_parameter_declaration_fieldFormal() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| /// The field documentation. | |
| final int fff; | |
| A({this.fff}); | |
| } | |
| void f() { | |
| new A(fff: 42); | |
| } | |
| '''); | |
| var hover = await prepareHover('fff});'); | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, isNotNull); | |
| expect(hover.containingClassDescription, 'A'); | |
| expect(hover.containingExecutableDescriptions, ['new']); | |
| expect(hover.dartdoc, 'The field documentation.'); | |
| expect(hover.elementDescription, '{int fff}'); | |
| expect(hover.elementKind, 'parameter'); | |
| expect(hover.staticType, 'int'); | |
| } | |
| Future<void> test_parameter_declaration_required() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| /// The method documentation. | |
| m(int p) { | |
| } | |
| } | |
| '''); | |
| var hover = await prepareHover('p) {'); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, isNotNull); | |
| expect(hover.containingClassDescription, 'A'); | |
| expect(hover.containingExecutableDescriptions, ['m']); | |
| expect(hover.dartdoc, 'The method documentation.'); | |
| expect(hover.elementDescription, 'int p'); | |
| expect(hover.elementKind, 'parameter'); | |
| // types | |
| expect(hover.staticType, 'int'); | |
| expect(hover.propagatedType, isNull); | |
| // no parameter | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_parameter_defaultValue() async { | |
| newFile(testFilePath, 'void b([int a=123]) { }'); | |
| var hover = await prepareHover('a='); | |
| // element | |
| expect(hover.elementDescription, '[int a = 123]'); | |
| expect(hover.elementKind, 'parameter'); | |
| } | |
| Future<void> | |
| test_parameter_ofConstructor_optionalPositional_super_defaultValue_explicit() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| A([int a = 1]); | |
| } | |
| class B extends A { | |
| B([super.a = 2]); | |
| } | |
| '''); | |
| var hover = await prepareHover('a = 2]'); | |
| // element | |
| expect(hover.elementDescription, '[int a = 2]'); | |
| expect(hover.elementKind, 'parameter'); | |
| } | |
| Future<void> | |
| test_parameter_ofConstructor_optionalPositional_super_defaultValue_inherited() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| A([int a = 1]); | |
| } | |
| class B extends A { | |
| B([super.a]); | |
| } | |
| '''); | |
| var hover = await prepareHover('a]'); | |
| // element | |
| expect(hover.elementDescription, '[int a = 1]'); | |
| expect(hover.elementKind, 'parameter'); | |
| } | |
| Future<void> | |
| test_parameter_ofConstructor_optionalPositional_super_defaultValue_inherited2() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| A([num a = 1.2]); | |
| } | |
| class B extends A{ | |
| B([int super.a]); | |
| } | |
| '''); | |
| var hover = await prepareHover('a]'); | |
| // element | |
| expect(hover.elementDescription, '[int a]'); | |
| expect(hover.elementKind, 'parameter'); | |
| } | |
| Future<void> test_parameter_ofPrimaryConstructor() async { | |
| newFile(testFilePath, ''' | |
| class A({var int a = 1}); | |
| void f() { | |
| new A(a: 42); | |
| } | |
| '''); | |
| var hover = await prepareHover('a = 1'); | |
| // element | |
| expect(hover.elementDescription, '{int a = 1}'); | |
| expect(hover.elementKind, 'parameter'); | |
| expect(hover.staticType, 'int'); | |
| var hover2 = await prepareHover('a: 42'); | |
| // element | |
| expect(hover2.elementDescription, '{int a = 1}'); | |
| expect(hover2.elementKind, 'parameter'); | |
| expect(hover2.staticType, 'int'); | |
| } | |
| Future<void> test_parameter_reference_deprecated_optional() async { | |
| newFile(testFilePath, ''' | |
| void f({@Deprecated.optional() int p}) {} | |
| void g() { | |
| f(p: 1); | |
| } | |
| '''); | |
| var hover = await prepareHover('f(p: 1);'); | |
| // element | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.elementDescription, 'void f({int p})'); | |
| expect(hover.elementKind, 'function'); | |
| expect(hover.isDeprecated, isFalse); | |
| } | |
| Future<void> test_parameter_reference_fieldFormal() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| /// The field documentation. | |
| final int fff; | |
| A({this.fff}); | |
| } | |
| void f() { | |
| new A(fff: 42); | |
| } | |
| '''); | |
| var hover = await prepareHover('fff: 42'); | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, isNotNull); | |
| expect(hover.containingClassDescription, 'A'); | |
| expect(hover.containingExecutableDescriptions, ['new']); | |
| expect(hover.dartdoc, 'The field documentation.'); | |
| expect(hover.elementDescription, '{int fff}'); | |
| expect(hover.elementKind, 'parameter'); | |
| expect(hover.staticType, 'int'); | |
| } | |
| Future<void> test_parameter_reference_privateNamed() async { | |
| newFile(testFilePath, ''' | |
| class A { | |
| /// The field documentation. | |
| final int _fff; | |
| A({this._fff}); | |
| } | |
| void f() { | |
| new A(fff: 42); | |
| } | |
| '''); | |
| var hover = await prepareHover('fff: 42'); | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, isNotNull); | |
| expect(hover.containingClassDescription, 'A'); | |
| expect(hover.containingExecutableDescriptions, ['new']); | |
| expect(hover.dartdoc, 'The field documentation.'); | |
| expect(hover.elementDescription, '{int fff}'); | |
| expect(hover.elementKind, 'parameter'); | |
| expect(hover.staticType, 'int'); | |
| } | |
| Future<void> test_parameter_reference_recordType() async { | |
| newFile(testFilePath, ''' | |
| void f((int, String) r) { | |
| print(r); | |
| } | |
| '''); | |
| var hover = await prepareHover('r);'); | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, isNotNull); | |
| expect(hover.containingClassDescription, isNull); | |
| expect(hover.dartdoc, isNull); | |
| expect(hover.elementDescription, '(int, String) r'); | |
| expect(hover.elementKind, 'parameter'); | |
| expect(hover.staticType, '(int, String)'); | |
| } | |
| Future<void> test_recordLiteral() async { | |
| newFile(testFilePath, ''' | |
| Object f() { | |
| return ( 1, 'two', true ); | |
| } | |
| '''); | |
| var hover = await prepareHover('( 1'); | |
| expect(hover.containingLibraryName, isNull); | |
| expect(hover.containingLibraryPath, isNull); | |
| expect(hover.containingClassDescription, isNull); | |
| expect(hover.dartdoc, isNull); | |
| expect(hover.elementDescription, isNull); | |
| expect(hover.elementKind, isNull); | |
| expect(hover.staticType, '(int, String, bool)'); | |
| } | |
| Future<void> test_simpleIdentifier_typedef_functionType() async { | |
| newFile(testFilePath, ''' | |
| typedef A = void Function(int); | |
| '''); | |
| var hover = await prepareHover('A'); | |
| _assertHover( | |
| hover, | |
| elementDescription: 'typedef A = void Function(int)', | |
| elementKind: 'type alias', | |
| ); | |
| } | |
| Future<void> test_simpleIdentifier_typedef_interfaceType() async { | |
| newFile(testFilePath, ''' | |
| typedef A = Map<int, String>; | |
| '''); | |
| var hover = await prepareHover('A'); | |
| _assertHover( | |
| hover, | |
| elementDescription: 'typedef A = Map<int, String>', | |
| elementKind: 'type alias', | |
| ); | |
| } | |
| Future<void> test_simpleIdentifier_typedef_legacy() async { | |
| newFile(testFilePath, ''' | |
| typedef void A(int a); | |
| '''); | |
| var hover = await prepareHover('A'); | |
| _assertHover( | |
| hover, | |
| elementDescription: 'typedef A = void Function(int a)', | |
| elementKind: 'type alias', | |
| ); | |
| } | |
| Future<void> test_topLevel_setter() async { | |
| newFile(testFilePath, ''' | |
| /// doc aaa | |
| /// doc bbb | |
| set fff(String value) {} | |
| void f() { | |
| fff = ''; | |
| } | |
| '''); | |
| var hover = await prepareHover('fff ='); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, testFile.path); | |
| expect(hover.containingClassDescription, isNull); | |
| expect(hover.dartdoc, '''doc aaa\ndoc bbb'''); | |
| expect(hover.elementDescription, 'set fff(String value)'); | |
| expect(hover.elementKind, 'setter'); | |
| // types | |
| expect(hover.staticType, 'String'); | |
| expect(hover.propagatedType, isNull); | |
| // don't show parameter for setters | |
| expect(hover.parameter, isNull); | |
| } | |
| Future<void> test_topLevel_setter_parameter() async { | |
| newFile(testFilePath, ''' | |
| set fff(String value) {} | |
| void f(String x) { | |
| fff = x; | |
| } | |
| '''); | |
| var hover = await prepareHover('x;'); | |
| // element | |
| expect(hover.containingLibraryName, 'package:test/test.dart'); | |
| expect(hover.containingLibraryPath, isNotNull); | |
| expect(hover.containingClassDescription, isNull); | |
| expect(hover.elementDescription, 'String x'); | |
| expect(hover.elementKind, 'parameter'); | |
| // types | |
| expect(hover.staticType, 'String'); | |
| expect(hover.propagatedType, isNull); | |
| // don't show parameter information for setters | |
| expect(hover.parameter, isNull); | |
| } | |
| void _assertHover( | |
| HoverInformation hover, { | |
| String? containingLibraryPath, | |
| String? containingLibraryName, | |
| required String elementDescription, | |
| required String elementKind, | |
| bool isDeprecated = false, | |
| }) { | |
| containingLibraryName ??= 'package:test/test.dart'; | |
| expect(hover.containingLibraryName, containingLibraryName); | |
| containingLibraryPath ??= testFile.path; | |
| expect(hover.containingLibraryPath, containingLibraryPath); | |
| expect(hover.elementDescription, elementDescription); | |
| expect(hover.elementKind, elementKind); | |
| expect(hover.isDeprecated, isDeprecated); | |
| } | |
| } |