Add async methods for Cider.

Change-Id: I8e7ad68af11933748e40899789169fdcf58124e1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/238003
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Keerti Parthasarathy <keertip@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Konstantin Shcheglov
2022-03-22 00:26:57 +00:00
committed by Commit Bot
parent 3d69c3c0c4
commit b14c3c3607
14 changed files with 311 additions and 168 deletions
@@ -21,7 +21,7 @@ class CiderAssistsComputer {
Future<List<Assist>> compute(
String path, int lineNumber, int colNumber, int length) async {
var result = <Assist>[];
var resolvedUnit = _fileResolver.resolve(path: path);
var resolvedUnit = await _fileResolver.resolve2(path: path);
var lineInfo = resolvedUnit.lineInfo;
var offset = lineInfo.getOffsetOfLine(lineNumber) + colNumber;
@@ -54,14 +54,17 @@ class CiderCompletionComputer {
@visibleForTesting void Function(ResolvedUnitResult)? testResolvedUnit,
}) async {
return _performanceRoot.runAsync('completion', (performance) async {
var resolvedUnit = performance.run('resolution', (performance) {
return _fileResolver.resolve(
completionLine: line,
completionColumn: column,
path: path,
performance: performance,
);
});
var resolvedUnit = await performance.runAsync(
'resolution',
(performance) async {
return _fileResolver.resolve2(
completionLine: line,
completionColumn: column,
path: path,
performance: performance,
);
},
);
if (testResolvedUnit != null) {
testResolvedUnit(resolvedUnit);
@@ -15,6 +15,7 @@ class CiderDocumentSymbolsComputer {
CiderDocumentSymbolsComputer(this._fileResolver);
@Deprecated('Use compute2() instead')
List<DocumentSymbol> compute(String filePath) {
var result = <DocumentSymbol>[];
var resolvedUnit = _fileResolver.resolve(path: filePath);
@@ -35,6 +36,11 @@ class CiderDocumentSymbolsComputer {
return result;
}
Future<List<DocumentSymbol>> compute2(String filePath) async {
// ignore: deprecated_member_use_from_same_package
return compute(filePath);
}
DocumentSymbol _asDocumentSymbol(
Set<SymbolKind> supportedKinds,
LineInfo lineInfo,
+2 -2
View File
@@ -40,7 +40,7 @@ class CiderFixesComputer {
/// Compute quick fixes for errors on the line with the [offset].
Future<List<CiderErrorFixes>> compute(String path, int lineNumber) async {
var result = <CiderErrorFixes>[];
var resolvedUnit = _fileResolver.resolve(path: path);
var resolvedUnit = await _fileResolver.resolve2(path: path);
var lineInfo = resolvedUnit.lineInfo;
@@ -89,7 +89,7 @@ class _CiderDartFixContextImpl extends DartFixContextImpl {
var files = _fileResolver.getFilesWithTopLevelDeclarations(name);
for (var file in files) {
if (file.partOfLibrary == null) {
var libraryElement = _fileResolver.getLibraryByUri(
var libraryElement = await _fileResolver.getLibraryByUri2(
uriStr: file.uriStr,
);
TopLevelDeclarations.addElement(result, libraryElement, name);
@@ -81,6 +81,7 @@ class CheckNameResponse {
String get oldName => canRename.refactoringElement.element.displayName;
@Deprecated('Use computeRenameRanges2() instead')
RenameResponse? computeRenameRanges() {
var elements = <Element>[];
var element = canRename.refactoringElement.element;
@@ -105,6 +106,11 @@ class CheckNameResponse {
}
return RenameResponse(matches, this, flutterWidgetRename: flutterRename);
}
Future<RenameResponse?> computeRenameRanges2() async {
// ignore: deprecated_member_use_from_same_package
return computeRenameRanges();
}
}
class CiderRenameComputer {
@@ -114,6 +120,7 @@ class CiderRenameComputer {
/// Check if the identifier at the [line], [column] for the file at the
/// [filePath] can be renamed.
@Deprecated('Use canRename2() instead')
CanRenameResponse? canRename(String filePath, int line, int column) {
var resolvedUnit = _fileResolver.resolve(path: filePath);
var lineInfo = resolvedUnit.lineInfo;
@@ -144,6 +151,14 @@ class CiderRenameComputer {
return null;
}
/// Check if the identifier at the [line], [column] for the file at the
/// [filePath] can be renamed.
Future<CanRenameResponse?> canRename2(
String filePath, int line, int column) async {
// ignore: deprecated_member_use_from_same_package
return canRename(filePath, line, column);
}
bool _canRenameElement(Element element) {
var enclosingElement = element.enclosingElement;
if (element is ConstructorElement) {
@@ -15,6 +15,7 @@ class CiderSignatureHelpComputer {
CiderSignatureHelpComputer(this._fileResolver);
@Deprecated('Use compute2() instead')
SignatureHelpResponse? compute(String filePath, int line, int column) {
var resolvedUnit = _fileResolver.resolve(path: filePath);
var lineInfo = resolvedUnit.lineInfo;
@@ -44,6 +45,12 @@ class CiderSignatureHelpComputer {
}
return null;
}
Future<SignatureHelpResponse?> compute2(
String filePath, int line, int column) async {
// ignore: deprecated_member_use_from_same_package
return compute(filePath, line, column);
}
}
class SignatureHelpResponse {
@@ -18,8 +18,8 @@ void main() {
@reflectiveTest
class CiderDocumentSymbolsComputerTest extends CiderServiceTest {
void test_class() {
var unitOutline = _compute('''
void test_class() async {
var unitOutline = await _compute('''
abstract class A<K, V> {
int fa, fb;
String fc;
@@ -145,10 +145,10 @@ R fb<R, P>(P p) {}
}
}
void test_isTest_isTestGroup() {
void test_isTest_isTestGroup() async {
BazelMockPackages.instance.addMeta(resourceProvider);
var outline = _compute('''
var outline = await _compute('''
import 'package:meta/meta.dart';
@isTestGroup
@@ -268,11 +268,11 @@ void f() {
);
}
List<DocumentSymbol> _compute(String content) {
Future<List<DocumentSymbol>> _compute(String content) async {
newFile2(testPath, content);
return CiderDocumentSymbolsComputer(
fileResolver,
).compute(convertPath(testPath));
).compute2(convertPath(testPath));
}
void _expect(DocumentSymbol outline,
@@ -76,7 +76,7 @@ void f(A a) {
var a = newFile2('/workspace/dart/test/lib/a.dart', r'''
class Test {}
''');
fileResolver.resolve(path: a.path);
await fileResolver.resolve2(path: a.path);
await _compute(r'''
void f(Test a) {}^
@@ -93,7 +93,7 @@ void f(Test a) {}
var a = newFile2('/workspace/dart/test/lib/a.dart', r'''
enum Test {a, b, c}
''');
fileResolver.resolve(path: a.path);
await fileResolver.resolve2(path: a.path);
await _compute(r'''
void f(Test a) {}^
@@ -112,7 +112,7 @@ extension E on int {
void foo() {}
}
''');
fileResolver.resolve(path: a.path);
await fileResolver.resolve2(path: a.path);
await _compute(r'''
void f() {
@@ -133,7 +133,7 @@ void f() {
var a = newFile2('/workspace/dart/test/lib/a.dart', r'''
void foo() {}
''');
fileResolver.resolve(path: a.path);
await fileResolver.resolve2(path: a.path);
await _compute(r'''
void f() {
@@ -154,7 +154,7 @@ void f() {
var a = newFile2('/workspace/dart/test/lib/a.dart', r'''
mixin Test {}
''');
fileResolver.resolve(path: a.path);
await fileResolver.resolve2(path: a.path);
await _compute(r'''
void f(Test a) {}^
@@ -171,7 +171,7 @@ void f(Test a) {}
var a = newFile2('/workspace/dart/test/lib/a.dart', r'''
var a = 0;
''');
fileResolver.resolve(path: a.path);
await fileResolver.resolve2(path: a.path);
await _compute(r'''
void f() {
@@ -27,8 +27,8 @@ class CiderRenameComputerTest extends CiderServiceTest {
BazelMockPackages.instance.addFlutter(resourceProvider);
}
void test_canRename_class() {
var refactor = _compute(r'''
void test_canRename_class() async {
var refactor = await _compute(r'''
class ^Old {}
}
''');
@@ -37,8 +37,8 @@ class ^Old {}
expect(refactor.refactoringElement.offset, _correctionContext.offset);
}
void test_canRename_field() {
var refactor = _compute(r'''
void test_canRename_field() async {
var refactor = await _compute(r'''
class A {
int ^bar;
void foo() {
@@ -51,8 +51,8 @@ class A {
expect(refactor.refactoringElement.offset, _correctionContext.offset);
}
void test_canRename_field_static_private() {
var refactor = _compute(r'''
void test_canRename_field_static_private() async {
var refactor = await _compute(r'''
class A{
static const ^_val = 1234;
}
@@ -63,8 +63,8 @@ class A{
expect(refactor.refactoringElement.offset, _correctionContext.offset);
}
void test_canRename_function() {
var refactor = _compute(r'''
void test_canRename_function() async {
var refactor = await _compute(r'''
void ^foo() {
}
''');
@@ -73,8 +73,8 @@ void ^foo() {
expect(refactor.refactoringElement.offset, _correctionContext.offset);
}
void test_canRename_label() {
var refactor = _compute(r'''
void test_canRename_label() async {
var refactor = await _compute(r'''
main() {
myLabel:
while (true) {
@@ -89,8 +89,8 @@ main() {
expect(refactor.refactoringElement.offset, _correctionContext.offset);
}
void test_canRename_local() {
var refactor = _compute(r'''
void test_canRename_local() async {
var refactor = await _compute(r'''
void foo() {
var ^a = 0; var b = a + 1;
}
@@ -100,8 +100,8 @@ void foo() {
expect(refactor.refactoringElement.offset, _correctionContext.offset);
}
void test_canRename_method() {
var refactor = _compute(r'''
void test_canRename_method() async {
var refactor = await _compute(r'''
extension E on int {
void ^foo() {}
}
@@ -111,8 +111,8 @@ extension E on int {
expect(refactor.refactoringElement.offset, _correctionContext.offset);
}
void test_canRename_operator() {
var refactor = _compute(r'''
void test_canRename_operator() async {
var refactor = await _compute(r'''
class A{
A operator ^+(A other) => this;
}
@@ -121,8 +121,8 @@ class A{
expect(refactor, isNull);
}
void test_canRename_parameter() {
var refactor = _compute(r'''
void test_canRename_parameter() async {
var refactor = await _compute(r'''
void foo(int ^bar) {
var a = bar + 1;
}
@@ -133,8 +133,8 @@ void foo(int ^bar) {
expect(refactor.refactoringElement.offset, _correctionContext.offset);
}
void test_checkName_class() {
var result = _checkName(r'''
void test_checkName_class() async {
var result = await _checkName(r'''
class ^Old {}
''', 'New');
@@ -142,8 +142,8 @@ class ^Old {}
expect(result.oldName, 'Old');
}
void test_checkName_function() {
var result = _checkName(r'''
void test_checkName_function() async {
var result = await _checkName(r'''
int ^foo() => 2;
''', 'bar');
@@ -151,8 +151,8 @@ int ^foo() => 2;
expect(result.oldName, 'foo');
}
void test_checkName_local() {
var result = _checkName(r'''
void test_checkName_local() async {
var result = await _checkName(r'''
void foo() {
var ^a = 0; var b = a + 1;
}
@@ -162,8 +162,8 @@ void foo() {
expect(result.oldName, 'a');
}
void test_checkName_local_invalid() {
var result = _checkName(r'''
void test_checkName_local_invalid() async {
var result = await _checkName(r'''
void foo() {
var ^a = 0; var b = a + 1;
}
@@ -173,8 +173,8 @@ void foo() {
expect(result.oldName, 'a');
}
void test_checkName_parameter() {
var result = _checkName(r'''
void test_checkName_parameter() async {
var result = await _checkName(r'''
void foo(String ^a) {
var b = a + 1;
}
@@ -184,8 +184,8 @@ void foo(String ^a) {
expect(result.oldName, 'a');
}
void test_checkName_topLevelVariable() {
var result = _checkName(r'''
void test_checkName_topLevelVariable() async {
var result = await _checkName(r'''
var ^foo;
''', 'bar');
@@ -193,8 +193,8 @@ var ^foo;
expect(result.oldName, 'foo');
}
void test_checkName_TypeAlias() {
var result = _checkName(r'''
void test_checkName_TypeAlias() async {
var result = await _checkName(r'''
typedef ^Foo = void Function();
''', 'Bar');
@@ -202,8 +202,8 @@ typedef ^Foo = void Function();
expect(result.oldName, 'Foo');
}
void test_rename_class() {
var result = _rename(r'''
void test_rename_class() async {
var result = await _rename(r'''
class ^Old implements Other {
Old() {}
Old.named() {}
@@ -234,8 +234,8 @@ void f() {
]);
}
void test_rename_class_flutterWidget() {
var result = _rename(r'''
void test_rename_class_flutterWidget() async {
var result = await _rename(r'''
import 'package:flutter/material.dart';
class ^TestPage extends StatefulWidget {
@@ -268,8 +268,8 @@ class TestPageState extends State<TestPage> {
]);
}
void test_rename_field() {
var result = _rename(r'''
void test_rename_field() async {
var result = await _rename(r'''
class A{
int get ^x => 5;
}
@@ -286,8 +286,8 @@ void foo() {
]);
}
void test_rename_field_static_private() {
var result = _rename(r'''
void test_rename_field_static_private() async {
var result = await _rename(r'''
class A{
static const ^_val = 1234;
}
@@ -304,8 +304,8 @@ void foo() {
]);
}
void test_rename_function() {
var result = _rename(r'''
void test_rename_function() async {
var result = await _rename(r'''
test() {}
^foo() {}
void f() {
@@ -324,12 +324,12 @@ void f() {
]);
}
void test_rename_function_imported() {
void test_rename_function_imported() async {
var a = newFile2('/workspace/dart/test/lib/a.dart', r'''
foo() {}
''');
fileResolver.resolve(path: a.path);
var result = _rename(r'''
await fileResolver.resolve2(path: a.path);
var result = await _rename(r'''
import 'a.dart';
void f() {
^foo();
@@ -345,8 +345,8 @@ void f() {
]);
}
void test_rename_local() {
var result = _rename(r'''
void test_rename_local() async {
var result = await _rename(r'''
void foo() {
var ^a = 0; var b = a + 1;
}
@@ -359,8 +359,8 @@ void foo() {
[CharacterLocation(2, 7), CharacterLocation(2, 22)]));
}
void test_rename_parameter() {
var result = _rename(r'''
void test_rename_parameter() async {
var result = await _rename(r'''
void foo(String ^a) {
var b = a + 1;
}
@@ -369,8 +369,8 @@ void foo(String ^a) {
expect(result.checkName.oldName, 'a');
}
void test_rename_propertyAccessor() {
var result = _rename(r'''
void test_rename_propertyAccessor() async {
var result = await _rename(r'''
get foo {}
set foo(x) {}
void f() {
@@ -389,8 +389,8 @@ void f() {
]);
}
void test_rename_typeAlias_functionType() {
var result = _rename(r'''
void test_rename_typeAlias_functionType() async {
var result = await _rename(r'''
typedef ^F = void Function();
void f(F a) {}
''', 'bar');
@@ -401,45 +401,42 @@ void f(F a) {}
]);
}
CheckNameResponse? _checkName(String content, String newName) {
Future<CheckNameResponse?> _checkName(String content, String newName) async {
_updateFile(content);
return CiderRenameComputer(
var canRename = await CiderRenameComputer(
fileResolver,
)
.canRename(
convertPath(testPath),
_correctionContext.line,
_correctionContext.character,
)
?.checkNewName(newName);
).canRename2(
convertPath(testPath),
_correctionContext.line,
_correctionContext.character,
);
return canRename?.checkNewName(newName);
}
CanRenameResponse? _compute(String content) {
Future<CanRenameResponse?> _compute(String content) async {
_updateFile(content);
return CiderRenameComputer(
fileResolver,
).canRename(
).canRename2(
convertPath(testPath),
_correctionContext.line,
_correctionContext.character,
);
}
RenameResponse? _rename(String content, String newName) {
Future<RenameResponse?> _rename(String content, String newName) async {
_updateFile(content);
return CiderRenameComputer(
var canRename = await CiderRenameComputer(
fileResolver,
)
.canRename(
convertPath(testPath),
_correctionContext.line,
_correctionContext.character,
)
?.checkNewName(newName)
?.computeRenameRanges();
).canRename2(
convertPath(testPath),
_correctionContext.line,
_correctionContext.character,
);
return canRename?.checkNewName(newName)?.computeRenameRanges2();
}
void _updateFile(String content) {
@@ -21,8 +21,8 @@ void main() {
class CiderSignatureHelpComputerTest extends CiderServiceTest {
late _CorrectionContext _correctionContext;
void test_noDefaultConstructor() {
var result = _compute('''
void test_noDefaultConstructor() async {
var result = await _compute('''
class A {
A._();
}
@@ -33,7 +33,7 @@ final a = A(^);
expect(result, null);
}
void test_params_multipleNamed() {
void test_params_multipleNamed() async {
final content = '''
/// Does foo.
foo(String s, {bool b = true, bool a}) {
@@ -42,7 +42,7 @@ foo(String s, {bool b = true, bool a}) {
''';
final expectedLabel = 'foo(String s, {bool b = true, bool a})';
testSignature(
await testSignature(
content,
expectedLabel,
'Does foo.',
@@ -54,7 +54,7 @@ foo(String s, {bool b = true, bool a}) {
CharacterLocation(3, 7));
}
void test_params_multipleOptional() {
void test_params_multipleOptional() async {
final content = '''
/// Does foo.
foo(String s, [bool b = true, bool a]) {
@@ -63,7 +63,7 @@ foo(String s, [bool b = true, bool a]) {
''';
final expectedLabel = 'foo(String s, [bool b = true, bool a])';
testSignature(
await testSignature(
content,
expectedLabel,
'Does foo.',
@@ -75,7 +75,7 @@ foo(String s, [bool b = true, bool a]) {
CharacterLocation(3, 7));
}
void test_retrigger_validLocation() {
void test_retrigger_validLocation() async {
final content = '''
/// Does foo.
foo(String s, {bool b = true, bool a}) {
@@ -84,7 +84,7 @@ foo(String s, {bool b = true, bool a}) {
''';
final expectedLabel = 'foo(String s, {bool b = true, bool a})';
testSignature(
await testSignature(
content,
expectedLabel,
'Does foo.',
@@ -96,7 +96,7 @@ foo(String s, {bool b = true, bool a}) {
CharacterLocation(3, 7));
}
void test_simple() {
void test_simple() async {
final content = '''
/// Does foo.
foo(String s, int i) {
@@ -104,7 +104,7 @@ foo(String s, int i) {
}
''';
final expectedLabel = 'foo(String s, int i)';
testSignature(
await testSignature(
content,
expectedLabel,
'Does foo.',
@@ -115,7 +115,7 @@ foo(String s, int i) {
CharacterLocation(3, 7));
}
void test_triggerCharacter_validLocation() {
void test_triggerCharacter_validLocation() async {
final content = '''
/// Does foo.
foo(String s, int i) {
@@ -124,7 +124,7 @@ foo(String s, int i) {
''';
final expectedLabel = 'foo(String s, int i)';
testSignature(
await testSignature(
content,
expectedLabel,
'Does foo.',
@@ -135,7 +135,7 @@ foo(String s, int i) {
CharacterLocation(3, 7));
}
void test_typeParams_class() {
void test_typeParams_class() async {
final content = '''
/// My Foo.
class Foo<T1, T2 extends String> {}
@@ -143,7 +143,7 @@ class Foo<T1, T2 extends String> {}
class Bar extends Foo<^> {}
''';
testSignature(
await testSignature(
content,
'class Foo<T1, T2 extends String>',
'My Foo.',
@@ -154,7 +154,7 @@ class Bar extends Foo<^> {}
CharacterLocation(4, 23));
}
void test_typeParams_function() {
void test_typeParams_function() async {
final content = '''
/// My Foo.
void foo<T1, T2 extends String>() {
@@ -162,7 +162,7 @@ void foo<T1, T2 extends String>() {
}
''';
testSignature(
await testSignature(
content,
'void foo<T1, T2 extends String>()',
'My Foo.',
@@ -173,7 +173,7 @@ void foo<T1, T2 extends String>() {
CharacterLocation(3, 7));
}
void test_typeParams_method() {
void test_typeParams_method() async {
final content = '''
class Foo {
/// My Foo.
@@ -183,7 +183,7 @@ class Foo {
}
''';
testSignature(
await testSignature(
content,
'void foo<T1, T2 extends String>()',
'My Foo.',
@@ -194,13 +194,13 @@ class Foo {
CharacterLocation(4, 9));
}
void testSignature(
Future<void> testSignature(
String content,
String expectedLabel,
String expectedDoc,
List<ParameterInformation> expectedParameters,
CharacterLocation leftParenLocation) {
var result = _compute(content);
CharacterLocation leftParenLocation) async {
var result = await _compute(content);
var signature = result!.signatureHelp.signatures.first;
final expected =
MarkupContent(kind: MarkupKind.Markdown, value: expectedDoc);
@@ -211,12 +211,12 @@ class Foo {
expect(result.callStart == leftParenLocation, isTrue);
}
SignatureHelpResponse? _compute(String content) {
Future<SignatureHelpResponse?> _compute(String content) async {
_updateFile(content);
return CiderSignatureHelpComputer(
fileResolver,
).compute(
).compute2(
convertPath(testPath),
_correctionContext.line,
_correctionContext.character,
@@ -179,18 +179,20 @@ class _MicroAnalysisSessionImpl extends AnalysisSessionImpl {
@override
Future<SomeLibraryElementResult> getLibraryByUri(String uriStr) async {
var element = analysisContext.fileResolver.getLibraryByUri(uriStr: uriStr);
var element = await analysisContext.fileResolver.getLibraryByUri2(
uriStr: uriStr,
);
return LibraryElementResultImpl(element);
}
@override
Future<SomeResolvedLibraryResult> getResolvedLibrary(String path) async {
return analysisContext.fileResolver.resolveLibrary(path: path);
return analysisContext.fileResolver.resolveLibrary2(path: path);
}
@override
Future<SomeResolvedUnitResult> getResolvedUnit(String path) async {
return analysisContext.fileResolver.resolve(path: path);
return analysisContext.fileResolver.resolve2(path: path);
}
@override
@@ -180,6 +180,7 @@ class FileResolver {
/// Looks for references to the given Element. All the files currently
/// cached by the resolver are searched, generated files are ignored.
@Deprecated('Use findReferences2() instead')
List<CiderSearchMatch> findReferences(Element element,
{OperationPerformanceImpl? performance}) {
return logger.run('findReferences for ${element.name}', () {
@@ -220,6 +221,18 @@ class FileResolver {
});
}
/// Looks for references to the given Element. All the files currently
/// cached by the resolver are searched, generated files are ignored.
Future<List<CiderSearchMatch>> findReferences2(Element element,
{OperationPerformanceImpl? performance}) async {
// ignore: deprecated_member_use_from_same_package
return findReferences(
element,
performance: performance,
);
}
@Deprecated('Use getErrors2() instead')
ErrorsResult getErrors({
required String path,
OperationPerformanceImpl? performance,
@@ -275,6 +288,17 @@ class FileResolver {
});
}
Future<ErrorsResult> getErrors2({
required String path,
OperationPerformanceImpl? performance,
}) async {
// ignore: deprecated_member_use_from_same_package
return getErrors(
path: path,
performance: performance,
);
}
FileContext getFileContext({
required String path,
required OperationPerformanceImpl performance,
@@ -311,6 +335,7 @@ class FileResolver {
return fsState.getFilesWithTopLevelDeclarations(name);
}
@Deprecated('Use getLibraryByUri2() instead')
LibraryElement getLibraryByUri({
required String uriStr,
OperationPerformanceImpl? performance,
@@ -344,6 +369,17 @@ class FileResolver {
return libraryContext!.elementFactory.libraryOfUri2(uriStr);
}
Future<LibraryElement> getLibraryByUri2({
required String uriStr,
OperationPerformanceImpl? performance,
}) async {
// ignore: deprecated_member_use_from_same_package
return getLibraryByUri(
uriStr: uriStr,
performance: performance,
);
}
String getLibraryLinkedSignature({
required String path,
required OperationPerformanceImpl performance,
@@ -377,6 +413,7 @@ class FileResolver {
/// partially resynthesized data, and so prepare for loading linked summaries
/// from bytes, which will be done by [getErrors]. It is OK for it to
/// spend some more time on this.
@Deprecated('Use linkLibraries2() instead')
void linkLibraries({
required String path,
}) {
@@ -399,6 +436,32 @@ class FileResolver {
_resetContextObjects();
}
/// Ensure that libraries necessary for resolving [path] are linked.
///
/// Libraries are linked in library cycles, from the bottom to top, so that
/// when we link a cycle, everything it transitively depends is ready. We
/// load newly linked libraries from bytes, and when we link a new library
/// cycle we partially resynthesize AST and elements from previously
/// loaded libraries.
///
/// But when we are done linking libraries, and want to resolve just the
/// very top library that transitively depends on the whole dependency
/// tree, this library will not reference as many elements in the
/// dependencies as we needed for linking. Most probably it references
/// elements from directly imported libraries, and a couple of layers below.
/// So, keeping all previously resynthesized data is usually a waste.
///
/// This method ensures that we discard the libraries context, with all its
/// partially resynthesized data, and so prepare for loading linked summaries
/// from bytes, which will be done by [getErrors2]. It is OK for it to
/// spend some more time on this.
Future<void> linkLibraries2({
required String path,
}) async {
// ignore: deprecated_member_use_from_same_package
linkLibraries(path: path);
}
/// Update the cache with list of invalidated ids and clears [removedCacheIds].
void releaseAndClearRemovedIds() {
byteStore.release(removedCacheIds);
@@ -417,6 +480,7 @@ class FileResolver {
}
/// The [completionLine] and [completionColumn] are zero based.
@Deprecated('Use resolve2() instead')
ResolvedUnitResult resolve({
int? completionLine,
int? completionColumn,
@@ -458,6 +522,23 @@ class FileResolver {
}
/// The [completionLine] and [completionColumn] are zero based.
Future<ResolvedUnitResult> resolve2({
int? completionLine,
int? completionColumn,
required String path,
OperationPerformanceImpl? performance,
}) async {
// ignore: deprecated_member_use_from_same_package
return resolve(
completionLine: completionLine,
completionColumn: completionColumn,
path: path,
performance: performance,
);
}
/// The [completionLine] and [completionColumn] are zero based.
@Deprecated('Use resolveLibrary2() instead')
ResolvedLibraryResult resolveLibrary({
int? completionLine,
int? completionColumn,
@@ -570,6 +651,24 @@ class FileResolver {
});
}
/// The [completionLine] and [completionColumn] are zero based.
Future<ResolvedLibraryResult> resolveLibrary2({
int? completionLine,
int? completionColumn,
String? completionPath,
required String path,
OperationPerformanceImpl? performance,
}) async {
// ignore: deprecated_member_use_from_same_package
return resolveLibrary(
completionLine: completionLine,
completionColumn: completionColumn,
completionPath: completionPath,
path: path,
performance: performance,
);
}
/// Make sure that [fsState], [contextObjects], and [libraryContext] are
/// created and configured with the given [fileAnalysisOptions].
///
@@ -66,9 +66,9 @@ class FileResolutionTest with ResourceProviderMixin, ResolutionTest {
fileResolver.testView = FileResolverTestView();
}
ErrorsResult getTestErrors() {
Future<ErrorsResult> getTestErrors() async {
var path = convertPath(_testFile);
return fileResolver.getErrors(path: path);
return fileResolver.getErrors2(path: path);
}
@override
@@ -76,7 +76,7 @@ class FileResolutionTest with ResourceProviderMixin, ResolutionTest {
String path, {
OperationPerformanceImpl? performance,
}) async {
result = fileResolver.resolve(
result = await fileResolver.resolve2(
path: path,
performance: performance,
);
@@ -393,7 +393,8 @@ void func() {
''');
await resolveFile(bPath);
var result = fileResolver.findReferences(_findElement(6, aPath));
var element = await _findElement(6, aPath);
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
CiderSearchMatch(bPath, [CharacterLocation(4, 11)]),
CiderSearchMatch(aPath, [CharacterLocation(1, 7)])
@@ -414,7 +415,8 @@ class A {
''');
await resolveFile(aPath);
var result = fileResolver.findReferences(_findElement(16, aPath));
var element = await _findElement(16, aPath);
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
CiderSearchMatch(
aPath, [CharacterLocation(2, 7), CharacterLocation(5, 5)])
@@ -433,7 +435,8 @@ foo(String str) {}
''');
await resolveFile(aPath);
var result = fileResolver.findReferences(_findElement(11, aPath));
var element = await _findElement(11, aPath);
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
CiderSearchMatch(
aPath, [CharacterLocation(2, 3), CharacterLocation(5, 1)])
@@ -459,7 +462,8 @@ main() {
''');
await resolveFile(bPath);
var result = fileResolver.findReferences(_findElement(20, aPath));
var element = await _findElement(20, aPath);
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
CiderSearchMatch(bPath, [CharacterLocation(5, 15)]),
CiderSearchMatch(aPath, [CharacterLocation(2, 11)])
@@ -478,7 +482,8 @@ class A {
}
''');
await resolveFile(aPath);
var result = fileResolver.findReferences(_findElement(39, aPath));
var element = await _findElement(39, aPath);
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
CiderSearchMatch(
aPath, [CharacterLocation(3, 9), CharacterLocation(4, 11)])
@@ -511,7 +516,8 @@ main() {
''');
await resolveFile(bPath);
var result = fileResolver.findReferences(_findElement(17, aPath));
var element = await _findElement(17, aPath);
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
CiderSearchMatch(bPath, [CharacterLocation(5, 5)]),
CiderSearchMatch(
@@ -538,7 +544,8 @@ main() {
''');
await resolveFile(bPath);
var result = fileResolver.findReferences(_findElement(21, aPath));
var element = await _findElement(21, aPath);
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
CiderSearchMatch(bPath, [CharacterLocation(5, 5)]),
CiderSearchMatch(aPath, [CharacterLocation(2, 12)])
@@ -565,7 +572,8 @@ main() {
''');
await resolveFile(bPath);
var result = fileResolver.findReferences(_findElement(19, aPath));
var element = await _findElement(19, aPath);
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
CiderSearchMatch(bPath, [CharacterLocation(4, 13)]),
CiderSearchMatch(aPath, [CharacterLocation(3, 9)])
@@ -592,7 +600,8 @@ main() {
''');
await resolveFile(bPath);
var result = fileResolver.findReferences(_findElement(20, aPath));
var element = await _findElement(20, aPath);
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
CiderSearchMatch(bPath, [CharacterLocation(4, 3)]),
CiderSearchMatch(aPath, [CharacterLocation(3, 10)])
@@ -612,7 +621,8 @@ void func() {
''');
await resolveFile(aPath);
var result = fileResolver.findReferences(_findElement(10, aPath));
var element = await _findElement(10, aPath);
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
CiderSearchMatch(
aPath, [CharacterLocation(1, 11), CharacterLocation(4, 11)])
@@ -630,7 +640,8 @@ class Foo<T> {
}
''');
await resolveFile(aPath);
var result = fileResolver.findReferences(_findElement(10, aPath));
var element = await _findElement(10, aPath);
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
CiderSearchMatch(aPath, [
CharacterLocation(1, 11),
@@ -658,7 +669,8 @@ void f(func o) {}
''');
await resolveFile(bPath);
var result = fileResolver.findReferences(_findElement(8, aPath));
var element = await _findElement(8, aPath);
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
CiderSearchMatch(bPath, [CharacterLocation(3, 8)]),
CiderSearchMatch(aPath, [CharacterLocation(1, 9)])
@@ -666,13 +678,13 @@ void f(func o) {}
expect(result, unorderedEquals(expected));
}
test_getErrors() {
test_getErrors() async {
addTestFile(r'''
var a = b;
var foo = 0;
''');
var result = getTestErrors();
var result = await getTestErrors();
expect(result.path, convertPath('/workspace/dart/test/lib/test.dart'));
expect(result.uri.toString(), 'package:dart.test/test.dart');
assertErrorsInList(result.errors, [
@@ -681,7 +693,7 @@ var foo = 0;
expect(result.lineInfo.lineStarts, [0, 11, 24]);
}
test_getErrors_reuse() {
test_getErrors_reuse() async {
addTestFile('var a = b;');
var path = convertPath('/workspace/dart/test/lib/test.dart');
@@ -690,34 +702,34 @@ var foo = 0;
expect(fileResolver.testView!.resolvedLibraries, isEmpty);
// No cached, will resolve once.
expect(getTestErrors().errors, hasLength(1));
expect((await getTestErrors()).errors, hasLength(1));
expect(fileResolver.testView!.resolvedLibraries, [path]);
// Has cached, will be not resolved again.
expect(getTestErrors().errors, hasLength(1));
expect((await getTestErrors()).errors, hasLength(1));
expect(fileResolver.testView!.resolvedLibraries, [path]);
// New resolver.
// Still has cached, will be not resolved.
createFileResolver();
expect(getTestErrors().errors, hasLength(1));
expect((await getTestErrors()).errors, hasLength(1));
expect(fileResolver.testView!.resolvedLibraries, <Object>[]);
// Change the file, new resolver.
// With changed file the previously cached result cannot be used.
addTestFile('var a = c;');
createFileResolver();
expect(getTestErrors().errors, hasLength(1));
expect((await getTestErrors()).errors, hasLength(1));
expect(fileResolver.testView!.resolvedLibraries, [path]);
// New resolver.
// Still has cached, will be not resolved.
createFileResolver();
expect(getTestErrors().errors, hasLength(1));
expect((await getTestErrors()).errors, hasLength(1));
expect(fileResolver.testView!.resolvedLibraries, <Object>[]);
}
test_getErrors_reuse_changeDependency() {
test_getErrors_reuse_changeDependency() async {
newFile2('/workspace/dart/test/lib/a.dart', r'''
var a = 0;
''');
@@ -733,11 +745,11 @@ var b = a.foo;
expect(fileResolver.testView!.resolvedLibraries, isEmpty);
// No cached, will resolve once.
expect(getTestErrors().errors, hasLength(1));
expect((await getTestErrors()).errors, hasLength(1));
expect(fileResolver.testView!.resolvedLibraries, [path]);
// Has cached, will be not resolved again.
expect(getTestErrors().errors, hasLength(1));
expect((await getTestErrors()).errors, hasLength(1));
expect(fileResolver.testView!.resolvedLibraries, [path]);
// Change the dependency, new resolver.
@@ -747,13 +759,13 @@ var b = a.foo;
var a = 4.2;
''');
createFileResolver();
expect(getTestErrors().errors, hasLength(1));
expect((await getTestErrors()).errors, hasLength(1));
expect(fileResolver.testView!.resolvedLibraries, [path]);
// New resolver.
// Still has cached, will be not resolved.
createFileResolver();
expect(getTestErrors().errors, hasLength(1));
expect((await getTestErrors()).errors, hasLength(1));
expect(fileResolver.testView!.resolvedLibraries, <Object>[]);
}
@@ -782,39 +794,41 @@ var b = 1 + 2;
assertHasOneVariable();
}
test_getLibraryByUri() {
test_getLibraryByUri() async {
newFile2('/workspace/dart/my/lib/a.dart', r'''
class A {}
''');
var element = fileResolver.getLibraryByUri(
var element = await fileResolver.getLibraryByUri2(
uriStr: 'package:dart.my/a.dart',
);
expect(element.definingCompilationUnit.classes, hasLength(1));
}
test_getLibraryByUri_notExistingFile() {
var element = fileResolver.getLibraryByUri(
test_getLibraryByUri_notExistingFile() async {
var element = await fileResolver.getLibraryByUri2(
uriStr: 'package:dart.my/a.dart',
);
expect(element.definingCompilationUnit.classes, isEmpty);
}
test_getLibraryByUri_partOf() {
test_getLibraryByUri_partOf() async {
newFile2('/workspace/dart/my/lib/a.dart', r'''
part of 'b.dart';
''');
expect(() {
fileResolver.getLibraryByUri(
expect(() async {
await fileResolver.getLibraryByUri2(
uriStr: 'package:dart.my/a.dart',
);
}, throwsArgumentError);
}
test_getLibraryByUri_unresolvedUri() {
expect(() {
fileResolver.getLibraryByUri(uriStr: 'my:unresolved');
test_getLibraryByUri_unresolvedUri() async {
expect(() async {
await fileResolver.getLibraryByUri2(
uriStr: 'my:unresolved',
);
}, throwsArgumentError);
}
@@ -835,16 +849,16 @@ import 'dart:math';
assertNoErrorsInResult();
}
test_linkLibraries_getErrors() {
test_linkLibraries_getErrors() async {
addTestFile(r'''
var a = b;
var foo = 0;
''');
var path = convertPath('/workspace/dart/test/lib/test.dart');
fileResolver.linkLibraries(path: path);
await fileResolver.linkLibraries2(path: path);
var result = getTestErrors();
var result = await getTestErrors();
expect(result.path, path);
expect(result.uri.toString(), 'package:dart.test/test.dart');
assertErrorsInList(result.errors, [
@@ -1136,7 +1150,7 @@ part of 'a.dart';
var testView = fileResolver.testView!;
expect(testView.resolvedLibraries, isEmpty);
fileResolver.resolve(
await fileResolver.resolve2(
path: b_path,
completionLine: 0,
completionColumn: 0,
@@ -1169,7 +1183,7 @@ void func() {
}
''');
var result = fileResolver.resolveLibrary(path: aPath);
var result = await fileResolver.resolveLibrary2(path: aPath);
expect(result.units.length, 2);
expect(result.units[0].path, aPath);
expect(result.units[0].uri, Uri.parse('package:dart.test/a.dart'));
@@ -1270,8 +1284,8 @@ import 'foo:bar';
expect(fileResolver.fsState!.testView.removedPaths, matcher);
}
Element _findElement(int offset, String filePath) {
var resolvedUnit = fileResolver.resolve(path: filePath);
Future<Element> _findElement(int offset, String filePath) async {
var resolvedUnit = await fileResolver.resolve2(path: filePath);
var node = NodeLocator(offset).searchWithin(resolvedUnit.unit);
var element = getElementOfNode(node);
return element!;