mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 16:41:07 +00:00
[kernel] Add ExtensionTypeDeclaration.procedures
This adds a list of `Procedure`s to `ExtensionTypeDeclaration`. This is meant to model representation fields and combined member signatures computed from inherited non-extension type members. These are not meant to be handled by the backends. The combined member signature can be the interface target of an `InstanceInvocation` expression but will always have a `.memberSignatureOrigin` value from one of the original class members. TEST=existing Change-Id: I87768ed75a3c7126b0a30f8ccf06e46678c56db6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/330301 Reviewed-by: Alexander Markov <alexmarkov@google.com> Reviewed-by: Srujan Gaddam <srujzs@google.com> Reviewed-by: Jens Johansen <jensj@google.com> Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
parent
06ab207091
commit
f87142fdc2
|
@ -254,7 +254,7 @@ extension ExtensionMemberDescriptorExtension on ExtensionMemberDescriptor {
|
|||
bool get isSetter => kind == ExtensionMemberKind.Setter;
|
||||
bool get isMethod => kind == ExtensionMemberKind.Method;
|
||||
|
||||
bool get isExternal => (member.asProcedure).isExternal;
|
||||
bool get isExternal => (memberReference.asProcedure).isExternal;
|
||||
}
|
||||
|
||||
extension ProcedureExtension on Procedure {
|
||||
|
|
|
@ -714,8 +714,8 @@ class ExtensionIndex {
|
|||
void _indexExtensions(Library library) {
|
||||
if (_processedExtensionLibraries.contains(library)) return;
|
||||
for (var extension in library.extensions) {
|
||||
for (var descriptor in extension.members) {
|
||||
var reference = descriptor.member;
|
||||
for (var descriptor in extension.memberDescriptors) {
|
||||
var reference = descriptor.memberReference;
|
||||
var onType = extension.onType;
|
||||
bool isInteropOnType = false;
|
||||
Annotatable? cls;
|
||||
|
@ -738,7 +738,7 @@ class ExtensionIndex {
|
|||
_extensionMemberIndex[reference] = descriptor;
|
||||
_extensionAnnotatableIndex[reference] = cls!;
|
||||
_extensionIndex[reference] = extension;
|
||||
final tearOffReference = descriptor.tearOff;
|
||||
final tearOffReference = descriptor.tearOffReference;
|
||||
if (tearOffReference != null) {
|
||||
_extensionMemberIndex[tearOffReference] = descriptor;
|
||||
_extensionIndex[tearOffReference] = extension;
|
||||
|
@ -832,11 +832,11 @@ class ExtensionIndex {
|
|||
if (_processedExtensionTypeLibraries.contains(library)) return;
|
||||
for (var extensionType in library.extensionTypeDeclarations) {
|
||||
if (isInteropExtensionType(extensionType)) {
|
||||
for (var descriptor in extensionType.members) {
|
||||
final reference = descriptor.member;
|
||||
for (var descriptor in extensionType.memberDescriptors) {
|
||||
final reference = descriptor.memberReference;
|
||||
_extensionTypeMemberIndex[reference] = descriptor;
|
||||
_extensionTypeIndex[reference] = extensionType;
|
||||
final tearOffReference = descriptor.tearOff;
|
||||
final tearOffReference = descriptor.tearOffReference;
|
||||
if (tearOffReference != null) {
|
||||
_extensionTypeMemberIndex[tearOffReference] = descriptor;
|
||||
_extensionTypeIndex[tearOffReference] = extensionType;
|
||||
|
|
|
@ -199,7 +199,7 @@ class StaticInteropMockValidator {
|
|||
// setters return their return and parameter types, respectively.
|
||||
DartType _getTypeOfDescriptor(ExtensionMemberDescriptor interopDescriptor) {
|
||||
// CFE creates static procedures for each extension member.
|
||||
var interopMember = interopDescriptor.member.asProcedure;
|
||||
var interopMember = interopDescriptor.memberReference.asProcedure;
|
||||
|
||||
if (interopDescriptor.isGetter) {
|
||||
return interopMember.function.returnType;
|
||||
|
@ -325,7 +325,7 @@ class StaticInteropMockValidator {
|
|||
var extensions = _staticInteropClassesWithExtensions[cls.reference];
|
||||
if (extensions != null) {
|
||||
for (var extension in extensions) {
|
||||
for (var descriptor in extension.members) {
|
||||
for (var descriptor in extension.memberDescriptors) {
|
||||
if (!descriptor.isExternal || descriptor.isStatic) continue;
|
||||
// No need to handle external fields - they are transformed to
|
||||
// external getters/setters by the CFE.
|
||||
|
@ -336,7 +336,8 @@ class StaticInteropMockValidator {
|
|||
}
|
||||
_descriptorToExtensionName[descriptor] =
|
||||
extension.isUnnamedExtension ? '<unnamed>' : extension.name;
|
||||
var name = js_interop.getJSName(descriptor.member.asMember);
|
||||
var name =
|
||||
js_interop.getJSName(descriptor.memberReference.asMember);
|
||||
if (name.isEmpty) name = descriptor.name.text;
|
||||
exportNameToDescriptors!
|
||||
.putIfAbsent(name, () => {})
|
||||
|
|
|
@ -77,9 +77,10 @@ String? computeKernelElementNameForSourceMaps(
|
|||
String _findExtensionMemberName(ir.Member member) {
|
||||
assert(member.isExtensionMember);
|
||||
for (ir.Extension extension in member.enclosingLibrary.extensions) {
|
||||
for (ir.ExtensionMemberDescriptor descriptor in extension.members) {
|
||||
if (descriptor.member == member.reference ||
|
||||
descriptor.tearOff == member.reference) {
|
||||
for (ir.ExtensionMemberDescriptor descriptor
|
||||
in extension.memberDescriptors) {
|
||||
if (descriptor.memberReference == member.reference ||
|
||||
descriptor.tearOffReference == member.reference) {
|
||||
String extensionName;
|
||||
// Anonymous extensions contain a # on their synthetic name.
|
||||
if (extension.name.contains('#')) {
|
||||
|
|
|
@ -32,20 +32,20 @@ class DillExtensionBuilder extends ExtensionBuilderImpl {
|
|||
parent: parent.scope,
|
||||
debugName: "extension ${extension.name}",
|
||||
isModifiable: false)) {
|
||||
for (ExtensionMemberDescriptor descriptor in extension.members) {
|
||||
for (ExtensionMemberDescriptor descriptor in extension.memberDescriptors) {
|
||||
Name name = descriptor.name;
|
||||
switch (descriptor.kind) {
|
||||
case ExtensionMemberKind.Method:
|
||||
if (descriptor.isStatic) {
|
||||
Procedure procedure = descriptor.member.asProcedure;
|
||||
Procedure procedure = descriptor.memberReference.asProcedure;
|
||||
scope.addLocalMember(
|
||||
name.text,
|
||||
new DillExtensionStaticMethodBuilder(
|
||||
procedure, descriptor, this),
|
||||
setter: false);
|
||||
} else {
|
||||
Procedure procedure = descriptor.member.asProcedure;
|
||||
Procedure? tearOff = descriptor.tearOff?.asProcedure;
|
||||
Procedure procedure = descriptor.memberReference.asProcedure;
|
||||
Procedure? tearOff = descriptor.tearOffReference?.asProcedure;
|
||||
assert(tearOff != null, "No tear found for ${descriptor}");
|
||||
scope.addLocalMember(
|
||||
name.text,
|
||||
|
@ -55,25 +55,25 @@ class DillExtensionBuilder extends ExtensionBuilderImpl {
|
|||
}
|
||||
break;
|
||||
case ExtensionMemberKind.Getter:
|
||||
Procedure procedure = descriptor.member.asProcedure;
|
||||
Procedure procedure = descriptor.memberReference.asProcedure;
|
||||
scope.addLocalMember(name.text,
|
||||
new DillExtensionGetterBuilder(procedure, descriptor, this),
|
||||
setter: false);
|
||||
break;
|
||||
case ExtensionMemberKind.Field:
|
||||
Field field = descriptor.member.asField;
|
||||
Field field = descriptor.memberReference.asField;
|
||||
scope.addLocalMember(
|
||||
name.text, new DillExtensionFieldBuilder(field, descriptor, this),
|
||||
setter: false);
|
||||
break;
|
||||
case ExtensionMemberKind.Setter:
|
||||
Procedure procedure = descriptor.member.asProcedure;
|
||||
Procedure procedure = descriptor.memberReference.asProcedure;
|
||||
scope.addLocalMember(name.text,
|
||||
new DillExtensionSetterBuilder(procedure, descriptor, this),
|
||||
setter: true);
|
||||
break;
|
||||
case ExtensionMemberKind.Operator:
|
||||
Procedure procedure = descriptor.member.asProcedure;
|
||||
Procedure procedure = descriptor.memberReference.asProcedure;
|
||||
scope.addLocalMember(name.text,
|
||||
new DillExtensionOperatorBuilder(procedure, descriptor, this),
|
||||
setter: false);
|
||||
|
|
|
@ -43,20 +43,20 @@ class DillExtensionTypeDeclarationBuilder
|
|||
new ConstructorScope(
|
||||
_extensionTypeDeclaration.name, <String, MemberBuilder>{})) {
|
||||
for (ExtensionTypeMemberDescriptor descriptor
|
||||
in _extensionTypeDeclaration.members) {
|
||||
in _extensionTypeDeclaration.memberDescriptors) {
|
||||
Name name = descriptor.name;
|
||||
switch (descriptor.kind) {
|
||||
case ExtensionTypeMemberKind.Method:
|
||||
if (descriptor.isStatic) {
|
||||
Procedure procedure = descriptor.member.asProcedure;
|
||||
Procedure procedure = descriptor.memberReference.asProcedure;
|
||||
scope.addLocalMember(
|
||||
name.text,
|
||||
new DillExtensionTypeStaticMethodBuilder(
|
||||
procedure, descriptor, this),
|
||||
setter: false);
|
||||
} else {
|
||||
Procedure procedure = descriptor.member.asProcedure;
|
||||
Procedure? tearOff = descriptor.tearOff?.asProcedure;
|
||||
Procedure procedure = descriptor.memberReference.asProcedure;
|
||||
Procedure? tearOff = descriptor.tearOffReference?.asProcedure;
|
||||
assert(tearOff != null, "No tear found for ${descriptor}");
|
||||
scope.addLocalMember(
|
||||
name.text,
|
||||
|
@ -66,32 +66,32 @@ class DillExtensionTypeDeclarationBuilder
|
|||
}
|
||||
break;
|
||||
case ExtensionTypeMemberKind.Getter:
|
||||
Procedure procedure = descriptor.member.asProcedure;
|
||||
Procedure procedure = descriptor.memberReference.asProcedure;
|
||||
scope.addLocalMember(name.text,
|
||||
new DillExtensionTypeGetterBuilder(procedure, descriptor, this),
|
||||
setter: false);
|
||||
break;
|
||||
case ExtensionTypeMemberKind.Field:
|
||||
Field field = descriptor.member.asField;
|
||||
Field field = descriptor.memberReference.asField;
|
||||
scope.addLocalMember(name.text,
|
||||
new DillExtensionTypeFieldBuilder(field, descriptor, this),
|
||||
setter: false);
|
||||
break;
|
||||
case ExtensionTypeMemberKind.Setter:
|
||||
Procedure procedure = descriptor.member.asProcedure;
|
||||
Procedure procedure = descriptor.memberReference.asProcedure;
|
||||
scope.addLocalMember(name.text,
|
||||
new DillExtensionTypeSetterBuilder(procedure, descriptor, this),
|
||||
setter: true);
|
||||
break;
|
||||
case ExtensionTypeMemberKind.Operator:
|
||||
Procedure procedure = descriptor.member.asProcedure;
|
||||
Procedure procedure = descriptor.memberReference.asProcedure;
|
||||
scope.addLocalMember(name.text,
|
||||
new DillExtensionTypeOperatorBuilder(procedure, descriptor, this),
|
||||
setter: false);
|
||||
break;
|
||||
case ExtensionTypeMemberKind.Constructor:
|
||||
Procedure procedure = descriptor.member.asProcedure;
|
||||
Procedure? tearOff = descriptor.tearOff?.asProcedure;
|
||||
Procedure procedure = descriptor.memberReference.asProcedure;
|
||||
Procedure? tearOff = descriptor.tearOffReference?.asProcedure;
|
||||
constructorScope.addLocalMember(
|
||||
name.text,
|
||||
new DillExtensionTypeConstructorBuilder(
|
||||
|
@ -99,8 +99,8 @@ class DillExtensionTypeDeclarationBuilder
|
|||
break;
|
||||
case ExtensionTypeMemberKind.Factory:
|
||||
case ExtensionTypeMemberKind.RedirectingFactory:
|
||||
Procedure procedure = descriptor.member.asProcedure;
|
||||
Procedure? tearOff = descriptor.tearOff?.asProcedure;
|
||||
Procedure procedure = descriptor.memberReference.asProcedure;
|
||||
Procedure? tearOff = descriptor.tearOffReference?.asProcedure;
|
||||
constructorScope.addLocalMember(
|
||||
name.text,
|
||||
new DillExtensionTypeFactoryBuilder(
|
||||
|
|
|
@ -149,10 +149,10 @@ class SourceExtensionBuilder extends ExtensionBuilderImpl
|
|||
kind = ExtensionMemberKind.Operator;
|
||||
break;
|
||||
}
|
||||
extension.members.add(new ExtensionMemberDescriptor(
|
||||
extension.memberDescriptors.add(new ExtensionMemberDescriptor(
|
||||
name: new Name(name, libraryBuilder.library),
|
||||
member: memberReference,
|
||||
tearOff: tearOffReference,
|
||||
memberReference: memberReference,
|
||||
tearOffReference: tearOffReference,
|
||||
isStatic: memberBuilder.isStatic,
|
||||
kind: kind));
|
||||
}
|
||||
|
|
|
@ -503,12 +503,13 @@ class SourceExtensionTypeDeclarationBuilder
|
|||
kind = ExtensionTypeMemberKind.Operator;
|
||||
break;
|
||||
}
|
||||
extensionTypeDeclaration.members.add(new ExtensionTypeMemberDescriptor(
|
||||
name: new Name(name, libraryBuilder.library),
|
||||
member: memberReference,
|
||||
tearOff: tearOffReference,
|
||||
isStatic: memberBuilder.isStatic,
|
||||
kind: kind));
|
||||
extensionTypeDeclaration.memberDescriptors.add(
|
||||
new ExtensionTypeMemberDescriptor(
|
||||
name: new Name(name, libraryBuilder.library),
|
||||
memberReference: memberReference,
|
||||
tearOffReference: tearOffReference,
|
||||
isStatic: memberBuilder.isStatic,
|
||||
kind: kind));
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -986,33 +986,33 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
|
|||
Member? targetTearoff;
|
||||
ProcedureKind? targetKind;
|
||||
for (ExtensionTypeMemberDescriptor descriptor
|
||||
in extensionType.extensionTypeDeclaration.members) {
|
||||
in extensionType.extensionTypeDeclaration.memberDescriptors) {
|
||||
if (descriptor.name == name) {
|
||||
switch (descriptor.kind) {
|
||||
case ExtensionTypeMemberKind.Method:
|
||||
if (!isSetter) {
|
||||
targetMember = descriptor.member.asMember;
|
||||
targetTearoff = descriptor.tearOff?.asMember;
|
||||
targetMember = descriptor.memberReference.asMember;
|
||||
targetTearoff = descriptor.tearOffReference?.asMember;
|
||||
targetKind = ProcedureKind.Method;
|
||||
}
|
||||
break;
|
||||
case ExtensionTypeMemberKind.Getter:
|
||||
if (!isSetter) {
|
||||
targetMember = descriptor.member.asMember;
|
||||
targetMember = descriptor.memberReference.asMember;
|
||||
targetTearoff = null;
|
||||
targetKind = ProcedureKind.Getter;
|
||||
}
|
||||
break;
|
||||
case ExtensionTypeMemberKind.Setter:
|
||||
if (isSetter) {
|
||||
targetMember = descriptor.member.asMember;
|
||||
targetMember = descriptor.memberReference.asMember;
|
||||
targetTearoff = null;
|
||||
targetKind = ProcedureKind.Setter;
|
||||
}
|
||||
break;
|
||||
case ExtensionTypeMemberKind.Operator:
|
||||
if (!isSetter) {
|
||||
targetMember = descriptor.member.asMember;
|
||||
targetMember = descriptor.memberReference.asMember;
|
||||
targetTearoff = null;
|
||||
targetKind = ProcedureKind.Operator;
|
||||
}
|
||||
|
|
|
@ -853,9 +853,9 @@ List<String> extensionMethodDescriptorToText(
|
|||
}
|
||||
|
||||
return [
|
||||
descriptorToText(descriptor.member, forTearOff: false),
|
||||
if (descriptor.tearOff != null)
|
||||
descriptorToText(descriptor.tearOff!, forTearOff: true),
|
||||
descriptorToText(descriptor.memberReference, forTearOff: false),
|
||||
if (descriptor.tearOffReference != null)
|
||||
descriptorToText(descriptor.tearOffReference!, forTearOff: true),
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -217,7 +217,7 @@ class ExtensionsDataExtractor extends CfeDataExtractor<Features> {
|
|||
features.addElement(
|
||||
Tags.extensionTypeParameters, typeParameterToText(typeParameter));
|
||||
}
|
||||
for (ExtensionMemberDescriptor descriptor in extension.members) {
|
||||
for (ExtensionMemberDescriptor descriptor in extension.memberDescriptors) {
|
||||
for (String text in extensionMethodDescriptorToText(descriptor)) {
|
||||
features.addElement(Tags.extensionMembers, text);
|
||||
}
|
||||
|
|
|
@ -400,6 +400,7 @@ dereferencing
|
|||
deregister
|
||||
descent
|
||||
descriptive
|
||||
descriptors
|
||||
deserializable
|
||||
deserializer
|
||||
deserializers
|
||||
|
|
|
@ -117,6 +117,7 @@ const Map<String?, Map<String, FieldRule?>> _fieldRuleMap = {
|
|||
},
|
||||
'ExtensionTypeDeclaration': {
|
||||
'typeParameters': FieldRule(isDeclaration: true),
|
||||
'_procedures': FieldRule(name: 'procedures'),
|
||||
},
|
||||
'Field': {
|
||||
'reference': FieldRule(name: 'fieldReference'),
|
||||
|
|
|
@ -147,7 +147,7 @@ type CanonicalName {
|
|||
|
||||
type ComponentFile {
|
||||
UInt32 magic = 0x90ABCDEF;
|
||||
UInt32 formatVersion = 111;
|
||||
UInt32 formatVersion = 112;
|
||||
Byte[10] shortSdkHash;
|
||||
List<String> problemsAsJson; // Described in problems.md.
|
||||
Library[] libraries;
|
||||
|
@ -374,6 +374,7 @@ type ExtensionTypeDeclaration extends Node {
|
|||
DartType declaredRepresentationType;
|
||||
StringReference representationName;
|
||||
List<DartType> implements;
|
||||
List<Procedure> procedures;
|
||||
List<ExtensionTypeMemberKind> members;
|
||||
}
|
||||
|
||||
|
|
|
@ -1570,7 +1570,7 @@ class Extension extends NamedNode
|
|||
///
|
||||
/// The members are converted into top-level members and only accessible
|
||||
/// by reference through [ExtensionMemberDescriptor].
|
||||
List<ExtensionMemberDescriptor> members;
|
||||
List<ExtensionMemberDescriptor> memberDescriptors;
|
||||
|
||||
@override
|
||||
List<Expression> annotations = const <Expression>[];
|
||||
|
@ -1594,11 +1594,12 @@ class Extension extends NamedNode
|
|||
{required this.name,
|
||||
List<TypeParameter>? typeParameters,
|
||||
DartType? onType,
|
||||
List<ExtensionMemberDescriptor>? members,
|
||||
List<ExtensionMemberDescriptor>? memberDescriptors,
|
||||
required this.fileUri,
|
||||
Reference? reference})
|
||||
: this.typeParameters = typeParameters ?? <TypeParameter>[],
|
||||
this.members = members ?? <ExtensionMemberDescriptor>[],
|
||||
this.memberDescriptors =
|
||||
memberDescriptors ?? <ExtensionMemberDescriptor>[],
|
||||
super(reference) {
|
||||
setParents(this.typeParameters, this);
|
||||
if (onType != null) {
|
||||
|
@ -1722,18 +1723,18 @@ class ExtensionMemberDescriptor {
|
|||
int flags = 0;
|
||||
|
||||
/// Reference to the top-level member created for the extension method.
|
||||
final Reference member;
|
||||
final Reference memberReference;
|
||||
|
||||
/// Reference to the top-level member created for the extension member tear
|
||||
/// off, if any.
|
||||
final Reference? tearOff;
|
||||
final Reference? tearOffReference;
|
||||
|
||||
ExtensionMemberDescriptor(
|
||||
{required this.name,
|
||||
required this.kind,
|
||||
bool isStatic = false,
|
||||
required this.member,
|
||||
required this.tearOff}) {
|
||||
required this.memberReference,
|
||||
required this.tearOffReference}) {
|
||||
this.isStatic = isStatic;
|
||||
}
|
||||
|
||||
|
@ -1747,7 +1748,7 @@ class ExtensionMemberDescriptor {
|
|||
@override
|
||||
String toString() {
|
||||
return 'ExtensionMemberDescriptor($name,$kind,'
|
||||
'${member.toStringInternal()},isStatic=${isStatic})';
|
||||
'${memberReference.toStringInternal()},isStatic=${isStatic})';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1790,11 +1791,19 @@ class ExtensionTypeDeclaration extends NamedNode
|
|||
/// library of the extension type declaration.
|
||||
late String representationName;
|
||||
|
||||
/// Abstract procedures that are part of the extension type declaration
|
||||
/// interface.
|
||||
///
|
||||
/// This includes a getter for the representation field and member signatures
|
||||
/// computed as the combined member signature of inherited non-extension type
|
||||
/// members.
|
||||
List<Procedure> _procedures;
|
||||
|
||||
/// The members declared by the extension type declaration.
|
||||
///
|
||||
/// The members are converted into top-level members and only accessible
|
||||
/// by reference through [ExtensionTypeMemberDescriptor].
|
||||
List<ExtensionTypeMemberDescriptor> members;
|
||||
List<ExtensionTypeMemberDescriptor> memberDescriptors;
|
||||
|
||||
@override
|
||||
List<Expression> annotations = const <Expression>[];
|
||||
|
@ -1816,15 +1825,19 @@ class ExtensionTypeDeclaration extends NamedNode
|
|||
{required this.name,
|
||||
List<TypeParameter>? typeParameters,
|
||||
DartType? declaredRepresentationType,
|
||||
List<ExtensionTypeMemberDescriptor>? members,
|
||||
List<ExtensionTypeMemberDescriptor>? memberDescriptors,
|
||||
List<DartType>? implements,
|
||||
List<Procedure>? procedures,
|
||||
required this.fileUri,
|
||||
Reference? reference})
|
||||
: this.typeParameters = typeParameters ?? <TypeParameter>[],
|
||||
this.members = members ?? <ExtensionTypeMemberDescriptor>[],
|
||||
this.memberDescriptors =
|
||||
memberDescriptors ?? <ExtensionTypeMemberDescriptor>[],
|
||||
this.implements = implements ?? <DartType>[],
|
||||
this._procedures = procedures ?? <Procedure>[],
|
||||
super(reference) {
|
||||
setParents(this.typeParameters, this);
|
||||
setParents(this._procedures, this);
|
||||
if (declaredRepresentationType != null) {
|
||||
this.declaredRepresentationType = declaredRepresentationType;
|
||||
}
|
||||
|
@ -1837,6 +1850,20 @@ class ExtensionTypeDeclaration extends NamedNode
|
|||
|
||||
Library get enclosingLibrary => parent as Library;
|
||||
|
||||
void addProcedure(Procedure procedure) {
|
||||
procedure.parent = this;
|
||||
procedures.add(procedure);
|
||||
}
|
||||
|
||||
List<Procedure> get procedures => _procedures;
|
||||
|
||||
/// Internal. Should *ONLY* be used from within kernel.
|
||||
///
|
||||
/// Used for adding procedures when reading the dill file.
|
||||
void set proceduresInternal(List<Procedure> procedures) {
|
||||
_procedures = procedures;
|
||||
}
|
||||
|
||||
@override
|
||||
R accept<R>(TreeVisitor<R> v) => v.visitExtensionTypeDeclaration(this);
|
||||
|
||||
|
@ -1852,6 +1879,7 @@ class ExtensionTypeDeclaration extends NamedNode
|
|||
visitList(annotations, v);
|
||||
visitList(typeParameters, v);
|
||||
declaredRepresentationType.accept(v);
|
||||
visitList(procedures, v);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1859,6 +1887,7 @@ class ExtensionTypeDeclaration extends NamedNode
|
|||
v.transformList(annotations, this);
|
||||
v.transformList(typeParameters, this);
|
||||
declaredRepresentationType = v.visitDartType(declaredRepresentationType);
|
||||
v.transformList(procedures, this);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1867,6 +1896,7 @@ class ExtensionTypeDeclaration extends NamedNode
|
|||
v.transformTypeParameterList(typeParameters, this);
|
||||
declaredRepresentationType =
|
||||
v.visitDartType(declaredRepresentationType, cannotRemoveSentinel);
|
||||
v.transformProcedureList(procedures, this);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1933,18 +1963,18 @@ class ExtensionTypeMemberDescriptor {
|
|||
|
||||
/// Reference to the top-level member created for the extension type
|
||||
/// declaration member.
|
||||
final Reference member;
|
||||
final Reference memberReference;
|
||||
|
||||
/// Reference to the top-level member created for the extension type
|
||||
/// declaration member tear off, if any.
|
||||
final Reference? tearOff;
|
||||
final Reference? tearOffReference;
|
||||
|
||||
ExtensionTypeMemberDescriptor(
|
||||
{required this.name,
|
||||
required this.kind,
|
||||
bool isStatic = false,
|
||||
required this.member,
|
||||
required this.tearOff}) {
|
||||
required this.memberReference,
|
||||
required this.tearOffReference}) {
|
||||
this.isStatic = isStatic;
|
||||
}
|
||||
|
||||
|
@ -1959,8 +1989,8 @@ class ExtensionTypeMemberDescriptor {
|
|||
@override
|
||||
String toString() {
|
||||
return 'ExtensionTypeMemberDescriptor($name,$kind,'
|
||||
'${member.toStringInternal()},isStatic=${isStatic},'
|
||||
'${tearOff?.toStringInternal()})';
|
||||
'${memberReference.toStringInternal()},isStatic=${isStatic},'
|
||||
'${tearOffReference?.toStringInternal()})';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15296,8 +15326,8 @@ final ExtensionMemberDescriptor dummyExtensionMemberDescriptor =
|
|||
new ExtensionMemberDescriptor(
|
||||
name: dummyName,
|
||||
kind: ExtensionMemberKind.Getter,
|
||||
member: dummyReference,
|
||||
tearOff: null);
|
||||
memberReference: dummyReference,
|
||||
tearOffReference: null);
|
||||
|
||||
/// Non-nullable [ExtensionTypeDeclaration] dummy value.
|
||||
///
|
||||
|
@ -15316,8 +15346,8 @@ final ExtensionTypeMemberDescriptor dummyExtensionTypeMemberDescriptor =
|
|||
new ExtensionTypeMemberDescriptor(
|
||||
name: dummyName,
|
||||
kind: ExtensionTypeMemberKind.Getter,
|
||||
member: dummyReference,
|
||||
tearOff: null);
|
||||
memberReference: dummyReference,
|
||||
tearOffReference: null);
|
||||
|
||||
/// Non-nullable [ExtensionType] dummy value.
|
||||
///
|
||||
|
|
|
@ -1361,6 +1361,19 @@ class BinaryBuilder {
|
|||
return list;
|
||||
}
|
||||
|
||||
List<Procedure> _readProcedureListWithoutOffsets(TreeNode parent) {
|
||||
int length = readUInt30();
|
||||
if (!useGrowableLists && length == 0) {
|
||||
// When lists don't have to be growable anyway, we might as well use an
|
||||
// almost constant one for the empty list.
|
||||
return emptyListOfProcedure;
|
||||
}
|
||||
List<Procedure> list = new List<Procedure>.generate(length, (int index) {
|
||||
return readProcedure(/* no end offset = */ -1)..parent = parent;
|
||||
}, growable: useGrowableLists);
|
||||
return list;
|
||||
}
|
||||
|
||||
void _readLibraryDependencies(Library library) {
|
||||
int length = readUInt30();
|
||||
if (!useGrowableLists && length == 0) {
|
||||
|
@ -1571,7 +1584,7 @@ class BinaryBuilder {
|
|||
node.fileUri = fileUri;
|
||||
node.onType = onType;
|
||||
|
||||
node.members = _readExtensionMemberDescriptorList();
|
||||
node.memberDescriptors = _readExtensionMemberDescriptorList();
|
||||
|
||||
return node;
|
||||
}
|
||||
|
@ -1597,8 +1610,8 @@ class BinaryBuilder {
|
|||
return new ExtensionMemberDescriptor(
|
||||
name: name,
|
||||
kind: ExtensionMemberKind.values[kind],
|
||||
member: memberName.reference,
|
||||
tearOff: tearOffName?.reference)
|
||||
memberReference: memberName.reference,
|
||||
tearOffReference: tearOffName?.reference)
|
||||
..flags = flags;
|
||||
}
|
||||
|
||||
|
@ -1639,6 +1652,8 @@ class BinaryBuilder {
|
|||
DartType representationType = readDartType();
|
||||
String representationName = readStringReference();
|
||||
List<DartType> implements = _readExtensionTypeDeclarationImplementsList();
|
||||
|
||||
node.proceduresInternal = _readProcedureListWithoutOffsets(node);
|
||||
typeParameterStack.length = 0;
|
||||
|
||||
node.name = name;
|
||||
|
@ -1647,7 +1662,8 @@ class BinaryBuilder {
|
|||
node.representationName = representationName;
|
||||
|
||||
node.implements = implements;
|
||||
node.members = _readExtensionTypeMemberDescriptorList();
|
||||
|
||||
node.memberDescriptors = _readExtensionTypeMemberDescriptorList();
|
||||
|
||||
return node;
|
||||
}
|
||||
|
@ -1684,8 +1700,8 @@ class BinaryBuilder {
|
|||
return new ExtensionTypeMemberDescriptor(
|
||||
name: name,
|
||||
kind: ExtensionTypeMemberKind.values[kind],
|
||||
member: memberName.reference,
|
||||
tearOff: tearOffName?.reference)
|
||||
memberReference: memberName.reference,
|
||||
tearOffReference: tearOffName?.reference)
|
||||
..flags = flags;
|
||||
}
|
||||
|
||||
|
|
|
@ -2646,17 +2646,17 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
|
|||
|
||||
leaveScope(typeParameters: node.typeParameters);
|
||||
|
||||
final int len = node.members.length;
|
||||
final int len = node.memberDescriptors.length;
|
||||
writeUInt30(len);
|
||||
for (int i = 0; i < len; i++) {
|
||||
final ExtensionMemberDescriptor descriptor = node.members[i];
|
||||
final ExtensionMemberDescriptor descriptor = node.memberDescriptors[i];
|
||||
writeName(descriptor.name);
|
||||
writeByte(descriptor.kind.index);
|
||||
writeByte(descriptor.flags);
|
||||
assert(descriptor.member.canonicalName != null,
|
||||
assert(descriptor.memberReference.canonicalName != null,
|
||||
"No canonical name for ${descriptor}.");
|
||||
writeNonNullCanonicalNameReference(descriptor.member);
|
||||
writeNullAllowedCanonicalNameReference(descriptor.tearOff);
|
||||
writeNonNullCanonicalNameReference(descriptor.memberReference);
|
||||
writeNullAllowedCanonicalNameReference(descriptor.tearOffReference);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2679,23 +2679,25 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
|
|||
writeDartType(node.declaredRepresentationType);
|
||||
writeStringReference(node.representationName);
|
||||
writeNodeList(node.implements);
|
||||
writeProcedureNodeList(node.procedures);
|
||||
leaveScope(typeParameters: node.typeParameters);
|
||||
|
||||
final int len = node.members.length;
|
||||
final int len = node.memberDescriptors.length;
|
||||
writeUInt30(len);
|
||||
for (int i = 0; i < len; i++) {
|
||||
final ExtensionTypeMemberDescriptor descriptor = node.members[i];
|
||||
final ExtensionTypeMemberDescriptor descriptor =
|
||||
node.memberDescriptors[i];
|
||||
writeName(descriptor.name);
|
||||
writeByte(descriptor.kind.index);
|
||||
writeByte(descriptor.flags);
|
||||
assert(descriptor.member.canonicalName != null,
|
||||
assert(descriptor.memberReference.canonicalName != null,
|
||||
"No canonical name for ${descriptor}.");
|
||||
writeNonNullCanonicalNameReference(descriptor.member);
|
||||
writeNonNullCanonicalNameReference(descriptor.memberReference);
|
||||
assert(
|
||||
descriptor.tearOff == null ||
|
||||
descriptor.tearOff?.canonicalName != null,
|
||||
descriptor.tearOffReference == null ||
|
||||
descriptor.tearOffReference?.canonicalName != null,
|
||||
"No canonical name for ${descriptor} tear-off.");
|
||||
writeNullAllowedCanonicalNameReference(descriptor.tearOff);
|
||||
writeNullAllowedCanonicalNameReference(descriptor.tearOffReference);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -226,7 +226,7 @@ class Tag {
|
|||
/// Internal version of kernel binary format.
|
||||
/// Bump it when making incompatible changes in kernel binaries.
|
||||
/// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md.
|
||||
static const int BinaryFormatVersion = 111;
|
||||
static const int BinaryFormatVersion = 112;
|
||||
}
|
||||
|
||||
abstract class ConstantTag {
|
||||
|
|
|
@ -247,7 +247,7 @@ class _MemberTable {
|
|||
class_!.fields.forEach(_addMember);
|
||||
class_!.constructors.forEach(_addMember);
|
||||
} else if (extension_ != null) {
|
||||
extension_!.members.forEach(_addExtensionMember);
|
||||
extension_!.memberDescriptors.forEach(_addExtensionMember);
|
||||
} else {
|
||||
library.procedures.forEach(_addMember);
|
||||
library.fields.forEach(_addMember);
|
||||
|
@ -307,8 +307,8 @@ class _MemberTable {
|
|||
_members![name] = replacement;
|
||||
}
|
||||
|
||||
addReference(extensionMember.member, forTearOff: false);
|
||||
addReference(extensionMember.tearOff, forTearOff: true);
|
||||
addReference(extensionMember.memberReference, forTearOff: false);
|
||||
addReference(extensionMember.tearOffReference, forTearOff: true);
|
||||
}
|
||||
|
||||
String get containerName {
|
||||
|
|
|
@ -129,8 +129,9 @@ class IndexedLibrary extends IndexedContainer {
|
|||
// repurposing these canonical names.
|
||||
for (Extension extension in unnamedExtensions) {
|
||||
extension.reference.canonicalName?.unbind();
|
||||
for (ExtensionMemberDescriptor descriptor in extension.members) {
|
||||
Reference reference = descriptor.member;
|
||||
for (ExtensionMemberDescriptor descriptor
|
||||
in extension.memberDescriptors) {
|
||||
Reference reference = descriptor.memberReference;
|
||||
Member member = reference.asMember;
|
||||
if (member is Field) {
|
||||
member.fieldReference.canonicalName?.unbind();
|
||||
|
@ -139,7 +140,7 @@ class IndexedLibrary extends IndexedContainer {
|
|||
} else {
|
||||
member.reference.canonicalName?.unbind();
|
||||
}
|
||||
descriptor.tearOff?.canonicalName?.unbind();
|
||||
descriptor.tearOffReference?.canonicalName?.unbind();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1715,10 +1715,11 @@ class EquivalenceStrategy {
|
|||
if (!checkExtensionMemberDescriptor_flags(visitor, node, other)) {
|
||||
result = visitor.resultOnInequivalence;
|
||||
}
|
||||
if (!checkExtensionMemberDescriptor_member(visitor, node, other)) {
|
||||
if (!checkExtensionMemberDescriptor_memberReference(visitor, node, other)) {
|
||||
result = visitor.resultOnInequivalence;
|
||||
}
|
||||
if (!checkExtensionMemberDescriptor_tearOff(visitor, node, other)) {
|
||||
if (!checkExtensionMemberDescriptor_tearOffReference(
|
||||
visitor, node, other)) {
|
||||
result = visitor.resultOnInequivalence;
|
||||
}
|
||||
return result;
|
||||
|
@ -1746,7 +1747,7 @@ class EquivalenceStrategy {
|
|||
if (!checkExtension_onType(visitor, node, other)) {
|
||||
result = visitor.resultOnInequivalence;
|
||||
}
|
||||
if (!checkExtension_members(visitor, node, other)) {
|
||||
if (!checkExtension_memberDescriptors(visitor, node, other)) {
|
||||
result = visitor.resultOnInequivalence;
|
||||
}
|
||||
if (!checkExtension_annotations(visitor, node, other)) {
|
||||
|
@ -1780,10 +1781,12 @@ class EquivalenceStrategy {
|
|||
if (!checkExtensionTypeMemberDescriptor_flags(visitor, node, other)) {
|
||||
result = visitor.resultOnInequivalence;
|
||||
}
|
||||
if (!checkExtensionTypeMemberDescriptor_member(visitor, node, other)) {
|
||||
if (!checkExtensionTypeMemberDescriptor_memberReference(
|
||||
visitor, node, other)) {
|
||||
result = visitor.resultOnInequivalence;
|
||||
}
|
||||
if (!checkExtensionTypeMemberDescriptor_tearOff(visitor, node, other)) {
|
||||
if (!checkExtensionTypeMemberDescriptor_tearOffReference(
|
||||
visitor, node, other)) {
|
||||
result = visitor.resultOnInequivalence;
|
||||
}
|
||||
return result;
|
||||
|
@ -1816,7 +1819,11 @@ class EquivalenceStrategy {
|
|||
visitor, node, other)) {
|
||||
result = visitor.resultOnInequivalence;
|
||||
}
|
||||
if (!checkExtensionTypeDeclaration_members(visitor, node, other)) {
|
||||
if (!checkExtensionTypeDeclaration_procedures(visitor, node, other)) {
|
||||
result = visitor.resultOnInequivalence;
|
||||
}
|
||||
if (!checkExtensionTypeDeclaration_memberDescriptors(
|
||||
visitor, node, other)) {
|
||||
result = visitor.resultOnInequivalence;
|
||||
}
|
||||
if (!checkExtensionTypeDeclaration_annotations(visitor, node, other)) {
|
||||
|
@ -6022,24 +6029,31 @@ class EquivalenceStrategy {
|
|||
return visitor.checkValues(node.flags, other.flags, 'flags');
|
||||
}
|
||||
|
||||
bool checkExtensionMemberDescriptor_member(EquivalenceVisitor visitor,
|
||||
ExtensionMemberDescriptor node, ExtensionMemberDescriptor other) {
|
||||
return visitor.checkReferences(node.member, other.member, 'member');
|
||||
bool checkExtensionMemberDescriptor_memberReference(
|
||||
EquivalenceVisitor visitor,
|
||||
ExtensionMemberDescriptor node,
|
||||
ExtensionMemberDescriptor other) {
|
||||
return visitor.checkReferences(
|
||||
node.memberReference, other.memberReference, 'memberReference');
|
||||
}
|
||||
|
||||
bool checkExtensionMemberDescriptor_tearOff(EquivalenceVisitor visitor,
|
||||
ExtensionMemberDescriptor node, ExtensionMemberDescriptor other) {
|
||||
return visitor.checkReferences(node.tearOff, other.tearOff, 'tearOff');
|
||||
bool checkExtensionMemberDescriptor_tearOffReference(
|
||||
EquivalenceVisitor visitor,
|
||||
ExtensionMemberDescriptor node,
|
||||
ExtensionMemberDescriptor other) {
|
||||
return visitor.checkReferences(
|
||||
node.tearOffReference, other.tearOffReference, 'tearOffReference');
|
||||
}
|
||||
|
||||
bool checkExtension_members(
|
||||
bool checkExtension_memberDescriptors(
|
||||
EquivalenceVisitor visitor, Extension node, Extension other) {
|
||||
return visitor.checkLists(node.members, other.members, (a, b, _) {
|
||||
return visitor.checkLists(node.memberDescriptors, other.memberDescriptors,
|
||||
(a, b, _) {
|
||||
if (identical(a, b)) return true;
|
||||
if (a is! ExtensionMemberDescriptor) return false;
|
||||
if (b is! ExtensionMemberDescriptor) return false;
|
||||
return checkExtensionMemberDescriptor(visitor, a, b);
|
||||
}, 'members');
|
||||
}, 'memberDescriptors');
|
||||
}
|
||||
|
||||
bool checkExtension_annotations(
|
||||
|
@ -6095,6 +6109,12 @@ class EquivalenceStrategy {
|
|||
other.representationName, 'representationName');
|
||||
}
|
||||
|
||||
bool checkExtensionTypeDeclaration_procedures(EquivalenceVisitor visitor,
|
||||
ExtensionTypeDeclaration node, ExtensionTypeDeclaration other) {
|
||||
return visitor.checkLists(
|
||||
node.procedures, other.procedures, visitor.checkNodes, 'procedures');
|
||||
}
|
||||
|
||||
bool checkExtensionTypeMemberDescriptor_name(EquivalenceVisitor visitor,
|
||||
ExtensionTypeMemberDescriptor node, ExtensionTypeMemberDescriptor other) {
|
||||
return visitor.checkNodes(node.name, other.name, 'name');
|
||||
|
@ -6110,24 +6130,33 @@ class EquivalenceStrategy {
|
|||
return visitor.checkValues(node.flags, other.flags, 'flags');
|
||||
}
|
||||
|
||||
bool checkExtensionTypeMemberDescriptor_member(EquivalenceVisitor visitor,
|
||||
ExtensionTypeMemberDescriptor node, ExtensionTypeMemberDescriptor other) {
|
||||
return visitor.checkReferences(node.member, other.member, 'member');
|
||||
bool checkExtensionTypeMemberDescriptor_memberReference(
|
||||
EquivalenceVisitor visitor,
|
||||
ExtensionTypeMemberDescriptor node,
|
||||
ExtensionTypeMemberDescriptor other) {
|
||||
return visitor.checkReferences(
|
||||
node.memberReference, other.memberReference, 'memberReference');
|
||||
}
|
||||
|
||||
bool checkExtensionTypeMemberDescriptor_tearOff(EquivalenceVisitor visitor,
|
||||
ExtensionTypeMemberDescriptor node, ExtensionTypeMemberDescriptor other) {
|
||||
return visitor.checkReferences(node.tearOff, other.tearOff, 'tearOff');
|
||||
bool checkExtensionTypeMemberDescriptor_tearOffReference(
|
||||
EquivalenceVisitor visitor,
|
||||
ExtensionTypeMemberDescriptor node,
|
||||
ExtensionTypeMemberDescriptor other) {
|
||||
return visitor.checkReferences(
|
||||
node.tearOffReference, other.tearOffReference, 'tearOffReference');
|
||||
}
|
||||
|
||||
bool checkExtensionTypeDeclaration_members(EquivalenceVisitor visitor,
|
||||
ExtensionTypeDeclaration node, ExtensionTypeDeclaration other) {
|
||||
return visitor.checkLists(node.members, other.members, (a, b, _) {
|
||||
bool checkExtensionTypeDeclaration_memberDescriptors(
|
||||
EquivalenceVisitor visitor,
|
||||
ExtensionTypeDeclaration node,
|
||||
ExtensionTypeDeclaration other) {
|
||||
return visitor.checkLists(node.memberDescriptors, other.memberDescriptors,
|
||||
(a, b, _) {
|
||||
if (identical(a, b)) return true;
|
||||
if (a is! ExtensionTypeMemberDescriptor) return false;
|
||||
if (b is! ExtensionTypeMemberDescriptor) return false;
|
||||
return checkExtensionTypeMemberDescriptor(visitor, a, b);
|
||||
}, 'members');
|
||||
}, 'memberDescriptors');
|
||||
}
|
||||
|
||||
bool checkExtensionTypeDeclaration_annotations(EquivalenceVisitor visitor,
|
||||
|
|
|
@ -1360,7 +1360,7 @@ class Printer extends VisitorDefault<void> with VisitorVoidMixin {
|
|||
|
||||
endLine(endLineString);
|
||||
++indentation;
|
||||
node.members.forEach((ExtensionMemberDescriptor descriptor) {
|
||||
node.memberDescriptors.forEach((ExtensionMemberDescriptor descriptor) {
|
||||
void writeReference(Reference reference, {required bool isTearOff}) {
|
||||
writeIndentation();
|
||||
writeModifier(descriptor.isStatic, 'static');
|
||||
|
@ -1398,9 +1398,9 @@ class Printer extends VisitorDefault<void> with VisitorVoidMixin {
|
|||
endLine(';');
|
||||
}
|
||||
|
||||
writeReference(descriptor.member, isTearOff: false);
|
||||
if (descriptor.tearOff != null) {
|
||||
writeReference(descriptor.tearOff!, isTearOff: true);
|
||||
writeReference(descriptor.memberReference, isTearOff: false);
|
||||
if (descriptor.tearOffReference != null) {
|
||||
writeReference(descriptor.tearOffReference!, isTearOff: true);
|
||||
}
|
||||
});
|
||||
--indentation;
|
||||
|
@ -1430,7 +1430,8 @@ class Printer extends VisitorDefault<void> with VisitorVoidMixin {
|
|||
|
||||
endLine(endLineString);
|
||||
++indentation;
|
||||
node.members.forEach((ExtensionTypeMemberDescriptor descriptor) {
|
||||
node.procedures.forEach(writeNode);
|
||||
node.memberDescriptors.forEach((ExtensionTypeMemberDescriptor descriptor) {
|
||||
void writeReference(Reference reference, {required bool isTearOff}) {
|
||||
writeIndentation();
|
||||
writeModifier(descriptor.isStatic, 'static');
|
||||
|
@ -1477,9 +1478,9 @@ class Printer extends VisitorDefault<void> with VisitorVoidMixin {
|
|||
endLine(';');
|
||||
}
|
||||
|
||||
writeReference(descriptor.member, isTearOff: false);
|
||||
if (descriptor.tearOff != null) {
|
||||
writeReference(descriptor.tearOff!, isTearOff: true);
|
||||
writeReference(descriptor.memberReference, isTearOff: false);
|
||||
if (descriptor.tearOffReference != null) {
|
||||
writeReference(descriptor.tearOffReference!, isTearOff: true);
|
||||
}
|
||||
});
|
||||
--indentation;
|
||||
|
|
|
@ -710,13 +710,13 @@ class WidgetCreatorTracker {
|
|||
return;
|
||||
}
|
||||
|
||||
for (ExtensionMemberDescriptor member in extension.members) {
|
||||
for (ExtensionMemberDescriptor member in extension.memberDescriptors) {
|
||||
if (member.isStatic) {
|
||||
// We could support static extension methods but it is not clear that
|
||||
// there is a use case for this.
|
||||
continue;
|
||||
}
|
||||
final Procedure method = member.member.asProcedure;
|
||||
final Procedure method = member.memberReference.asProcedure;
|
||||
if (_hasWidgetFactoryAnnotation(method)) {
|
||||
_maybeAddNamedParameter(
|
||||
method.function,
|
||||
|
@ -730,7 +730,7 @@ class WidgetCreatorTracker {
|
|||
),
|
||||
);
|
||||
}
|
||||
final Procedure? tearOff = member.tearOff?.asProcedure;
|
||||
final Procedure? tearOff = member.tearOffReference?.asProcedure;
|
||||
if (tearOff != null && _hasWidgetFactoryAnnotation(tearOff)) {
|
||||
_maybeAddNamedParameter(
|
||||
tearOff.function,
|
||||
|
|
|
@ -403,8 +403,9 @@ class VerifyingVisitor extends RecursiveResultVisitor<void> {
|
|||
if (_extensionsMembers == null) {
|
||||
Map<Reference, ExtensionMemberDescriptor> map = _extensionsMembers = {};
|
||||
for (Extension extension in library.extensions) {
|
||||
for (ExtensionMemberDescriptor descriptor in extension.members) {
|
||||
Reference memberReference = descriptor.member;
|
||||
for (ExtensionMemberDescriptor descriptor
|
||||
in extension.memberDescriptors) {
|
||||
Reference memberReference = descriptor.memberReference;
|
||||
map[memberReference] = descriptor;
|
||||
Member member = memberReference.asMember;
|
||||
if (!member.isExtensionMember) {
|
||||
|
@ -413,7 +414,7 @@ class VerifyingVisitor extends RecursiveResultVisitor<void> {
|
|||
"Member $member (${descriptor}) from $extension is not marked "
|
||||
"as an extension member.");
|
||||
}
|
||||
Reference? tearOffReference = descriptor.tearOff;
|
||||
Reference? tearOffReference = descriptor.tearOffReference;
|
||||
if (tearOffReference != null) {
|
||||
map[tearOffReference] = descriptor;
|
||||
Member tearOff = tearOffReference.asMember;
|
||||
|
@ -438,8 +439,8 @@ class VerifyingVisitor extends RecursiveResultVisitor<void> {
|
|||
for (ExtensionTypeDeclaration extensionTypeDeclaration
|
||||
in library.extensionTypeDeclarations) {
|
||||
for (ExtensionTypeMemberDescriptor descriptor
|
||||
in extensionTypeDeclaration.members) {
|
||||
Reference memberReference = descriptor.member;
|
||||
in extensionTypeDeclaration.memberDescriptors) {
|
||||
Reference memberReference = descriptor.memberReference;
|
||||
map[memberReference] = descriptor;
|
||||
Member member = memberReference.asMember;
|
||||
if (!member.isExtensionTypeMember) {
|
||||
|
@ -448,7 +449,7 @@ class VerifyingVisitor extends RecursiveResultVisitor<void> {
|
|||
"Member $member (${descriptor}) from $extensionTypeDeclaration "
|
||||
"is not marked as an extension type member.");
|
||||
}
|
||||
Reference? tearOffReference = descriptor.tearOff;
|
||||
Reference? tearOffReference = descriptor.tearOffReference;
|
||||
if (tearOffReference != null) {
|
||||
map[tearOffReference] = descriptor;
|
||||
Member tearOff = tearOffReference.asMember;
|
||||
|
|
|
@ -877,9 +877,9 @@ class TreeShaker {
|
|||
if (m.isExtensionMember) {
|
||||
// The AST should have exactly one [Extension] for [m].
|
||||
final extension = m.enclosingLibrary.extensions.firstWhere((extension) {
|
||||
return extension.members.any((descriptor) =>
|
||||
descriptor.member.asMember == m ||
|
||||
descriptor.tearOff?.asMember == m);
|
||||
return extension.memberDescriptors.any((descriptor) =>
|
||||
descriptor.memberReference.asMember == m ||
|
||||
descriptor.tearOffReference?.asMember == m);
|
||||
});
|
||||
|
||||
// Ensure we retain the [Extension] itself (though members might be
|
||||
|
@ -894,9 +894,9 @@ class TreeShaker {
|
|||
final extensionTypeDeclaration = m
|
||||
.enclosingLibrary.extensionTypeDeclarations
|
||||
.firstWhere((extensionTypeDeclaration) {
|
||||
return extensionTypeDeclaration.members.any((descriptor) =>
|
||||
descriptor.member.asMember == m ||
|
||||
descriptor.tearOff?.asMember == m);
|
||||
return extensionTypeDeclaration.memberDescriptors.any((descriptor) =>
|
||||
descriptor.memberReference.asMember == m ||
|
||||
descriptor.tearOffReference?.asMember == m);
|
||||
});
|
||||
|
||||
// Ensure we retain the [ExtensionTypeDeclaration] itself (though
|
||||
|
@ -1985,17 +1985,17 @@ class _TreeShakerPass2 extends RemovingTransformer {
|
|||
TreeNode visitExtension(Extension node, TreeNode? removalSentinel) {
|
||||
if (shaker.isExtensionUsed(node)) {
|
||||
int writeIndex = 0;
|
||||
for (int i = 0; i < node.members.length; ++i) {
|
||||
ExtensionMemberDescriptor descriptor = node.members[i];
|
||||
for (int i = 0; i < node.memberDescriptors.length; ++i) {
|
||||
ExtensionMemberDescriptor descriptor = node.memberDescriptors[i];
|
||||
|
||||
// To avoid depending on the order in which members and extensions are
|
||||
// visited during the transformation, we handle both cases: either the
|
||||
// member was already removed or it will be removed later.
|
||||
final Reference memberReference = descriptor.member;
|
||||
final Reference memberReference = descriptor.memberReference;
|
||||
final bool memberIsBound = memberReference.node != null;
|
||||
final bool isMemberUsed =
|
||||
memberIsBound && shaker.isMemberUsed(memberReference.asMember);
|
||||
final Reference? tearOffReference = descriptor.tearOff;
|
||||
final Reference? tearOffReference = descriptor.tearOffReference;
|
||||
final bool tearOffIsBound = tearOffReference?.node != null;
|
||||
final bool isTearOffUsed =
|
||||
tearOffIsBound && shaker.isMemberUsed(tearOffReference!.asMember);
|
||||
|
@ -2008,16 +2008,16 @@ class _TreeShakerPass2 extends RemovingTransformer {
|
|||
name: descriptor.name,
|
||||
kind: descriptor.kind,
|
||||
isStatic: descriptor.isStatic,
|
||||
member: descriptor.member,
|
||||
tearOff: null);
|
||||
memberReference: descriptor.memberReference,
|
||||
tearOffReference: null);
|
||||
}
|
||||
node.members[writeIndex++] = descriptor;
|
||||
node.memberDescriptors[writeIndex++] = descriptor;
|
||||
}
|
||||
}
|
||||
node.members.length = writeIndex;
|
||||
node.memberDescriptors.length = writeIndex;
|
||||
|
||||
// We only retain the extension if at least one member is retained.
|
||||
assert(node.members.isNotEmpty);
|
||||
assert(node.memberDescriptors.isNotEmpty);
|
||||
return node;
|
||||
}
|
||||
return removalSentinel!;
|
||||
|
@ -2028,18 +2028,18 @@ class _TreeShakerPass2 extends RemovingTransformer {
|
|||
ExtensionTypeDeclaration node, TreeNode? removalSentinel) {
|
||||
if (shaker.isExtensionTypeDeclarationUsed(node)) {
|
||||
int writeIndex = 0;
|
||||
for (int i = 0; i < node.members.length; ++i) {
|
||||
ExtensionTypeMemberDescriptor descriptor = node.members[i];
|
||||
for (int i = 0; i < node.memberDescriptors.length; ++i) {
|
||||
ExtensionTypeMemberDescriptor descriptor = node.memberDescriptors[i];
|
||||
|
||||
// To avoid depending on the order in which members and extension type
|
||||
// declarations are visited during the transformation, we handle both
|
||||
// cases: either the member was already removed or it will be removed
|
||||
// later.
|
||||
final Reference memberReference = descriptor.member;
|
||||
final Reference memberReference = descriptor.memberReference;
|
||||
final bool memberIsBound = memberReference.node != null;
|
||||
final bool isMemberUsed =
|
||||
memberIsBound && shaker.isMemberUsed(memberReference.asMember);
|
||||
final Reference? tearOffReference = descriptor.tearOff;
|
||||
final Reference? tearOffReference = descriptor.tearOffReference;
|
||||
final bool tearOffIsBound = tearOffReference?.node != null;
|
||||
final bool isTearOffUsed =
|
||||
tearOffIsBound && shaker.isMemberUsed(tearOffReference!.asMember);
|
||||
|
@ -2052,17 +2052,17 @@ class _TreeShakerPass2 extends RemovingTransformer {
|
|||
name: descriptor.name,
|
||||
kind: descriptor.kind,
|
||||
isStatic: descriptor.isStatic,
|
||||
member: descriptor.member,
|
||||
tearOff: null);
|
||||
memberReference: descriptor.memberReference,
|
||||
tearOffReference: null);
|
||||
}
|
||||
node.members[writeIndex++] = descriptor;
|
||||
node.memberDescriptors[writeIndex++] = descriptor;
|
||||
}
|
||||
}
|
||||
node.members.length = writeIndex;
|
||||
node.memberDescriptors.length = writeIndex;
|
||||
|
||||
// We only retain the extension type declaration if at least one member is
|
||||
// retained.
|
||||
assert(node.members.isNotEmpty);
|
||||
assert(node.memberDescriptors.isNotEmpty);
|
||||
return node;
|
||||
}
|
||||
return removalSentinel!;
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace kernel {
|
|||
// package:kernel/binary.md.
|
||||
|
||||
static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
|
||||
static const uint32_t kSupportedKernelFormatVersion = 111;
|
||||
static const uint32_t kSupportedKernelFormatVersion = 112;
|
||||
|
||||
// Keep in sync with package:kernel/lib/binary/tag.dart
|
||||
#define KERNEL_TAG_LIST(V) \
|
||||
|
|
|
@ -1002,6 +1002,14 @@ void KernelLoader::FinishTopLevelClassLoading(
|
|||
helper_.SkipStringReference(); // skip representation name.
|
||||
helper_.SkipListOfDartTypes(); // skip implements types.
|
||||
|
||||
// Skip extension type procedures.
|
||||
const intptr_t extension_type_procedure_count =
|
||||
helper_.ReadListLength(); // read list length.
|
||||
for (intptr_t i = 0; i < extension_type_procedure_count; ++i) {
|
||||
ProcedureHelper procedure_helper(&helper_);
|
||||
procedure_helper.ReadUntilExcluding(ProcedureHelper::kEnd);
|
||||
}
|
||||
|
||||
const intptr_t extension_type_member_count = helper_.ReadListLength();
|
||||
for (intptr_t j = 0; j < extension_type_member_count; ++j) {
|
||||
helper_.SkipName(); // skip name.
|
||||
|
|
Loading…
Reference in a new issue