[analyzer] Dot shorthands: Update indexing.
Adds implementation for dot shorthand invocations, property accesses and constructors in indexing and added search tests. Unit tests passing for index and search. Bug: https://github.com/dart-lang/sdk/issues/59835 Change-Id: I2ee3ddbabb7f8ee0ead6538906a9a55f54bf20a2 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/430563 Commit-Queue: Kallen Tu <kallentu@google.com> Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
This commit is contained in:
@@ -860,6 +860,41 @@ class _IndexContributor extends GeneralizingAstVisitor {
|
||||
node.type.accept(this);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitDotShorthandConstructorInvocation(
|
||||
DotShorthandConstructorInvocation node,
|
||||
) {
|
||||
var element = _getActualConstructorElement(node.element?.baseElement);
|
||||
recordRelation(
|
||||
element,
|
||||
IndexRelationKind.IS_INVOKED_BY,
|
||||
node.constructorName,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitDotShorthandInvocation(DotShorthandInvocation node) {
|
||||
var name = node.memberName;
|
||||
var element = name.element;
|
||||
recordRelation(element, IndexRelationKind.IS_INVOKED_BY, name, true);
|
||||
node.typeArguments?.accept(this);
|
||||
node.argumentList.accept(this);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitDotShorthandPropertyAccess(DotShorthandPropertyAccess node) {
|
||||
IndexRelationKind kind;
|
||||
var element = node.propertyName.element;
|
||||
if (element is ConstructorElementMixin2) {
|
||||
element = _getActualConstructorElement(element);
|
||||
kind = IndexRelationKind.IS_REFERENCED_BY_CONSTRUCTOR_TEAR_OFF;
|
||||
} else {
|
||||
kind = IndexRelationKind.IS_REFERENCED_BY;
|
||||
}
|
||||
recordRelation(element, kind, node.propertyName, true);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
|
||||
var constructorElement = node.constructorElement2;
|
||||
|
||||
@@ -1280,6 +1280,21 @@ void f() {
|
||||
// No additional validation, but it should not fail with stack overflow.
|
||||
}
|
||||
|
||||
test_isReferencedBy_ConstructorElement_dotShorthand() async {
|
||||
await _indexTestUnit('''
|
||||
class A {}
|
||||
void f() {
|
||||
A a = .new(); // 1
|
||||
A tearOff = .new; // 2, is also a compile-time error
|
||||
}
|
||||
''');
|
||||
var element = findElement2.unnamedConstructor('A');
|
||||
assertElementIndexText(element, r'''
|
||||
31 3:10 |new| IS_INVOKED_BY qualified
|
||||
58 4:16 |new| IS_REFERENCED_BY_CONSTRUCTOR_TEAR_OFF qualified
|
||||
''');
|
||||
}
|
||||
|
||||
test_isReferencedBy_ConstructorElement_enum_named() async {
|
||||
await _indexTestUnit('''
|
||||
/// [new E.foo] 1
|
||||
@@ -1706,6 +1721,21 @@ class A {
|
||||
''');
|
||||
}
|
||||
|
||||
test_isReferencedBy_FieldElement_dotShorthand() async {
|
||||
await _indexTestUnit('''
|
||||
class A {
|
||||
static A field = A();
|
||||
}
|
||||
void f() {
|
||||
A a = .field; // 1
|
||||
}
|
||||
''');
|
||||
var element = findElement2.field('field').getter2!;
|
||||
assertElementIndexText(element, r'''
|
||||
56 5:10 |field| IS_REFERENCED_BY qualified
|
||||
''');
|
||||
}
|
||||
|
||||
test_isReferencedBy_FieldElement_enum() async {
|
||||
await _indexTestUnit('''
|
||||
enum E {
|
||||
@@ -1953,6 +1983,21 @@ class A {
|
||||
''');
|
||||
}
|
||||
|
||||
test_isReferencedBy_MethodElement_dotShorthand() async {
|
||||
await _indexTestUnit('''
|
||||
class A {
|
||||
static A method() => A();
|
||||
}
|
||||
void f() {
|
||||
A a = .method(); // 1
|
||||
}
|
||||
''');
|
||||
var element = findElement2.method('method');
|
||||
assertElementIndexText(element, r'''
|
||||
60 5:10 |method| IS_INVOKED_BY qualified
|
||||
''');
|
||||
}
|
||||
|
||||
test_isReferencedBy_MethodElement_enum() async {
|
||||
await _indexTestUnit('''
|
||||
enum E {
|
||||
|
||||
@@ -1304,6 +1304,22 @@ void f() {
|
||||
''');
|
||||
}
|
||||
|
||||
test_searchReferences_ConstructorElement_dotShorthand() async {
|
||||
await resolveTestCode('''
|
||||
class A {}
|
||||
void main() {
|
||||
A a = .new(); // 1
|
||||
A tearOff = .new; // 2, is also a compile-time error
|
||||
}
|
||||
''');
|
||||
var element = findElement2.unnamedConstructor('A');
|
||||
await assertElementReferencesText(element, r'''
|
||||
<testLibraryFragment>::@function::main
|
||||
34 3:10 |new| INVOCATION qualified
|
||||
61 4:16 |new| REFERENCE_BY_CONSTRUCTOR_TEAR_OFF qualified
|
||||
''');
|
||||
}
|
||||
|
||||
test_searchReferences_ConstructorElement_enum_named() async {
|
||||
await resolveTestCode('''
|
||||
/// [new E.named] 1
|
||||
@@ -1496,6 +1512,22 @@ class A {
|
||||
''');
|
||||
}
|
||||
|
||||
test_searchReferences_FieldElement_dotShorthand() async {
|
||||
await resolveTestCode('''
|
||||
class A {
|
||||
static A field = A();
|
||||
}
|
||||
void main() {
|
||||
A a = .field; // 1
|
||||
}
|
||||
''');
|
||||
var element = findElement2.field('field');
|
||||
await assertElementReferencesText(element, r'''
|
||||
<testLibraryFragment>::@function::main
|
||||
59 5:10 |field| READ qualified
|
||||
''');
|
||||
}
|
||||
|
||||
test_searchReferences_FieldElement_enum() async {
|
||||
await resolveTestCode('''
|
||||
enum E {
|
||||
@@ -1938,6 +1970,24 @@ class A {
|
||||
''');
|
||||
}
|
||||
|
||||
test_searchReferences_MethodElement_dotShorthand() async {
|
||||
await resolveTestCode('''
|
||||
class A {
|
||||
static A method() => A();
|
||||
}
|
||||
void main() {
|
||||
A a = .method(); // 1
|
||||
A aa = .method; // 2, is also a compile-time error
|
||||
}
|
||||
''');
|
||||
var element = findElement2.method('method');
|
||||
await assertElementReferencesText(element, r'''
|
||||
<testLibraryFragment>::@function::main
|
||||
63 5:10 |method| INVOCATION qualified
|
||||
88 6:11 |method| REFERENCE qualified
|
||||
''');
|
||||
}
|
||||
|
||||
test_searchReferences_MethodElement_enum() async {
|
||||
await resolveTestCode('''
|
||||
enum E {
|
||||
|
||||
Reference in New Issue
Block a user