Skip to content

Commit 79a3052

Browse files
stereotype441Commit Queue
authored andcommitted
[analyzer] Expose some inheritance manager methods through the public API.
A few analyzer clients make use of the private `InheritanceManager3` class, notably: - `package:mockito`, - `package:dartdoc`, - `package:analyzer_plugin` - The Google-internal logic to integrate Dart with Kythe. This creates a breakage risk, because private classes of the analyzer might get updated at any time without a major version number change. This CL introduces new methods and getters to the `InterfaceElement2` class, providing the functionality needed by the above clients. It also exposes the formerly private `Name` class, which is referred to by the new methods and getters. Once a new version of the analyzer containing this change has been published, I will update the clients to use the new public API. Change-Id: I859409a5e3009521d1df8ff6187329aedfb73fa2 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/412621 Reviewed-by: Brian Wilkerson <[email protected]> Reviewed-by: Konstantin Shcheglov <[email protected]> Commit-Queue: Paul Berry <[email protected]>
1 parent 230e4f9 commit 79a3052

20 files changed

+274
-15
lines changed

pkg/analysis_server/lib/src/lsp/handlers/custom/handler_super.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import 'package:analyzer/dart/ast/ast.dart';
1111
import 'package:analyzer/dart/element/element2.dart';
1212
import 'package:analyzer/src/dart/analysis/session.dart';
1313
import 'package:analyzer/src/dart/ast/element_locator.dart';
14-
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
1514
import 'package:analyzer/src/utilities/extensions/ast.dart';
1615

1716
class SuperHandler

pkg/analysis_server/lib/src/services/correction/dart/create_method.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import 'package:analysis_server_plugin/edit/dart/correction_producer.dart';
77
import 'package:analyzer/dart/analysis/results.dart';
88
import 'package:analyzer/dart/ast/ast.dart';
99
import 'package:analyzer/dart/element/element2.dart';
10-
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
1110
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
1211
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
1312
import 'package:analyzer_plugin/utilities/range_factory.dart';

pkg/analysis_server/lib/src/services/correction/dart/encapsulate_field.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import 'package:analysis_server/src/utilities/extensions/ast.dart';
77
import 'package:analysis_server_plugin/edit/dart/correction_producer.dart';
88
import 'package:analyzer/dart/ast/ast.dart';
99
import 'package:analyzer/dart/element/element2.dart';
10-
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
1110
import 'package:analyzer_plugin/utilities/assist/assist.dart';
1211
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
1312
import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';

pkg/analysis_server/lib/src/services/correction/dart/import_library.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import 'package:analyzer/dart/element/type_system.dart';
1818
import 'package:analyzer/error/error.dart';
1919
import 'package:analyzer/source/source_range.dart';
2020
import 'package:analyzer/src/dart/ast/extensions.dart';
21-
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
2221
import 'package:analyzer/src/dart/element/type.dart';
2322
import 'package:analyzer/src/dart/resolver/applicable_extensions.dart';
2423
import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_dart.dart';

pkg/analysis_server/lib/src/services/correction/dart/rename_method_parameter.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import 'package:analyzer/dart/ast/token.dart';
88
import 'package:analyzer/dart/ast/visitor.dart';
99
import 'package:analyzer/dart/element/element2.dart';
1010
import 'package:analyzer/src/dart/ast/ast.dart';
11-
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
1211
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
1312
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
1413
import 'package:analyzer_plugin/utilities/range_factory.dart';

pkg/analysis_server/lib/src/services/correction/dart/use_different_division_operator.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import 'package:analyzer/dart/ast/ast.dart';
99
import 'package:analyzer/dart/ast/token.dart';
1010
import 'package:analyzer/dart/element/element2.dart';
1111
import 'package:analyzer/dart/element/type.dart';
12-
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
1312
import 'package:analyzer/src/dart/element/type.dart';
1413
import 'package:analyzer/src/dart/resolver/applicable_extensions.dart';
1514
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';

