Skip to content

Commit 57c4148

Browse files
DanTupCommit Queue
authored andcommitted
[analyzer] Fix exception searching synthetic parameters
This fixes #60005 caused by `source!` by instead handling the null. However, it leaves navigation still not-working for these synthetic parameters (see failing tests). Change-Id: I793130a9533ccf97b523a50d74375ebf6dead7e3 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/411600 Reviewed-by: Konstantin Shcheglov <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Brian Wilkerson <[email protected]>
1 parent 1804a38 commit 57c4148

File tree

5 files changed

+142
-3
lines changed

5 files changed

+142
-3
lines changed

pkg/analysis_server/test/analysis/get_navigation_test.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,25 @@ void f(A a) {
466466
}
467467
}
468468

469+
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/60200')
470+
Future<void> test_parameter_generic() async {
471+
addTestFile('''
472+
void f() {
473+
B().m(p: null);
474+
}
475+
476+
class A<T> {
477+
void m({T? p}) {}
478+
}
479+
480+
class B extends A<String> {}
481+
''');
482+
await waitForTasksFinished();
483+
await _getNavigation(search: 'p: null');
484+
assertHasRegion('p: null');
485+
assertHasTarget('p}) {}');
486+
}
487+
469488
Future<void> test_parameter_wildcard() async {
470489
addTestFile('''
471490
var _ = 0;

pkg/analysis_server/test/search/element_references_test.dart

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -998,6 +998,47 @@ void f(ppp) {
998998
assertHasResult(SearchResultKind.READ, 'ppp();');
999999
}
10001000

1001+
Future<void> test_parameter_generic_declaration() async {
1002+
addTestFile('''
1003+
void f() {
1004+
B().m(p: null); // 1
1005+
B().m(p: null); // 2
1006+
}
1007+
1008+
class A<T> {
1009+
void m({T? p}) {} // 3
1010+
}
1011+
1012+
class B extends A<String> {}
1013+
''');
1014+
await findElementReferences(search: 'p}) {} // 3', false);
1015+
expect(searchElement!.kind, ElementKind.PARAMETER);
1016+
expect(results, hasLength(2));
1017+
assertHasResult(SearchResultKind.REFERENCE, 'p: null); // 1');
1018+
assertHasResult(SearchResultKind.REFERENCE, 'p: null); // 2');
1019+
}
1020+
1021+
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/60200')
1022+
Future<void> test_parameter_generic_invocation() async {
1023+
addTestFile('''
1024+
void f() {
1025+
B().m(p: null); // 1
1026+
B().m(p: null); // 2
1027+
}
1028+
1029+
class A<T> {
1030+
void m({T? p}) {} // 3
1031+
}
1032+
1033+
class B extends A<String> {}
1034+
''');
1035+
await findElementReferences(search: 'p: null); // 1', false);
1036+
expect(searchElement!.kind, ElementKind.PARAMETER);
1037+
expect(results, hasLength(2));
1038+
assertHasResult(SearchResultKind.REFERENCE, 'p: null); // 1');
1039+
assertHasResult(SearchResultKind.REFERENCE, 'p: null); // 2');
1040+
}
1041+
10011042
@failingTest
10021043
Future<void> test_path_inConstructor_named() async {
10031044
// The path does not contain the first expected element.

pkg/analyzer/lib/src/dart/analysis/search.dart

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,11 @@ class Search {
632632
name = externalElement.enclosingElement2.displayName;
633633
}
634634

635-
var elementPath = element.firstFragment.libraryFragment!.source.fullName;
635+
var elementPath = element.firstFragment.libraryFragment?.source.fullName;
636+
if (elementPath == null) {
637+
return;
638+
}
639+
636640
var elementFile = _driver.fsState.getExistingFromPath(elementPath);
637641
if (elementFile == null) {
638642
return;
@@ -896,8 +900,8 @@ class Search {
896900
bool Function(AstNode n) isRootNode,
897901
SearchedFiles searchedFiles,
898902
) async {
899-
String path = element.firstFragment.libraryFragment!.source.fullName;
900-
if (!searchedFiles.add(path, this)) {
903+
String? path = element.firstFragment.libraryFragment?.source.fullName;
904+
if (path == null || !searchedFiles.add(path, this)) {
901905
return const <SearchResult>[];
902906
}
903907

pkg/analyzer/lib/src/dart/element/element.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3418,6 +3418,9 @@ class FormalParameterFragmentImpl extends VariableFragmentImpl
34183418
TypeImpl type,
34193419
ParameterKind parameterKind,
34203420
) {
3421+
// TODO(dantup): This does not keep any reference to the non-synthetic
3422+
// parameter which prevents navigation/references from working. See
3423+
// https://github.com/dart-lang/sdk/issues/60200
34213424
var element = FormalParameterFragmentImpl(
34223425
name: name2 ?? '',
34233426
nameOffset: -1,

pkg/analyzer/test/src/dart/analysis/search_test.dart

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2111,6 +2111,78 @@ main(A<int> a) {
21112111
''');
21122112
}
21132113

