diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart index d70ac761fc92..d4e5bb810ba9 100644 --- a/pkg/analyzer/lib/src/dart/element/element.dart +++ b/pkg/analyzer/lib/src/dart/element/element.dart @@ -5562,18 +5562,23 @@ abstract class InstanceElementImpl2 extends ElementImpl2 LibraryElement2 get enclosingElement2 => firstFragment.library; @override - List get fields2 => - fields.map((e) => e.asElement2 as FieldElement2?).nonNulls.toList(); + List get fields2 { + _readMembers(); + return fields.map((e) => e.asElement2 as FieldElement2?).nonNulls.toList(); + } @override InstanceElementImpl get firstFragment; @override - List get getters2 => accessors - .where((e) => e.isGetter) - .map((e) => e.asElement2 as GetterElement?) - .nonNulls - .toList(); + List get getters2 { + _readMembers(); + return accessors + .where((e) => e.isGetter) + .map((e) => e.asElement2 as GetterElement?) + .nonNulls + .toList(); + } @override String get identifier => name3 ?? firstFragment.identifier; @@ -5613,11 +5618,14 @@ abstract class InstanceElementImpl2 extends ElementImpl2 AnalysisSession? get session => firstFragment.session; @override - List get setters2 => accessors - .where((e) => e.isSetter) - .map((e) => e.asElement2 as SetterElement?) - .nonNulls - .toList(); + List get setters2 { + _readMembers(); + return accessors + .where((e) => e.isSetter) + .map((e) => e.asElement2 as SetterElement?) + .nonNulls + .toList(); + } @override List get typeParameters2 => @@ -5892,6 +5900,11 @@ abstract class InstanceElementImpl2 extends ElementImpl2 Iterable _implementationsOfSetter2(String name) { return _implementationsOfSetter(name).map((e) => e.asElement2); } + + void _readMembers() { + // TODO(scheglov): use better implementation + firstFragment.element; + } } abstract class InterfaceElementImpl extends InstanceElementImpl diff --git a/pkg/analyzer/lib/src/dart/element/name_union.dart b/pkg/analyzer/lib/src/dart/element/name_union.dart index cc1b53a67178..7c0c05afad88 100644 --- a/pkg/analyzer/lib/src/dart/element/name_union.dart +++ b/pkg/analyzer/lib/src/dart/element/name_union.dart @@ -2,12 +2,10 @@ // 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. -// ignore_for_file: analyzer_use_new_elements - import 'dart:typed_data'; -import 'package:analyzer/dart/element/element.dart'; -import 'package:analyzer/dart/element/visitor.dart'; +import 'package:analyzer/dart/element/element2.dart'; +import 'package:analyzer/dart/element/visitor2.dart'; /// Union of a set of names. class ElementNameUnion { @@ -92,33 +90,45 @@ class ElementNameUnion { return true; } - static ElementNameUnion forLibrary(LibraryElement libraryElement) { + static ElementNameUnion forLibrary(LibraryElement2 libraryElement) { var result = ElementNameUnion.empty(); - libraryElement.accept( - _ElementVisitor(result), + libraryElement.accept2( + _ElementVisitor2(result), ); return result; } + + static bool _hasInterestingElements(Element2 element) { + if (element is ExecutableElement2) { + return false; + } + return true; + } + + static bool _isInterestingElement(Element2 element) { + return element.enclosingElement2 is LibraryElement2 || + element is FieldElement2 || + element is MethodElement2 || + element is PropertyAccessorElement2; + } } -class _ElementVisitor extends GeneralizingElementVisitor { +class _ElementVisitor2 extends GeneralizingElementVisitor2 { final ElementNameUnion union; - _ElementVisitor(this.union); + _ElementVisitor2(this.union); @override - void visitElement(Element element) { - var enclosing = element.enclosingElement3; - if (enclosing is CompilationUnitElement || - element is FieldElement || - element is MethodElement || - element is PropertyAccessorElement) { - var name = element.name; + void visitElement(Element2 element) { + if (ElementNameUnion._isInterestingElement(element)) { + var name = element.name3; if (name != null) { union.add(name); } } - super.visitElement(element); + if (ElementNameUnion._hasInterestingElements(element)) { + super.visitElement(element); + } } } diff --git a/pkg/analyzer/test/src/dart/element/name_union_test.dart b/pkg/analyzer/test/src/dart/element/name_union_test.dart index 3cee531d577e..c6b9c3ce3113 100644 --- a/pkg/analyzer/test/src/dart/element/name_union_test.dart +++ b/pkg/analyzer/test/src/dart/element/name_union_test.dart @@ -2,16 +2,10 @@ // 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. -// ignore_for_file: analyzer_use_new_elements - -import 'package:analyzer/dart/analysis/results.dart'; -import 'package:analyzer/dart/element/element.dart'; -import 'package:analyzer/dart/element/visitor.dart'; -import 'package:analyzer/src/dart/element/name_union.dart'; import 'package:test/test.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; -import '../resolution/context_collection_resolution.dart'; +import '../../summary/elements_base.dart'; main() { defineReflectiveSuite(() { @@ -20,54 +14,99 @@ main() { } @reflectiveTest -class ElementNameUnionTest extends PubPackageResolutionTest { - test_it() async { - await _checkLibrary('dart:async'); - await _checkLibrary('dart:core'); - await _checkLibrary('dart:math'); - } +class ElementNameUnionTest extends ElementsBaseTest { + @override + bool get keepLinkingLibraries => false; + + test_class() async { + var library = await buildLibrary(r''' +class MyClass { + final myField = 0; + int get myGetter => 0; + set mySetter(int _) {} + void myMethod() {} +} +'''); + + var nameUnion = library.nameUnion; + expect(nameUnion.contains('MyClass'), isTrue); + expect(nameUnion.contains('NotMyClass'), isFalse); - Future _checkLibrary(String uriStr) async { - var analysisContext = contextFor(testFile); - var analysisSession = analysisContext.currentSession; + expect(nameUnion.contains('myField'), isTrue); + expect(nameUnion.contains('NotMyField'), isFalse); - var result = await analysisSession.getLibraryByUri(uriStr); - result as LibraryElementResult; - var element = result.element; + expect(nameUnion.contains('myGetter'), isTrue); + expect(nameUnion.contains('NotMyGetter'), isFalse); - var union = ElementNameUnion.forLibrary(element); - element.accept( - _ElementVisitor(union), - ); + expect(nameUnion.contains('mySetter'), isTrue); + expect(nameUnion.contains('NotMySetter'), isFalse); + + expect(nameUnion.contains('myMethod'), isTrue); + expect(nameUnion.contains('NotMyMethod'), isFalse); } + + test_enum() async { + var library = await buildLibrary(r''' +enum MyEnum { + myValue } +'''); + + var nameUnion = library.nameUnion; + expect(nameUnion.contains('MyEnum'), isTrue); + expect(nameUnion.contains('NotMyEnum'), isFalse); -/// Checks that the name of every interesting element is in [union]. -class _ElementVisitor extends GeneralizingElementVisitor { - final ElementNameUnion union; + expect(nameUnion.contains('MyValue'), isTrue); + expect(nameUnion.contains('NotMyValue'), isFalse); + } - _ElementVisitor(this.union); + test_extension() async { + var library = await buildLibrary(r''' +extension MyExtension on int {} +'''); - @override - void visitElement(Element element) { - var enclosing = element.enclosingElement3; - if (enclosing is CompilationUnitElement || - element is FieldElement || - element is MethodElement || - element is PropertyAccessorElement) { - var name = element.name; - if (name != null) { - expect(union.contains(name), isTrue, reason: 'Expected to find $name'); - // This might fail, but the probability is low. If this does fail, try - // adding another `z` to the prefix. - expect( - union.contains('zz$name'), - isFalse, - reason: 'Expected to not find $name', - ); - } - } - - super.visitElement(element); + var nameUnion = library.nameUnion; + expect(nameUnion.contains('MyExtension'), isTrue); + expect(nameUnion.contains('NotMyExtension'), isFalse); + } + + test_extensionType() async { + var library = await buildLibrary(r''' +extension type MyExtensionType(int it) {} +'''); + + var nameUnion = library.nameUnion; + expect(nameUnion.contains('MyExtensionType'), isTrue); + expect(nameUnion.contains('NotMyExtensionType'), isFalse); + } + + test_mixin() async { + var library = await buildLibrary(r''' +mixin MyMixin {} +'''); + + var nameUnion = library.nameUnion; + expect(nameUnion.contains('MyMixin'), isTrue); + expect(nameUnion.contains('NotMyMixin'), isFalse); + } + + test_topLevelVariable() async { + var library = await buildLibrary(r''' +final myVariable = 0; +'''); + + var nameUnion = library.nameUnion; + expect(nameUnion.contains('myVariable'), isTrue); + expect(nameUnion.contains('NotMyVariable'), isFalse); + } + + test_typedef() async { + var library = await buildLibrary(r''' +typedef MyTypedef = int; +'''); + + var nameUnion = library.nameUnion; + expect(nameUnion.contains('MyTypedef'), isTrue); + expect(nameUnion.contains('NotMyTypedef'), isFalse); } }