pkg/analyzer/api.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3917,12 +3917,19 @@ package:analyzer/dart/element/element2.dart:
39173917
constructors2 (getter: List<ConstructorElement2>)
39183918
firstFragment (getter: InterfaceFragment)
39193919
fragments (getter: List<InterfaceFragment>)
3920+
inheritedConcreteMembers (getter: Map<Name, ExecutableElement2>)
3921+
inheritedMembers (getter: Map<Name, ExecutableElement2>)
3922+
interfaceMembers (getter: Map<Name, ExecutableElement2>)
39203923
interfaces (getter: List<InterfaceType>)
39213924
mixins (getter: List<InterfaceType>)
39223925
supertype (getter: InterfaceType?)
39233926
thisType (getter: InterfaceType)
39243927
unnamedConstructor2 (getter: ConstructorElement2?)
3928+
getInheritedConcreteMember (method: ExecutableElement2? Function(Name))
3929+
getInheritedMember (method: ExecutableElement2? Function(Name))
3930+
getInterfaceMember (method: ExecutableElement2? Function(Name))
39253931
getNamedConstructor2 (method: ConstructorElement2? Function(String))
3932+
getOverridden (method: List<ExecutableElement2>? Function(Name))
39263933
instantiate (method: InterfaceType Function({required NullabilitySuffix nullabilitySuffix, required List<DartType> typeArguments}))
39273934
lookUpConcreteMethod (method: MethodElement2? Function(String, LibraryElement2))
39283935
lookUpInheritedMethod2 (method: MethodElement2? Function({required LibraryElement2 library, required String methodName}))
@@ -4128,6 +4135,19 @@ package:analyzer/dart/element/element2.dart:
41284135
element (getter: MultiplyDefinedElement2)
41294136
nextFragment (getter: Null)
41304137
previousFragment (getter: Null)
4138+
Name (class extends Object):
4139+
forElement (static method: Name? Function(Element2))
4140+
forLibrary (constructor: Name Function(LibraryElement2?, String))
4141+
new (constructor: Name Function(Uri?, String))
4142+
forGetter (getter: Name)
4143+
forSetter (getter: Name)
4144+
hashCode (getter: int)
4145+
isPublic (getter: bool)
4146+
libraryUri (getter: Uri?)
4147+
name (getter: String)
4148+
== (method: bool Function(Object))
4149+
isAccessibleFor (method: bool Function(Uri))
4150+
toString (method: String Function())
41314151
NamespaceCombinator (see above)
41324152
PartInclude (class extends Object implements ElementDirective):
41334153
new (constructor: PartInclude Function())

pkg/analyzer/lib/dart/element/element2.dart

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ import 'package:analyzer/dart/element/type_provider.dart';
6464
import 'package:analyzer/dart/element/type_system.dart';
6565
import 'package:analyzer/source/line_info.dart';
6666
import 'package:analyzer/source/source.dart';
67+
import 'package:analyzer/src/dart/element/inheritance_manager3.dart' show Name;
6768
import 'package:analyzer/src/dart/resolver/scope.dart';
6869
import 'package:pub_semver/pub_semver.dart';
6970

@@ -81,6 +82,7 @@ export 'package:analyzer/dart/element/element.dart'
8182
HideElementCombinator,
8283
NamespaceCombinator,
8384
ShowElementCombinator;
85+
export 'package:analyzer/src/dart/element/inheritance_manager3.dart' show Name;
8486

