[dart2js] Add member applies to sets and builder.

Will be used during call hierarchy analysis in combination with explicit call graph construction.

Currently typemasks do not support the `difference` operation and so we cannot fully narrow the type cones based on the call hierarchy. An implementation is included here of the applies-to set with subtraction of overrides.

Change-Id: I3f6c113787a4d26e9751added482791365c12832
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/259560
Reviewed-by: Mayank Patke <fishythefish@google.com>
Commit-Queue: Nate Biggs <natebiggs@google.com>
diff --git a/pkg/compiler/lib/src/call_graph/applies_to.dart b/pkg/compiler/lib/src/call_graph/applies_to.dart
new file mode 100644
index 0000000..74b49ed
--- /dev/null
+++ b/pkg/compiler/lib/src/call_graph/applies_to.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// 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.
+
+import 'package:compiler/src/common/names.dart';
+import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/inferrer/abstract_value_domain.dart';
+import 'package:compiler/src/world_interfaces.dart';
+import 'package:compiler/src/universe/selector.dart';
+
+class MemberAppliesTo {
+  final MemberEntity member;
+  AbstractValue mask;
+
+  MemberAppliesTo(this.member, this.mask);
+
+  @override
+  String toString() => 'MemberAppliesTo($member:$mask)';
+}
+
+class MemberAppliesToBuilder {
+  final JClosedWorld _closedWorld;
+  final Map<Selector, Iterable<MemberAppliesTo>> _memberSetsBySelector = {};
+  final Map<Selector, List<MemberEntity>> _membersBySelector = {};
+
+  MemberAppliesToBuilder(this._closedWorld) {
+    for (final member in _closedWorld.liveInstanceMembers) {
+      if (member.isFunction || member.isGetter || member.isSetter) {
+        (_membersBySelector[Selector.fromElement(member)] ??= []).add(member);
+      }
+    }
+  }
+
+  Iterable<MemberAppliesTo> _buildSets(Selector selector) {
+    final List<MemberAppliesTo> memberSets = [];
+    final members = _membersBySelector.remove(selector);
+    if (members == null) {
+      return selector == Selectors.noSuchMethod_
+          ? const []
+          : forSelector(Selectors.noSuchMethod_);
+    }
+    for (final member in members) {
+      // TODO(fishythefish): Use type cone mask here.
+      final mask = _closedWorld.abstractValueDomain
+          .createNonNullSubclass(member.enclosingClass!);
+      final memberSet = MemberAppliesTo(member, mask);
+      memberSets.add(memberSet);
+    }
+    return memberSets;
+  }
+
+  Iterable<MemberAppliesTo> forSelector(Selector selector) =>
+      _memberSetsBySelector[selector] ??= _buildSets(selector);
+}
diff --git a/pkg/compiler/lib/src/js_model/js_world.dart b/pkg/compiler/lib/src/js_model/js_world.dart
index 7f0bb7b..0e949b5 100644
--- a/pkg/compiler/lib/src/js_model/js_world.dart
+++ b/pkg/compiler/lib/src/js_model/js_world.dart
@@ -65,6 +65,7 @@
   // TODO(johnniwinther): Can this be derived from [ClassSet]s?
   final Set<ClassEntity> implementedClasses;
 
+  @override
   final Set<MemberEntity> liveInstanceMembers;
 
   /// Members that are written either directly or through a setter selector.
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 9c400e0..7935546 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -69,6 +69,9 @@
 
   Iterable<MemberEntity> get processedMembers;
 
+  @override
+  Iterable<MemberEntity> get liveInstanceMembers;
+
   /// Returns the set of interfaces passed as type arguments to the internal
   /// `extractTypeArguments` function.
   Set<ClassEntity> get extractTypeArgumentsInterfacesNewRti;
diff --git a/pkg/compiler/lib/src/world_interfaces.dart b/pkg/compiler/lib/src/world_interfaces.dart
index fadcbce..1bde083 100644
--- a/pkg/compiler/lib/src/world_interfaces.dart
+++ b/pkg/compiler/lib/src/world_interfaces.dart
@@ -29,6 +29,8 @@
 
   AnnotationsData get annotationsData;
 
+  Iterable<MemberEntity> get liveInstanceMembers;
+
   bool isUsedAsMixin(ClassEntity cls);
 
   bool includesClosureCall(Selector selector, AbstractValue? receiver);