[cfe] Add ClassMember.memberKind and .getTearOff This adds the functionality to ClassMember that enables us to fully compute the ExtensionTypeAccessTarget. Change-Id: I62dd5e24f664c2edd70c2fe794f66595cc017173 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/332427 Commit-Queue: Johnni Winther <johnniwinther@google.com> Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
diff --git a/pkg/front_end/lib/src/fasta/builder/member_builder.dart b/pkg/front_end/lib/src/fasta/builder/member_builder.dart index d01f095..de4f4ce 100644 --- a/pkg/front_end/lib/src/fasta/builder/member_builder.dart +++ b/pkg/front_end/lib/src/fasta/builder/member_builder.dart
@@ -255,6 +255,12 @@ bool get hasDeclarations => false; @override + bool get forSetter => memberKind == ClassMemberKind.Setter; + + @override + bool get isProperty => memberKind != ClassMemberKind.Method; + + @override List<ClassMember> get declarations => throw new UnsupportedError("$runtimeType.declarations");
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_member_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_member_builder.dart index 5008045..365d6ac 100644 --- a/pkg/front_end/lib/src/fasta/dill/dill_member_builder.dart +++ b/pkg/front_end/lib/src/fasta/dill/dill_member_builder.dart
@@ -22,7 +22,8 @@ import '../builder/member_builder.dart'; import '../builder/procedure_builder.dart'; -import '../kernel/hierarchy/class_member.dart' show ClassMember; +import '../kernel/hierarchy/class_member.dart' + show ClassMember, ClassMemberKind; import '../kernel/hierarchy/members_builder.dart' show ClassMembersBuilder; import '../kernel/member_covariance.dart'; @@ -93,12 +94,18 @@ @override List<ClassMember> get localMembers => _localMembers ??= isSetter ? const <ClassMember>[] - : <ClassMember>[new DillClassMember(this, forSetter: false)]; + : <ClassMember>[ + new DillClassMember( + this, + member is Field || isGetter + ? ClassMemberKind.Getter + : ClassMemberKind.Method) + ]; @override List<ClassMember> get localSetters => _localSetters ??= isSetter || member is Field && member.hasSetter - ? <ClassMember>[new DillClassMember(this, forSetter: true)] + ? <ClassMember>[new DillClassMember(this, ClassMemberKind.Setter)] : const <ClassMember>[]; @override @@ -268,9 +275,9 @@ Covariance? _covariance; @override - final bool forSetter; + final ClassMemberKind memberKind; - DillClassMember(this.memberBuilder, {required this.forSetter}); + DillClassMember(this.memberBuilder, this.memberKind); @override bool get isSourceDeclaration => false; @@ -295,12 +302,6 @@ } @override - bool get isProperty => - memberBuilder.kind == null || - memberBuilder.kind == ProcedureKind.Getter || - memberBuilder.kind == ProcedureKind.Setter; - - @override bool get isSynthesized { Member member = memberBuilder.member; return member is Procedure && member.isSynthetic; @@ -310,6 +311,12 @@ Member getMember(ClassMembersBuilder membersBuilder) => memberBuilder.member; @override + Member? getTearOff(ClassMembersBuilder membersBuilder) { + Member? readTarget = memberBuilder.readTarget; + return readTarget != memberBuilder.invokeTarget ? readTarget : null; + } + + @override Covariance getCovariance(ClassMembersBuilder membersBuilder) { return _covariance ??= new Covariance.fromMember(memberBuilder.member, forSetter: forSetter);
diff --git a/pkg/front_end/lib/src/fasta/kernel/hierarchy/class_member.dart b/pkg/front_end/lib/src/fasta/kernel/hierarchy/class_member.dart index f9eb7e7..40e8326 100644 --- a/pkg/front_end/lib/src/fasta/kernel/hierarchy/class_member.dart +++ b/pkg/front_end/lib/src/fasta/kernel/hierarchy/class_member.dart
@@ -22,6 +22,12 @@ import '../member_covariance.dart'; import 'members_builder.dart'; +enum ClassMemberKind { + Method, + Getter, + Setter, +} + abstract class ClassMember { Name get name; bool get isStatic; @@ -33,6 +39,8 @@ bool get isConst; bool get forSetter; + ClassMemberKind get memberKind; + /// Returns `true` if this member corresponds to a declaration in the source /// code. bool get isSourceDeclaration; @@ -43,6 +51,12 @@ /// Computes the [Member] node resulting from this class member. Member getMember(ClassMembersBuilder membersBuilder); + /// Computes the tear off [Member] node resulting from this class member, if + /// this is different from the [Member] returned from [getMember]. + /// + /// Returns `null` if this class member does not have a tear off. + Member? getTearOff(ClassMembersBuilder membersBuilder); + /// Returns the member [Covariance] for this class member. Covariance getCovariance(ClassMembersBuilder membersBuilder); @@ -154,13 +168,15 @@ final Name name; @override - final bool forSetter; + final ClassMemberKind memberKind; + + SynthesizedMember(this.name, this.memberKind); @override - final bool isProperty; + bool get forSetter => memberKind == ClassMemberKind.Setter; - SynthesizedMember(this.name, - {required this.forSetter, required this.isProperty}); + @override + bool get isProperty => memberKind != ClassMemberKind.Method; @override List<ClassMember> get declarations => throw new UnimplementedError(); @@ -206,6 +222,13 @@ @override bool get isExtensionTypeMember => false; + + @override + Member? getTearOff(ClassMembersBuilder membersBuilder) { + // Ensure member is computed. + getMember(membersBuilder); + return null; + } } /// Class member for a set of interface members. @@ -316,15 +339,14 @@ ClassMember? canonicalMember, ClassMember? mixedInMember, ClassMember? noSuchMethodTarget, - required bool isProperty, - required bool forSetter, + required ClassMemberKind memberKind, required bool shouldModifyKernel}) : this._superClassMember = superClassMember, this._canonicalMember = canonicalMember, this._mixedInMember = mixedInMember, this._noSuchMethodTarget = noSuchMethodTarget, this._shouldModifyKernel = shouldModifyKernel, - super(name, isProperty: isProperty, forSetter: forSetter); + super(name, memberKind); @override bool get hasDeclarations => true; @@ -540,9 +562,8 @@ InheritedClassMemberImplementsInterface(this.classBuilder, Name name, {required this.inheritedClassMember, required this.implementedInterfaceMember, - required bool isProperty, - required bool forSetter}) - : super(name, isProperty: isProperty, forSetter: forSetter); + required ClassMemberKind memberKind}) + : super(name, memberKind); @override DeclarationBuilder get declarationBuilder => classBuilder; @@ -713,11 +734,9 @@ SynthesizedNonExtensionTypeMember( this.extensionTypeDeclarationBuilder, Name name, this.declarations, - {required bool isProperty, - required bool forSetter, - required bool shouldModifyKernel}) + {required ClassMemberKind memberKind, required bool shouldModifyKernel}) : this._shouldModifyKernel = shouldModifyKernel, - super(name, isProperty: isProperty, forSetter: forSetter); + super(name, memberKind); @override DeclarationBuilder get declarationBuilder => extensionTypeDeclarationBuilder;
diff --git a/pkg/front_end/lib/src/fasta/kernel/hierarchy/extension_type_members.dart b/pkg/front_end/lib/src/fasta/kernel/hierarchy/extension_type_members.dart index ff43c6e3..8349926 100644 --- a/pkg/front_end/lib/src/fasta/kernel/hierarchy/extension_type_members.dart +++ b/pkg/front_end/lib/src/fasta/kernel/hierarchy/extension_type_members.dart
@@ -972,8 +972,7 @@ extensionTypeDeclarationBuilder, name, _implementedNonExtensionTypeMembers, - isProperty: _definingMember.isProperty, - forSetter: _definingMember.forSetter, + memberKind: _definingMember.memberKind, shouldModifyKernel: builder.shouldModifyKernel); builder._membersBuilder.registerMemberComputation(classMember); return nonExtensionTypeMemberMap[name] = classMember;
diff --git a/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_builder.dart b/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_builder.dart index 378cecc..6e5322c 100644 --- a/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_builder.dart +++ b/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_builder.dart
@@ -171,11 +171,18 @@ Member? getExtensionTypeMember( ExtensionTypeDeclaration extensionTypeDeclaration, Name name, {bool setter = false}) { - return getNodeFromExtensionTypeDeclaration(extensionTypeDeclaration) - .getMember(name, setter) + return getExtensionTypeClassMember(extensionTypeDeclaration, name, + setter: setter) ?.getMember(this); } + ClassMember? getExtensionTypeClassMember( + ExtensionTypeDeclaration extensionTypeDeclaration, Name name, + {bool setter = false}) { + return getNodeFromExtensionTypeDeclaration(extensionTypeDeclaration) + .getMember(name, setter); + } + @override Member? getDispatchTarget(Class cls, Name name, {bool setter = false}) { return getNodeFromClass(cls)
diff --git a/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart b/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart index 2578513..fad8b34 100644 --- a/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart +++ b/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart
@@ -2023,8 +2023,7 @@ canonicalMember: _mixedInMember, mixedInMember: _mixedInMember, noSuchMethodTarget: noSuchMethodTarget, - isProperty: _definingMember.isProperty, - forSetter: _definingMember.forSetter, + memberKind: _definingMember.memberKind, shouldModifyKernel: builder.shouldModifyKernel); builder._membersBuilder.registerMemberComputation(interfaceMember); @@ -2058,8 +2057,7 @@ classBuilder, name, inheritedClassMember: _extendedMember, implementedInterfaceMember: interfaceMember, - forSetter: _definingMember.forSetter, - isProperty: _definingMember.isProperty); + memberKind: _definingMember.memberKind); builder._membersBuilder.registerMemberComputation(classMember); if (!classBuilder.isAbstract) { overrides.registerInheritedImplements( @@ -2153,8 +2151,7 @@ // is the defining member. canonicalMember: _mixedInMember, mixedInMember: _mixedInMember, - isProperty: _definingMember.isProperty, - forSetter: _definingMember.forSetter, + memberKind: _definingMember.memberKind, shouldModifyKernel: builder.shouldModifyKernel); builder._membersBuilder.registerMemberComputation(interfaceMember); @@ -2173,8 +2170,7 @@ classBuilder, name, inheritedClassMember: _mixedInMember, implementedInterfaceMember: interfaceMember, - forSetter: _definingMember.forSetter, - isProperty: _definingMember.isProperty); + memberKind: _definingMember.memberKind); builder._membersBuilder.registerMemberComputation(classMember); if (!classBuilder.isAbstract) { @@ -2278,8 +2274,7 @@ // _because_ it is the defining member. canonicalMember: _declaredMember, noSuchMethodTarget: noSuchMethodTarget, - isProperty: _definingMember.isProperty, - forSetter: _definingMember.forSetter, + memberKind: _definingMember.memberKind, shouldModifyKernel: builder.shouldModifyKernel); builder._membersBuilder.registerMemberComputation(interfaceMember); } @@ -2311,8 +2306,7 @@ classBuilder, name, inheritedClassMember: _extendedMember, implementedInterfaceMember: interfaceMember, - forSetter: _definingMember.forSetter, - isProperty: _definingMember.isProperty); + memberKind: _definingMember.memberKind); builder._membersBuilder.registerMemberComputation(classMember); if (!classBuilder.isAbstract && noSuchMethodTarget == null) { @@ -2448,8 +2442,7 @@ classBuilder, name, interfaceMembers.toList(), superClassMember: _extendedMember, noSuchMethodTarget: noSuchMethodTarget, - isProperty: _definingMember.isProperty, - forSetter: _definingMember.forSetter, + memberKind: _definingMember.memberKind, shouldModifyKernel: builder.shouldModifyKernel); builder._membersBuilder.registerMemberComputation(interfaceMember); } @@ -2493,8 +2486,7 @@ classBuilder, name, inheritedClassMember: _extendedMember, implementedInterfaceMember: interfaceMember, - isProperty: _definingMember.isProperty, - forSetter: _definingMember.forSetter); + memberKind: _definingMember.memberKind); builder._membersBuilder.registerMemberComputation(classMember); if (!classBuilder.isAbstract && noSuchMethodTarget == null) { /// class Super { @@ -2519,8 +2511,7 @@ interfaceMember = new SynthesizedInterfaceMember( classBuilder, name, [_extendedMember], superClassMember: _extendedMember, - isProperty: _definingMember.isProperty, - forSetter: _definingMember.forSetter, + memberKind: _definingMember.memberKind, shouldModifyKernel: builder.shouldModifyKernel); builder._membersBuilder.registerMemberComputation(interfaceMember); @@ -2531,8 +2522,7 @@ classBuilder, name, inheritedClassMember: _extendedMember, implementedInterfaceMember: interfaceMember, - isProperty: _definingMember.isProperty, - forSetter: _definingMember.forSetter); + memberKind: _definingMember.memberKind); builder._membersBuilder.registerMemberComputation(classMember); } } else if (_implementedMembers != null) { @@ -2589,8 +2579,7 @@ interfaceMember = new SynthesizedInterfaceMember( classBuilder, name, interfaceMembers.toList(), noSuchMethodTarget: noSuchMethodTarget, - isProperty: _definingMember.isProperty, - forSetter: _definingMember.forSetter, + memberKind: _definingMember.memberKind, shouldModifyKernel: builder.shouldModifyKernel); builder._membersBuilder.registerMemberComputation(interfaceMember); }
diff --git a/pkg/front_end/lib/src/fasta/source/source_field_builder.dart b/pkg/front_end/lib/src/fasta/source/source_field_builder.dart index d83c204..7ca8c3e 100644 --- a/pkg/front_end/lib/src/fasta/source/source_field_builder.dart +++ b/pkg/front_end/lib/src/fasta/source/source_field_builder.dart
@@ -782,12 +782,16 @@ @override List<ClassMember> getLocalMembers(SourceFieldBuilder fieldBuilder) => - <ClassMember>[new SourceFieldMember(fieldBuilder, forSetter: false)]; + <ClassMember>[ + new SourceFieldMember(fieldBuilder, ClassMemberKind.Getter) + ]; @override List<ClassMember> getLocalSetters(SourceFieldBuilder fieldBuilder) => fieldBuilder.isAssignable - ? <ClassMember>[new SourceFieldMember(fieldBuilder, forSetter: true)] + ? <ClassMember>[ + new SourceFieldMember(fieldBuilder, ClassMemberKind.Setter) + ] : const <ClassMember>[]; @override @@ -818,9 +822,9 @@ Covariance? _covariance; @override - final bool forSetter; + final ClassMemberKind memberKind; - SourceFieldMember(this.memberBuilder, {required this.forSetter}); + SourceFieldMember(this.memberBuilder, this.memberKind); @override void inferType(ClassMembersBuilder membersBuilder) { @@ -839,6 +843,13 @@ } @override + Member? getTearOff(ClassMembersBuilder membersBuilder) { + // Ensure field type is computed. + getMember(membersBuilder); + return null; + } + + @override Covariance getCovariance(ClassMembersBuilder membersBuilder) { return _covariance ??= forSetter ? new Covariance.fromMember(getMember(membersBuilder), @@ -850,9 +861,6 @@ bool get isSourceDeclaration => true; @override - bool get isProperty => true; - - @override bool get isSynthesized => memberBuilder.isSynthesized; @override @@ -1210,15 +1218,23 @@ List<ClassMember> getLocalMembers(SourceFieldBuilder fieldBuilder) { List<ClassMember> list = <ClassMember>[ new _SynthesizedFieldClassMember(fieldBuilder, field, field.name, - _SynthesizedFieldMemberKind.LateField, + _SynthesizedFieldMemberKind.LateField, ClassMemberKind.Getter, isInternalImplementation: true), - new _SynthesizedFieldClassMember(fieldBuilder, _lateGetter, - fieldBuilder.memberName, _SynthesizedFieldMemberKind.LateGetterSetter, + new _SynthesizedFieldClassMember( + fieldBuilder, + _lateGetter, + fieldBuilder.memberName, + _SynthesizedFieldMemberKind.LateGetterSetter, + ClassMemberKind.Getter, isInternalImplementation: false) ]; if (_lateIsSetField != null) { - list.add(new _SynthesizedFieldClassMember(fieldBuilder, _lateIsSetField!, - _lateIsSetField!.name, _SynthesizedFieldMemberKind.LateIsSet, + list.add(new _SynthesizedFieldClassMember( + fieldBuilder, + _lateIsSetField!, + _lateIsSetField!.name, + _SynthesizedFieldMemberKind.LateIsSet, + ClassMemberKind.Getter, isInternalImplementation: true)); } return list; @@ -1228,18 +1244,26 @@ List<ClassMember> getLocalSetters(SourceFieldBuilder fieldBuilder) { List<ClassMember> list = <ClassMember>[ new _SynthesizedFieldClassMember(fieldBuilder, field, field.name, - _SynthesizedFieldMemberKind.LateField, - forSetter: true, isInternalImplementation: true), + _SynthesizedFieldMemberKind.LateField, ClassMemberKind.Setter, + isInternalImplementation: true), ]; if (_lateIsSetField != null) { - list.add(new _SynthesizedFieldClassMember(fieldBuilder, _lateIsSetField!, - _lateIsSetField!.name, _SynthesizedFieldMemberKind.LateIsSet, - forSetter: true, isInternalImplementation: true)); + list.add(new _SynthesizedFieldClassMember( + fieldBuilder, + _lateIsSetField!, + _lateIsSetField!.name, + _SynthesizedFieldMemberKind.LateIsSet, + ClassMemberKind.Setter, + isInternalImplementation: true)); } if (_lateSetter != null) { - list.add(new _SynthesizedFieldClassMember(fieldBuilder, _lateSetter!, - fieldBuilder.memberName, _SynthesizedFieldMemberKind.LateGetterSetter, - forSetter: true, isInternalImplementation: false)); + list.add(new _SynthesizedFieldClassMember( + fieldBuilder, + _lateSetter!, + fieldBuilder.memberName, + _SynthesizedFieldMemberKind.LateGetterSetter, + ClassMemberKind.Setter, + isInternalImplementation: false)); } return list; } @@ -1539,14 +1563,14 @@ Covariance? _covariance; @override - final bool forSetter; - - @override final bool isInternalImplementation; + @override + final ClassMemberKind memberKind; + _SynthesizedFieldClassMember( - this.fieldBuilder, this._member, this._name, this._kind, - {this.forSetter = false, required this.isInternalImplementation}); + this.fieldBuilder, this._member, this._name, this._kind, this.memberKind, + {required this.isInternalImplementation}); @override Member getMember(ClassMembersBuilder membersBuilder) { @@ -1555,6 +1579,13 @@ } @override + Member? getTearOff(ClassMembersBuilder membersBuilder) { + // Ensure field type is computed. + getMember(membersBuilder); + return null; + } + + @override Covariance getCovariance(ClassMembersBuilder membersBuilder) { return _covariance ??= new Covariance.fromMember(getMember(membersBuilder), forSetter: forSetter); @@ -1574,7 +1605,10 @@ bool get isSourceDeclaration => true; @override - bool get isProperty => isField || isGetter || isSetter; + bool get forSetter => memberKind == ClassMemberKind.Setter; + + @override + bool get isProperty => memberKind != ClassMemberKind.Method; @override DeclarationBuilder get declarationBuilder => fieldBuilder.declarationBuilder!; @@ -1970,7 +2004,7 @@ _getter, fieldBuilder.memberName, _SynthesizedFieldMemberKind.AbstractExternalGetterSetter, - forSetter: false, + ClassMemberKind.Getter, isInternalImplementation: false) ]; @@ -1983,7 +2017,7 @@ _setter!, fieldBuilder.memberName, _SynthesizedFieldMemberKind.AbstractExternalGetterSetter, - forSetter: true, + ClassMemberKind.Setter, isInternalImplementation: false) ] : const <ClassMember>[]; @@ -2117,7 +2151,7 @@ _getter, fieldBuilder.memberName, _SynthesizedFieldMemberKind.RepresentationField, - forSetter: false, + ClassMemberKind.Getter, isInternalImplementation: false) ];
diff --git a/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart b/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart index 1ed1904..2a3d416 100644 --- a/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart +++ b/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart
@@ -500,12 +500,17 @@ @override List<ClassMember> get localMembers => _localMembers ??= isSetter ? const <ClassMember>[] - : <ClassMember>[new SourceProcedureMember(this)]; + : <ClassMember>[ + new SourceProcedureMember( + this, isGetter ? ClassMemberKind.Getter : ClassMemberKind.Method) + ]; @override List<ClassMember> get localSetters => _localSetters ??= isSetter && !isConflictingSetter - ? <ClassMember>[new SourceProcedureMember(this)] + ? <ClassMember>[ + new SourceProcedureMember(this, ClassMemberKind.Setter) + ] : const <ClassMember>[]; @override @@ -670,9 +675,12 @@ @override final SourceProcedureBuilder memberBuilder; + @override + final ClassMemberKind memberKind; + Covariance? _covariance; - SourceProcedureMember(this.memberBuilder); + SourceProcedureMember(this.memberBuilder, this.memberKind); @override bool get isSourceDeclaration => true; @@ -694,20 +702,20 @@ } @override + Member? getTearOff(ClassMembersBuilder membersBuilder) { + // Ensure function type is computed. + getMember(membersBuilder); + Member? readTarget = memberBuilder.readTarget; + return readTarget != memberBuilder.invokeTarget ? readTarget : null; + } + + @override Covariance getCovariance(ClassMembersBuilder membersBuilder) { return _covariance ??= new Covariance.fromMember(getMember(membersBuilder), forSetter: forSetter); } @override - bool get forSetter => isSetter; - - @override - bool get isProperty => - memberBuilder.kind == ProcedureKind.Getter || - memberBuilder.kind == ProcedureKind.Setter; - - @override bool isSameDeclaration(ClassMember other) { return other is SourceProcedureMember && memberBuilder == other.memberBuilder;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart index 0e61b0c..89d492b 100644 --- a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart +++ b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart
@@ -41,6 +41,7 @@ SpreadMapEntry, convertToElement; import '../kernel/exhaustiveness.dart'; +import '../kernel/hierarchy/class_member.dart'; import '../kernel/implicit_type_argument.dart' show ImplicitTypeArgument; import '../kernel/internal_ast.dart'; import '../kernel/late_lowering.dart' as late_lowering; @@ -673,7 +674,7 @@ case ObjectAccessTargetKind.extensionMember: case ObjectAccessTargetKind.extensionTypeMember: if (callMember.tearoffTarget != null && - callMember.declarationMethodKind == ProcedureKind.Method) { + callMember.declarationMethodKind == ClassMemberKind.Method) { operandType = callMember.getGetterType(this); operand = new StaticInvocation( callMember.tearoffTarget as Procedure, @@ -1063,7 +1064,7 @@ ensureAssignableResult(receiverType, receiverResult).expression; ObjectAccessTarget target = new ExtensionAccessTarget(receiverType, - node.target, null, ProcedureKind.Setter, extensionTypeArguments); + node.target, null, ClassMemberKind.Setter, extensionTypeArguments); DartType valueType = target.getSetterType(this); @@ -1145,7 +1146,7 @@ ObjectAccessTarget readTarget = node.getter == null ? const ObjectAccessTarget.missing() : new ExtensionAccessTarget(receiverType, node.getter!, null, - ProcedureKind.Getter, extensionTypeArguments); + ClassMemberKind.Getter, extensionTypeArguments); DartType readType = readTarget.getGetterType(this); @@ -1168,7 +1169,7 @@ ObjectAccessTarget writeTarget = node.setter == null ? const ObjectAccessTarget.missing() : new ExtensionAccessTarget(receiverType, node.setter!, null, - ProcedureKind.Setter, extensionTypeArguments); + ClassMemberKind.Setter, extensionTypeArguments); DartType valueType = writeTarget.getSetterType(this); @@ -5459,7 +5460,7 @@ } ObjectAccessTarget target = new ExtensionAccessTarget(receiverType, - node.setter, null, ProcedureKind.Operator, extensionTypeArguments); + node.setter, null, ClassMemberKind.Method, extensionTypeArguments); DartType indexType = target.getIndexKeyType(this); DartType valueType = target.getIndexSetValueType(this); @@ -5864,14 +5865,14 @@ ObjectAccessTarget readTarget = node.getter != null ? new ExtensionAccessTarget(receiverType, node.getter!, null, - ProcedureKind.Operator, extensionTypeArguments) + ClassMemberKind.Method, extensionTypeArguments) : const ObjectAccessTarget.missing(); DartType readIndexType = readTarget.getIndexKeyType(this); ObjectAccessTarget writeTarget = node.setter != null ? new ExtensionAccessTarget(receiverType, node.setter!, null, - ProcedureKind.Operator, extensionTypeArguments) + ClassMemberKind.Method, extensionTypeArguments) : const ObjectAccessTarget.missing(); DartType writeIndexType = writeTarget.getIndexKeyType(this); @@ -6178,7 +6179,7 @@ case ObjectAccessTargetKind.nullableExtensionMember: case ObjectAccessTargetKind.extensionTypeMember: case ObjectAccessTargetKind.nullableExtensionTypeMember: - assert(binaryTarget.declarationMethodKind != ProcedureKind.Setter); + assert(binaryTarget.declarationMethodKind != ClassMemberKind.Setter); binary = new StaticInvocation( binaryTarget.member as Procedure, new Arguments(<Expression>[ @@ -6323,7 +6324,7 @@ case ObjectAccessTargetKind.nullableExtensionMember: case ObjectAccessTargetKind.extensionTypeMember: case ObjectAccessTargetKind.nullableExtensionTypeMember: - assert(unaryTarget.declarationMethodKind != ProcedureKind.Setter); + assert(unaryTarget.declarationMethodKind != ClassMemberKind.Setter); unary = new StaticInvocation( unaryTarget.member as Procedure, new Arguments(<Expression>[ @@ -6583,7 +6584,7 @@ case ObjectAccessTargetKind.nullableExtensionMember: case ObjectAccessTargetKind.extensionTypeMember: case ObjectAccessTargetKind.nullableExtensionTypeMember: - assert(writeTarget.declarationMethodKind != ProcedureKind.Setter); + assert(writeTarget.declarationMethodKind != ClassMemberKind.Setter); write = new StaticInvocation( writeTarget.member as Procedure, new Arguments(<Expression>[receiver, index, value], @@ -7307,7 +7308,7 @@ ObjectAccessTarget readTarget = node.getter != null ? new ExtensionAccessTarget(receiverType, node.getter!, null, - ProcedureKind.Operator, extensionTypeArguments) + ClassMemberKind.Method, extensionTypeArguments) : const ObjectAccessTarget.missing(); Expression receiver = @@ -7368,7 +7369,7 @@ ObjectAccessTarget writeTarget = node.setter != null ? new ExtensionAccessTarget(receiverType, node.setter!, null, - ProcedureKind.Operator, extensionTypeArguments) + ClassMemberKind.Method, extensionTypeArguments) : const ObjectAccessTarget.missing(); DartType writeIndexType = writeTarget.getIndexKeyType(this);
diff --git a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart index ef35c35..a7e81b1 100644 --- a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart +++ b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart
@@ -35,6 +35,7 @@ import '../builder/member_builder.dart'; import '../fasta_codes.dart'; import '../kernel/constructor_tearoff_lowering.dart'; +import '../kernel/hierarchy/class_member.dart'; import '../kernel/internal_ast.dart'; import '../kernel/kernel_helper.dart'; import '../kernel/type_algorithms.dart' show hasAnyTypeVariables; @@ -967,11 +968,12 @@ ExtensionType extensionType, Name name, int fileOffset, {required bool isSetter, required bool isReceiverTypePotentiallyNullable}) { - Member? member = _getExtensionTypeMember( + ClassMember? classMember = _getExtensionTypeMember( extensionType.extensionTypeDeclaration, name, isSetter); - if (member == null) { + if (classMember == null) { return null; } + Member? member = classMember.getMember(engine.membersBuilder); if (member is Procedure && member.stubKind == ProcedureStubKind.RepresentationField) { return new ObjectAccessTarget.extensionTypeRepresentation( @@ -979,50 +981,18 @@ isPotentiallyNullable: isReceiverTypePotentiallyNullable); } if (member.isExtensionTypeMember) { - // TODO(johnniwinther): Derive this from the [ClassMember]. - ExtensionTypeMemberDescriptor? memberDescriptor; - ExtensionTypeDeclaration? extensionTypeDeclaration; - outer: - for (ExtensionTypeDeclaration declaration - in member.enclosingLibrary.extensionTypeDeclarations) { - for (ExtensionTypeMemberDescriptor descriptor - in declaration.memberDescriptors) { - if (descriptor.memberReference == member.reference) { - extensionTypeDeclaration = declaration; - memberDescriptor = descriptor; - break outer; - } - } - } - assert(extensionTypeDeclaration != null, - "No enclosing extension type declaration found for $member."); - assert(memberDescriptor != null, - "No extension type member descriptor found for $member."); - ProcedureKind kind; - switch (memberDescriptor!.kind) { - case ExtensionTypeMemberKind.Method: - kind = ProcedureKind.Method; - case ExtensionTypeMemberKind.Operator: - kind = ProcedureKind.Operator; - case ExtensionTypeMemberKind.Getter: - kind = ProcedureKind.Getter; - case ExtensionTypeMemberKind.Setter: - kind = ProcedureKind.Setter; - case ExtensionTypeMemberKind.Constructor: - case ExtensionTypeMemberKind.Factory: - case ExtensionTypeMemberKind.Field: - case ExtensionTypeMemberKind.RedirectingFactory: - throw new UnsupportedError("Unexpected extension type member kind: " - "${memberDescriptor.kind}."); - } - + ExtensionTypeDeclarationBuilder extensionTypeDeclarationBuilder = + classMember.declarationBuilder as ExtensionTypeDeclarationBuilder; + ExtensionTypeDeclaration extensionTypeDeclaration = + extensionTypeDeclarationBuilder.extensionTypeDeclaration; + ClassMemberKind kind = classMember.memberKind; return new ObjectAccessTarget.extensionTypeMember( receiverType, - memberDescriptor.memberReference.asMember, - memberDescriptor.tearOffReference?.asMember, + member, + classMember.getTearOff(engine.membersBuilder), kind, hierarchyBuilder.getTypeArgumentsAsInstanceOf( - extensionType, extensionTypeDeclaration!)!, + extensionType, extensionTypeDeclaration)!, isPotentiallyNullable: isReceiverTypePotentiallyNullable); } else { return new ObjectAccessTarget.interfaceMember(receiverType, member, @@ -1117,16 +1087,31 @@ receiverType, setter ? thisBuilder.writeTarget! : thisBuilder.readTarget!, thisBuilder.readTarget, - setter ? ProcedureKind.Setter : ProcedureKind.Getter, + setter ? ClassMemberKind.Setter : ClassMemberKind.Getter, inferredTypeArguments, isPotentiallyNullable: isPotentiallyNullableAccess); } } else { + ClassMemberKind classMemberKind; + switch (thisBuilder.kind) { + case ProcedureKind.Method: + case ProcedureKind.Operator: + classMemberKind = ClassMemberKind.Method; + case ProcedureKind.Getter: + classMemberKind = ClassMemberKind.Getter; + case ProcedureKind.Setter: + classMemberKind = ClassMemberKind.Setter; + case ProcedureKind.Factory: + case null: + throw new UnsupportedError( + "Unexpected procedure kind ${thisBuilder.kind} on " + "builder $thisBuilder."); + } target = new ObjectAccessTarget.extensionMember( receiverType, setter ? thisBuilder.writeTarget! : thisBuilder.invokeTarget!, thisBuilder.readTarget, - thisBuilder.kind!, + classMemberKind, inferredTypeArguments, isPotentiallyNullable: isPotentiallyNullableAccess); } @@ -2458,7 +2443,7 @@ DartType calleeType = target.getGetterType(this); FunctionType functionType = target.getFunctionType(this); - if (target.declarationMethodKind == ProcedureKind.Getter) { + if (target.declarationMethodKind == ClassMemberKind.Getter) { StaticInvocation staticInvocation = transformExtensionMethodInvocation( fileOffset, target, receiver, new Arguments.empty()); ExpressionInferenceResult result = inferMethodInvocation( @@ -3828,13 +3813,16 @@ return TypeInferenceEngine.resolveInferenceNode(member, hierarchyBuilder); } - Member? _getExtensionTypeMember( + ClassMember? _getExtensionTypeMember( ExtensionTypeDeclaration extensionTypeDeclaration, Name name, bool setter) { - Member? member = engine.membersBuilder - .getExtensionTypeMember(extensionTypeDeclaration, name, setter: setter); - return TypeInferenceEngine.resolveInferenceNode(member, hierarchyBuilder); + ClassMember? member = engine.membersBuilder.getExtensionTypeClassMember( + extensionTypeDeclaration, name, + setter: setter); + TypeInferenceEngine.resolveInferenceNode( + member?.getMember(engine.membersBuilder), hierarchyBuilder); + return member; } bool _isLoweredSetLiteral(Expression expression) { @@ -4093,7 +4081,7 @@ case ObjectAccessTargetKind.extensionTypeMember: case ObjectAccessTargetKind.nullableExtensionTypeMember: switch (readTarget.declarationMethodKind) { - case ProcedureKind.Getter: + case ClassMemberKind.Getter: read = new StaticInvocation( readTarget.member as Procedure, new ArgumentsImpl(<Expression>[ @@ -4102,7 +4090,7 @@ ..fileOffset = fileOffset) ..fileOffset = fileOffset; break; - case ProcedureKind.Method: + case ClassMemberKind.Method: read = new StaticInvocation( readTarget.tearoffTarget as Procedure, new Arguments(<Expression>[ @@ -4112,9 +4100,7 @@ ..fileOffset = fileOffset; readResult = instantiateTearOff(readType, typeContext, read); break; - case ProcedureKind.Setter: - case ProcedureKind.Factory: - case ProcedureKind.Operator: + case ClassMemberKind.Setter: unhandled('$readTarget', "inferPropertyGet", -1, null); } break;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/object_access_target.dart b/pkg/front_end/lib/src/fasta/type_inference/object_access_target.dart index b3cc01c..46f947c 100644 --- a/pkg/front_end/lib/src/fasta/type_inference/object_access_target.dart +++ b/pkg/front_end/lib/src/fasta/type_inference/object_access_target.dart
@@ -8,6 +8,7 @@ import 'package:kernel/type_environment.dart' show SubtypeCheckMode; import '../builder/member_builder.dart'; +import '../kernel/hierarchy/class_member.dart'; import '../problems.dart' show unexpected; import 'inference_visitor_base.dart'; import 'type_schema_environment.dart'; @@ -122,7 +123,7 @@ DartType receiverType, Member member, Member? tearoffTarget, - ProcedureKind kind, + ClassMemberKind kind, List<DartType> inferredTypeArguments, {bool isPotentiallyNullable}) = ExtensionAccessTarget; @@ -131,7 +132,7 @@ DartType receiverType, Member member, Member? tearoffTarget, - ProcedureKind kind, + ClassMemberKind kind, List<DartType> extensionTypeArguments, {bool isPotentiallyNullable}) = ExtensionTypeAccessTarget; @@ -295,7 +296,7 @@ /// This is need because getters, setters, and methods are converted into /// top level methods, but access and invocation should still be treated as /// if they are the original procedure kind. - ProcedureKind get declarationMethodKind => + ClassMemberKind get declarationMethodKind => throw new UnsupportedError('ObjectAccessTarget.declarationMethodKind'); /// Returns type arguments for the type parameters of an extension or @@ -695,7 +696,7 @@ @override final Member? tearoffTarget; @override - final ProcedureKind declarationMethodKind; + final ClassMemberKind declarationMethodKind; @override final List<DartType> receiverTypeArguments; @@ -709,19 +710,17 @@ @override FunctionType getFunctionType(InferenceVisitorBase base) { switch (declarationMethodKind) { - case ProcedureKind.Method: - case ProcedureKind.Operator: + case ClassMemberKind.Method: FunctionType functionType = member.function! .computeFunctionType(base.libraryBuilder.nonNullable); if (!base.isNonNullableByDefault) { functionType = legacyErasure(functionType) as FunctionType; } return functionType; - case ProcedureKind.Getter: + case ClassMemberKind.Getter: // TODO(johnniwinther): Handle implicit .call on extension getter. return _getFunctionType(base, member.function!.returnType); - case ProcedureKind.Setter: - case ProcedureKind.Factory: + case ClassMemberKind.Setter: throw unexpected('$this', 'getFunctionType', -1, null); } } @@ -729,8 +728,7 @@ @override DartType getGetterType(InferenceVisitorBase base) { switch (declarationMethodKind) { - case ProcedureKind.Method: - case ProcedureKind.Operator: + case ClassMemberKind.Method: FunctionType functionType = member.function! .computeFunctionType(base.libraryBuilder.nonNullable); List<StructuralParameter> extensionTypeParameters = functionType @@ -753,7 +751,7 @@ resultType = legacyErasure(resultType); } return resultType; - case ProcedureKind.Getter: + case ClassMemberKind.Getter: FunctionType functionType = member.function! .computeFunctionType(base.libraryBuilder.nonNullable); List<StructuralParameter> extensionTypeParameters = functionType @@ -768,8 +766,7 @@ resultType = legacyErasure(resultType); } return resultType; - case ProcedureKind.Setter: - case ProcedureKind.Factory: + case ClassMemberKind.Setter: throw unexpected('$this', 'getGetterType', -1, null); } } @@ -777,7 +774,7 @@ @override DartType getSetterType(InferenceVisitorBase base) { switch (declarationMethodKind) { - case ProcedureKind.Setter: + case ClassMemberKind.Setter: FunctionType functionType = member.function! .computeFunctionType(base.libraryBuilder.nonNullable); List<StructuralParameter> extensionTypeParameters = functionType @@ -793,10 +790,8 @@ setterType = legacyErasure(setterType); } return setterType; - case ProcedureKind.Method: - case ProcedureKind.Getter: - case ProcedureKind.Operator: - case ProcedureKind.Factory: + case ClassMemberKind.Method: + case ClassMemberKind.Getter: throw unexpected('$this', 'getSetterType', -1, null); } } @@ -804,7 +799,7 @@ @override DartType getIndexKeyType(InferenceVisitorBase base) { switch (declarationMethodKind) { - case ProcedureKind.Operator: + case ClassMemberKind.Method: FunctionType functionType = member.function! .computeFunctionType(base.libraryBuilder.nonNullable); if (functionType.positionalParameters.length >= 2) { @@ -821,10 +816,8 @@ return keyType; } return const InvalidType(); - case ProcedureKind.Method: - case ProcedureKind.Getter: - case ProcedureKind.Setter: - case ProcedureKind.Factory: + case ClassMemberKind.Getter: + case ClassMemberKind.Setter: throw unexpected('$this', 'getIndexKeyType', -1, null); } } @@ -832,7 +825,7 @@ @override DartType getIndexSetValueType(InferenceVisitorBase base) { switch (declarationMethodKind) { - case ProcedureKind.Operator: + case ClassMemberKind.Method: FunctionType functionType = member.function! .computeFunctionType(base.libraryBuilder.nonNullable); if (functionType.positionalParameters.length >= 3) { @@ -849,10 +842,8 @@ return indexType; } return const InvalidType(); - case ProcedureKind.Method: - case ProcedureKind.Getter: - case ProcedureKind.Setter: - case ProcedureKind.Factory: + case ClassMemberKind.Getter: + case ClassMemberKind.Setter: throw unexpected('$this', 'getIndexSetValueType', -1, null); } } @@ -860,9 +851,8 @@ @override DartType getReturnType(InferenceVisitorBase base) { switch (declarationMethodKind) { - case ProcedureKind.Operator: - case ProcedureKind.Method: - case ProcedureKind.Getter: + case ClassMemberKind.Method: + case ClassMemberKind.Getter: FunctionType functionType = member.function! .computeFunctionType(base.libraryBuilder.nonNullable); DartType returnType = functionType.returnType; @@ -876,17 +866,15 @@ returnType = legacyErasure(returnType); } return returnType; - case ProcedureKind.Setter: + case ClassMemberKind.Setter: return const VoidType(); - case ProcedureKind.Factory: - throw unexpected('$this', 'getReturnType', -1, null); } } @override DartType getBinaryOperandType(InferenceVisitorBase base) { switch (declarationMethodKind) { - case ProcedureKind.Operator: + case ClassMemberKind.Method: FunctionType functionType = member.function! .computeFunctionType(base.libraryBuilder.nonNullable); if (functionType.positionalParameters.length > 1) { @@ -903,12 +891,9 @@ return keyType; } return const InvalidType(); - case ProcedureKind.Method: - case ProcedureKind.Getter: - case ProcedureKind.Setter: + case ClassMemberKind.Getter: + case ClassMemberKind.Setter: return const InvalidType(); - case ProcedureKind.Factory: - throw unexpected('$this', 'getBinaryOperandType', -1, null); } } @@ -1109,7 +1094,7 @@ @override final Member? tearoffTarget; @override - final ProcedureKind declarationMethodKind; + final ClassMemberKind declarationMethodKind; @override final List<DartType> receiverTypeArguments; @@ -1123,19 +1108,17 @@ @override FunctionType getFunctionType(InferenceVisitorBase base) { switch (declarationMethodKind) { - case ProcedureKind.Method: - case ProcedureKind.Operator: + case ClassMemberKind.Method: FunctionType functionType = member.function! .computeFunctionType(base.libraryBuilder.nonNullable); if (!base.isNonNullableByDefault) { functionType = legacyErasure(functionType) as FunctionType; } return functionType; - case ProcedureKind.Getter: + case ClassMemberKind.Getter: // TODO(johnniwinther): Handle implicit .call on extension getter. return _getFunctionType(base, member.function!.returnType); - case ProcedureKind.Setter: - case ProcedureKind.Factory: + case ClassMemberKind.Setter: throw unexpected('$this', 'getFunctionType', -1, null); } } @@ -1143,8 +1126,7 @@ @override DartType getGetterType(InferenceVisitorBase base) { switch (declarationMethodKind) { - case ProcedureKind.Method: - case ProcedureKind.Operator: + case ClassMemberKind.Method: FunctionType functionType = member.function! .computeFunctionType(base.libraryBuilder.nonNullable); List<StructuralParameter> extensionTypeParameters = functionType @@ -1167,7 +1149,7 @@ resultType = legacyErasure(resultType); } return resultType; - case ProcedureKind.Getter: + case ClassMemberKind.Getter: FunctionType functionType = member.function! .computeFunctionType(base.libraryBuilder.nonNullable); List<StructuralParameter> extensionTypeParameters = functionType @@ -1182,8 +1164,7 @@ resultType = legacyErasure(resultType); } return resultType; - case ProcedureKind.Setter: - case ProcedureKind.Factory: + case ClassMemberKind.Setter: throw unexpected('$this', 'getGetterType', -1, null); } } @@ -1191,7 +1172,7 @@ @override DartType getSetterType(InferenceVisitorBase base) { switch (declarationMethodKind) { - case ProcedureKind.Setter: + case ClassMemberKind.Setter: FunctionType functionType = member.function! .computeFunctionType(base.libraryBuilder.nonNullable); List<StructuralParameter> extensionTypeParameters = functionType @@ -1207,10 +1188,8 @@ setterType = legacyErasure(setterType); } return setterType; - case ProcedureKind.Method: - case ProcedureKind.Getter: - case ProcedureKind.Operator: - case ProcedureKind.Factory: + case ClassMemberKind.Method: + case ClassMemberKind.Getter: throw unexpected('$this', 'getSetterType', -1, null); } } @@ -1218,7 +1197,7 @@ @override DartType getIndexKeyType(InferenceVisitorBase base) { switch (declarationMethodKind) { - case ProcedureKind.Operator: + case ClassMemberKind.Method: FunctionType functionType = member.function! .computeFunctionType(base.libraryBuilder.nonNullable); if (functionType.positionalParameters.length >= 2) { @@ -1235,10 +1214,8 @@ return keyType; } return const InvalidType(); - case ProcedureKind.Method: - case ProcedureKind.Getter: - case ProcedureKind.Setter: - case ProcedureKind.Factory: + case ClassMemberKind.Getter: + case ClassMemberKind.Setter: throw unexpected('$this', 'getIndexKeyType', -1, null); } } @@ -1246,7 +1223,7 @@ @override DartType getIndexSetValueType(InferenceVisitorBase base) { switch (declarationMethodKind) { - case ProcedureKind.Operator: + case ClassMemberKind.Method: FunctionType functionType = member.function! .computeFunctionType(base.libraryBuilder.nonNullable); if (functionType.positionalParameters.length >= 3) { @@ -1263,10 +1240,8 @@ return indexType; } return const InvalidType(); - case ProcedureKind.Method: - case ProcedureKind.Getter: - case ProcedureKind.Setter: - case ProcedureKind.Factory: + case ClassMemberKind.Getter: + case ClassMemberKind.Setter: throw unexpected('$this', 'getIndexSetValueType', -1, null); } } @@ -1274,9 +1249,8 @@ @override DartType getReturnType(InferenceVisitorBase base) { switch (declarationMethodKind) { - case ProcedureKind.Operator: - case ProcedureKind.Method: - case ProcedureKind.Getter: + case ClassMemberKind.Method: + case ClassMemberKind.Getter: FunctionType functionType = member.function! .computeFunctionType(base.libraryBuilder.nonNullable); DartType returnType = functionType.returnType; @@ -1290,17 +1264,15 @@ returnType = legacyErasure(returnType); } return returnType; - case ProcedureKind.Setter: + case ClassMemberKind.Setter: return const VoidType(); - case ProcedureKind.Factory: - throw unexpected('$this', 'getReturnType', -1, null); } } @override DartType getBinaryOperandType(InferenceVisitorBase base) { switch (declarationMethodKind) { - case ProcedureKind.Operator: + case ClassMemberKind.Method: FunctionType functionType = member.function! .computeFunctionType(base.libraryBuilder.nonNullable); if (functionType.positionalParameters.length > 1) { @@ -1317,12 +1289,9 @@ return keyType; } return const InvalidType(); - case ProcedureKind.Method: - case ProcedureKind.Getter: - case ProcedureKind.Setter: + case ClassMemberKind.Getter: + case ClassMemberKind.Setter: return const InvalidType(); - case ProcedureKind.Factory: - throw unexpected('$this', 'getBinaryOperandType', -1, null); } }