8587
/// An element or fragment that can have either annotations (metadata), a
8688
/// documentation comment, or both associated with it.
@@ -1345,6 +1347,51 @@ abstract class InterfaceElement2 implements InstanceElement2 {
13451347
@override
13461348
List<InterfaceFragment> get fragments;
13471349

1350+
/// Returns a map of all concrete members that this type inherits from
1351+
/// superclasses and mixins, keyed by the member's [Name].
1352+
///
1353+
/// Members declared in this type have no effect on the map. This means that:
1354+
/// - If this type contains a member named `foo`, but none of its superclasses
1355+
/// or mixins contains a member named `foo`, then there will be no entry for
1356+
/// `foo` in the map.
1357+
/// - If this type contains a member named `foo`, and one of its superclasses
1358+
/// or mixins contains a member named `foo`, then there will be an entry for
1359+
/// `foo` in this map, pointing to the declaration inherited from the
1360+
/// superclass or mixin.
1361+
///
1362+
/// This method is potentially expensive, since it needs to consider all
1363+
/// possible inherited names. If you only need to look up a certain specific
1364+
/// name (or names), use [getInheritedConcreteMember] instead.
1365+
Map<Name, ExecutableElement2> get inheritedConcreteMembers;
1366+
1367+
/// Returns a map of all members that this type inherits from supertypes via
1368+
/// `extends`, `with`, `implements`, or `on` clauses, keyed by the member's
1369+
/// [Name].
1370+
///
1371+
/// Members declared in this type have no effect on the map. This means that:
1372+
/// - If this type contains a member named `foo`, but none of its supertypes
1373+
/// contains a member named `foo`, then there will be no entry for `foo` in
1374+
/// the map.
1375+
/// - If this type contains a member named `foo`, and one of its supertypes
1376+
/// contains a member named `foo`, then there will be an entry for `foo` in
1377+
/// this map, pointing to the declaration inherited from the supertype.
1378+
///
1379+
/// This method is potentially expensive, since it needs to consider all
1380+
/// possible inherited names. If you only need to look up a certain specific
1381+
/// name (or names), use [getInheritedMember] instead.
1382+
Map<Name, ExecutableElement2> get inheritedMembers;
1383+
1384+
/// Returns a map of all members in the type's interface, keyed by the
1385+
/// member's [Name].
1386+
///
1387+
/// Note that some names are not declared directly on [thisType], but are
1388+
/// inherited from supertypes.
1389+
///
1390+
/// This method is potentially expensive, since it needs to consider all
1391+
/// possible interface names. If you only need to look up a certain specific
1392+
/// name (or names), use [getInterfaceMember] instead.
1393+
Map<Name, ExecutableElement2> get interfaceMembers;
1394+
13481395
/// The interfaces that are implemented by this class.
13491396
///
13501397
/// <b>Note:</b> Because the element model represents the state of the code,
@@ -1394,9 +1441,63 @@ abstract class InterfaceElement2 implements InstanceElement2 {
13941441
/// constructor will be returned.
13951442
ConstructorElement2? get unnamedConstructor2;
13961443

1444+
/// Returns the most specific member with the given [name] that this type
1445+
/// inherits from a superclass or mixin.
1446+
///
1447+
/// Returns `null` if no member is inherited.
1448+
///
1449+
/// This method is semantically equivalent to calling
1450+
/// [inheritedConcreteMembers] and then using the `[]` operator, but it
1451+
/// potentially has better performance, since it does not need to consider all
1452+
/// possible inherited names.
1453+
ExecutableElement2? getInheritedConcreteMember(Name name);
1454+
1455+
/// Returns the most specific member with the given [name] that this type
1456+
/// inherits from a supertype via an `extends`, `with`, `implements`, or `on`
1457+
/// clause.
1458+
///
1459+
/// Returns `null` if no member is inherited because the member is not
1460+
/// declared at all, or because there is no the most specific signature.
1461+
///
1462+
/// This method is semantically equivalent to calling [inheritedMembers] and
1463+
/// then using the `[]` operator, but it potentially has better performance,
1464+
/// since it does not need to consider all possible inherited names.
1465+
ExecutableElement2? getInheritedMember(Name name);
1466+
1467+
/// Returns the most specific member with the given [name] in this type's
1468+
/// interface.
1469+
///
1470+
/// Returns `null` if there is no member with the given [name] in this type's
1471+
/// interface, either because the member is not declared at all, or because of
1472+
/// a conflict between inherited members.
1473+
///
1474+
/// This method is semantically equivalent to calling [interfaceMembers] and
1475+
/// then using the `[]` operator, but it potentially has better performance,
1476+
/// since it does not need to consider all possible interface names.
1477+
ExecutableElement2? getInterfaceMember(Name name);
1478+
13971479
/// Returns the constructor from [constructors2] that has the given [name].
13981480
ConstructorElement2? getNamedConstructor2(String name);
13991481

1482+
/// Returns all members of mixins, superclasses, and interfaces that a member
1483+
/// with the given [name], defined in this element, would override; or `null`
1484+
/// if no members would be overridden.
1485+
///
1486+
/// Transitive overrides are not included unless there is a direct path to
1487+
/// them. For example, if classes `A`, `B`, and `C` are defined as follows:
1488+
///
1489+
/// class A { void m() {} }
1490+
/// class B extends A { void m() {} }
1491+
/// class C extends B { void m() {} }
1492+
///
1493+
/// Then a [getOverridden] query for name `m` on class `C` would return just a
1494+
/// single result: the element for `B.m`.
1495+
///
1496+
/// However, if the example were changed so that `class C` both `extends B`
1497+
/// *and* `implements A`, then a list containing both `A.m` and `B.m` would be
1498+
/// returned.
1499+
List<ExecutableElement2>? getOverridden(Name name);
1500+
14001501
/// Create the [InterfaceType] for this element with the given
14011502
/// [typeArguments] and [nullabilitySuffix].
14021503
InterfaceType instantiate({

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

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6778,6 +6778,23 @@ abstract class InterfaceElementImpl2 extends InstanceElementImpl2
67786778
return library2.session.inheritanceManager;
67796779
}
67806780

6781+
@override
6782+
Map<Name, ExecutableElement2> get inheritedConcreteMembers =>
6783+
(session as AnalysisSessionImpl)
6784+
.inheritanceManager
6785+
.getInheritedConcreteMap(this);
6786+
6787+
@override
6788+
Map<Name, ExecutableElement2> get inheritedMembers =>
6789+
(session as AnalysisSessionImpl).inheritanceManager.getInheritedMap(this);
6790+
6791+
@override
6792+
Map<Name, ExecutableElement2> get interfaceMembers =>
6793+
(session as AnalysisSessionImpl)
6794+
.inheritanceManager
6795+
.getInterface2(this)
6796+
.map2;
6797+
67816798
@override
67826799
List<InterfaceTypeImpl> get interfaces => _interfaces;
67836800

@@ -6847,6 +6864,22 @@ abstract class InterfaceElementImpl2 extends InstanceElementImpl2
68476864
ConstructorElementMixin2? get unnamedConstructor2 =>
68486865
unnamedConstructor?.asElement2;
68496866

6867+
@override
6868+
ExecutableElement2? getInheritedConcreteMember(Name name) =>
6869+
inheritedConcreteMembers[name];
6870+
6871+
@override
6872+
ExecutableElement2? getInheritedMember(Name name) =>
6873+
(session as AnalysisSessionImpl)
6874+
.inheritanceManager
6875+
.getInherited4(this, name);
6876+
6877+
@override
6878+
ExecutableElement2? getInterfaceMember(Name name) =>
6879+
(session as AnalysisSessionImpl)
6880+
.inheritanceManager
6881+
.getMember4(this, name);
6882+
68506883
@override
68516884
ConstructorElementMixin? getNamedConstructor(String name) {
68526885
name = name.ifEqualThen('new', '');
@@ -6858,6 +6891,12 @@ abstract class InterfaceElementImpl2 extends InstanceElementImpl2
68586891
return constructors2.firstWhereOrNull((e) => e.name3 == name);
68596892
}
68606893

6894+
@override
6895+
List<ExecutableElement2>? getOverridden(Name name) =>
6896+
(session as AnalysisSessionImpl)
6897+
.inheritanceManager
6898+
.getOverridden4(this, name);
6899+
68616900
@override
68626901
InterfaceTypeImpl instantiate({
68636902
required List<DartType> typeArguments,

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
// ignore_for_file: analyzer_use_new_elements
66

7+
import 'package:_fe_analyzer_shared/src/base/analyzer_public_api.dart';
78
import 'package:analyzer/dart/element/element.dart';
89
import 'package:analyzer/dart/element/element2.dart';
910
import 'package:analyzer/dart/element/type.dart';
@@ -1316,6 +1317,7 @@ class Interface {
13161317
}
13171318

13181319
/// A public name, or a private name qualified by a library URI.
1320+
@AnalyzerPublicApi(message: 'Exposed by InterfaceElement2 methods')
13191321
class Name {
13201322
/// If the name is private, the URI of the defining library.
13211323
/// Otherwise, it is `null`.

0 commit comments

Comments
 (0)