2114+
test_searchReferences_ParameterElement_generic_atDeclaration() async {
2115+
await resolveTestCode('''
2116+
void f() {
2117+
B().m(p: null); // 1
2118+
B().m(p: null); // 2
2119+
}
2120+
2121+
class A<T> {
2122+
void m({T? p}) {} // 3
2123+
}
2124+
2125+
class B extends A<String> {}
2126+
''');
2127+
var element = findElement2.parameter('p');
2128+
await assertElementReferencesText(element, r'''
2129+
<testLibraryFragment>::@function::f
2130+
19 2:9 |p| REFERENCE qualified
2131+
42 3:9 |p| REFERENCE qualified
2132+
''');
2133+
}
2134+
2135+
@FailingTest(
2136+
// When this test begins passing, the temporary test
2137+
// test_searchReferences_ParameterElement_generic_atInvocation_doesNotThrow_issue60005
2138+
// can be removed.
2139+
issue: 'https://github.com/dart-lang/sdk/issues/60200')
2140+
test_searchReferences_ParameterElement_generic_atInvocation() async {
2141+
await resolveTestCode('''
2142+
void f() {
2143+
B().m(p: null); // 1
2144+
B().m(p: null); // 2
2145+
}
2146+
2147+
class A<T> {
2148+
void m({T? p}) {} // 3
2149+
}
2150+
2151+
class B extends A<String> {}
2152+
''');
2153+
var element =
2154+
findNode.namedExpression('p: null); // 1').correspondingParameter!;
2155+
await assertElementReferencesText(element, r'''
2156+
<testLibraryFragment>::@function::f
2157+
19 2:9 |p| REFERENCE qualified
2158+
42 3:9 |p| REFERENCE qualified
2159+
''');
2160+
}
2161+
2162+
/// A temporary test to ensure the search does not throw, while
2163+
/// [test_searchReferences_ParameterElement_generic_atInvocation] is marked as
2164+
/// failing.
2165+
///
2166+
/// This test can be removed once [test_searchReferences_ParameterElement_generic_atInvocation]
2167+
/// is passing.
2168+
test_searchReferences_ParameterElement_generic_atInvocation_doesNotThrow_issue60005() async {
2169+
await resolveTestCode('''
2170+
void f() {
2171+
B().m(p: null); // 1
2172+
B().m(p: null); // 2
2173+
}
2174+
2175+
class A<T> {
2176+
void m({T? p}) {} // 3
2177+
}
2178+
2179+
class B extends A<String> {}
2180+
''');
2181+
var element =
2182+
findNode.namedExpression('p: null); // 1').correspondingParameter!;
2183+
expect(driver.search.references(element, SearchedFiles()), completes);
2184+
}
2185+
21142186
test_searchReferences_ParameterElement_ofConstructor_super_named() async {
21152187
await resolveTestCode('''
21162188
class A {

0 commit comments

Comments
 (0)