Files
sdk/pkg/kernel/lib/extension_table.dart
T
Johnni Winther 94c9dff1c5 [cfe] Add isInternalImplementation to Extension(Type)MemberDescriptor
This adds a flag to the member descriptors that allow us to skip these when building the name space for extensions and extension types from dill.

The late lowering of fields in dart2js is fixed to support lookup from dill.

Change-Id: Iacbd6451ac234767036dfe8f818c3ecbb693ced8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/427720
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Mayank Patke <fishythefish@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
2025-05-12 00:26:25 -07:00

140 lines
4.6 KiB
Dart

// Copyright (c) 2025, 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:kernel/ast.dart';
/// Lookup table that provides access to the descriptor for extension and
/// extension type members.
class ExtensionTable {
final Map<Library, _LibraryInfo> _infoMap = {};
/// Returns the [ExtensionMemberInfo] for [member].
///
/// [member] must be marked as an extension member.
ExtensionMemberInfo getExtensionMemberInfo(Member member) {
if (!member.isExtensionMember) {
throw new ArgumentError("Member $member must be an extension member.");
}
_LibraryInfo info = _getLibraryInfo(member.enclosingLibrary);
return info.getExtensionMemberInfo(member);
}
/// Returns the [ExtensionTypeMemberInfo] for [member].
///
/// [member] must be marked as an extension type member.
ExtensionTypeMemberInfo getExtensionTypeMemberInfo(Member member) {
if (!member.isExtensionTypeMember) {
throw new ArgumentError("Member $member must be an extension member.");
}
_LibraryInfo info = _getLibraryInfo(member.enclosingLibrary);
return info.getExtensionTypeMemberInfo(member);
}
_LibraryInfo _getLibraryInfo(Library library) {
return _infoMap[library] ??= new _LibraryInfo(library);
}
}
/// Information about an extension member lowered as a top level member.
class ExtensionMemberInfo {
/// The extension to which the member belongs.
final Extension extension;
/// The lowered top level member.
final Member member;
/// The [ExtensionMemberDescriptor] for the lowered [member].
final ExtensionMemberDescriptor descriptor;
ExtensionMemberInfo(this.extension, this.member, this.descriptor);
}
/// Information about an extension type member lowered as a top level member.
class ExtensionTypeMemberInfo {
/// The extension type declaration to which the member belongs.
final ExtensionTypeDeclaration extensionTypeDeclaration;
/// The lowered top level member.
final Member member;
/// The [ExtensionMemberDescriptor] for the lowered [member].
final ExtensionTypeMemberDescriptor descriptor;
ExtensionTypeMemberInfo(
this.extensionTypeDeclaration, this.member, this.descriptor);
}
class _LibraryInfo {
final Library _library;
late final _ExtensionTable _extensionTable = new _ExtensionTable(_library);
late final _ExtensionTypeTable _extensionTypeTable =
new _ExtensionTypeTable(_library);
_LibraryInfo(this._library);
ExtensionMemberInfo getExtensionMemberInfo(Member member) {
return _extensionTable[member];
}
ExtensionTypeMemberInfo getExtensionTypeMemberInfo(Member member) {
return _extensionTypeTable[member];
}
}
class _ExtensionTable {
final Map<Member, ExtensionMemberInfo> _map = {};
_ExtensionTable(Library library) {
for (Extension extension in library.extensions) {
for (ExtensionMemberDescriptor descriptor
in extension.memberDescriptors) {
Member? member = descriptor.memberReference?.asMember;
if (member != null) {
_map[member] = new ExtensionMemberInfo(extension, member, descriptor);
}
Member? tearOff = descriptor.tearOffReference?.asMember;
if (tearOff != null) {
_map[tearOff] =
new ExtensionMemberInfo(extension, tearOff, descriptor);
}
}
}
}
ExtensionMemberInfo operator [](Member member) {
ExtensionMemberInfo? info = _map[member];
assert(info != null, "No info found for $member in ${_map.keys}");
return info!;
}
}
class _ExtensionTypeTable {
final Map<Member, ExtensionTypeMemberInfo> _map = {};
_ExtensionTypeTable(Library library) {
for (ExtensionTypeDeclaration extensionTypeDeclaration
in library.extensionTypeDeclarations) {
for (ExtensionTypeMemberDescriptor descriptor
in extensionTypeDeclaration.memberDescriptors) {
Member? member = descriptor.memberReference?.asMember;
if (member != null) {
_map[member] = new ExtensionTypeMemberInfo(
extensionTypeDeclaration, member, descriptor);
}
Member? tearOff = descriptor.tearOffReference?.asMember;
if (tearOff != null) {
_map[tearOff] = new ExtensionTypeMemberInfo(
extensionTypeDeclaration, tearOff, descriptor);
}
}
}
}
ExtensionTypeMemberInfo operator [](Member member) {
ExtensionTypeMemberInfo? info = _map[member];
assert(info != null, "No info found for $member in ${_map.keys}");
return info!;
}
}