[analyzer] Use FormalParameterElementOrMember when interfacing with shared code.
Change the analyzer's use of the following shared generic types so
that it supplies the type parameter `FormalParameterElementOrMember`
instead of `ParameterElementMixin` as the type it uses to represent
parameters of function types:
- `SharedFunctionTypeStructure`
- `TypeConstraintGenerator`
- `TypeConstraintGeneratorMixin`
`FormalParameterElementOrMember` is a new interface class that acts as
a common private base class for all the concrete subtypes of the
public API class `FormalParameterElement`.
This required adding a type cast in one place (in
`FunctionTypeImpl.sortedNamedParametersShared`). In other places, I
avoided type casts by tightening up some return types (for example,
`FieldFormalParameterElementImpl.element` now returns
`FieldFormalParameterElementImpl2` instead of
`FieldFormalParameterElement2`). The analyzer public API is unchanged,
though (for example, `FieldFormalParameterFragment.element` still has
a return type of `FieldFormalParameterElement2`), so clients should be
unaffected.
As a result of this change, it is no longer necessary for
`ParameterElementMixin` to implement the shared interface
`SharedNamedFunctionParameterStructure`. This interface is now
implemented by `FormalParameterElementOrMember`.
This is part of a larger arc of work to use types from the new
analyzer element model when interfacing with shared code.
Change-Id: I1ab5bf0607a80cbe30f4814bd5444487099825ee
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/402341
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 7b0002d..acf5f3b 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -4400,8 +4400,8 @@
});
@override
- FieldFormalParameterElement2 get element =>
- super.element as FieldFormalParameterElement2;
+ FieldFormalParameterElementImpl2 get element =>
+ super.element as FieldFormalParameterElementImpl2;
/// Initializing formals are visible only in the "formal parameter
/// initializer scope", which is the current scope of the initializer list
@@ -4428,7 +4428,7 @@
visitor.visitFieldFormalParameterElement(this);
@override
- FormalParameterElement _createElement(
+ FieldFormalParameterElementImpl2 _createElement(
FormalParameterFragment firstFragment) =>
FieldFormalParameterElementImpl2(firstFragment as ParameterElementImpl);
}
@@ -4453,7 +4453,7 @@
FragmentedAnnotatableElementMixin<FormalParameterFragment>,
FragmentedElementMixin<FormalParameterFragment>,
_NonTopLevelVariableOrParameter
- implements FormalParameterElement {
+ implements FormalParameterElementOrMember {
final ParameterElementImpl wrappedElement;
FormalParameterElementImpl(this.wrappedElement) {
@@ -4552,6 +4552,9 @@
String? get name3 => wrappedElement.name;
@override
+ String get nameShared => wrappedElement.name;
+
+ @override
// TODO(augmentations): Implement the merge of formal parameters.
DartType get type => wrappedElement.type;
@@ -4588,6 +4591,11 @@
// .toList();
}
+abstract class FormalParameterElementOrMember
+ implements
+ FormalParameterElement,
+ SharedNamedFunctionParameterStructure<DartType> {}
+
mixin FragmentedAnnotatableElementMixin<E extends Fragment>
implements FragmentedElementMixin<E> {
String? get documentationComment {
@@ -9029,7 +9037,7 @@
bool inheritsCovariant = false;
/// The element corresponding to this fragment.
- FormalParameterElement? _element;
+ FormalParameterElementImpl? _element;
/// Initialize a newly created parameter element to have the given [name] and
/// [nameOffset].
@@ -9065,7 +9073,7 @@
ParameterElement get declaration => this;
@override
- FormalParameterElement get element {
+ FormalParameterElementImpl get element {
if (_element != null) {
return _element!;
}
@@ -9080,7 +9088,7 @@
return _createElement(firstFragment);
}
- set element(FormalParameterElement element) => _element = element;
+ set element(FormalParameterElementImpl element) => _element = element;
@override
Fragment? get enclosingFragment => enclosingElement3 as Fragment?;
@@ -9170,7 +9178,7 @@
builder.writeFormalParameter(this);
}
- FormalParameterElement _createElement(
+ FormalParameterElementImpl _createElement(
FormalParameterFragment firstFragment) =>
FormalParameterElementImpl(firstFragment as ParameterElementImpl);
}
@@ -9241,10 +9249,7 @@
/// A mixin that provides a common implementation for methods defined in
/// [ParameterElement].
-mixin ParameterElementMixin
- implements
- ParameterElement,
- SharedNamedFunctionParameterStructure<DartType> {
+mixin ParameterElementMixin implements ParameterElement {
@override
bool get isNamed => parameterKind.isNamed;
@@ -9270,9 +9275,6 @@
bool get isRequiredPositional => parameterKind.isRequiredPositional;
@override
- String get nameShared => name;
-
- @override
// Overridden to remove the 'deprecated' annotation.
ParameterKind get parameterKind;
@@ -10274,8 +10276,8 @@
});
@override
- SuperFormalParameterElement2 get element =>
- super.element as SuperFormalParameterElement2;
+ SuperFormalParameterElementImpl2 get element =>
+ super.element as SuperFormalParameterElementImpl2;
/// Super parameters are visible only in the initializer list scope,
/// and introduce final variables.
@@ -10329,7 +10331,7 @@
}
@override
- FormalParameterElement _createElement(
+ FormalParameterElementImpl _createElement(
FormalParameterFragment firstFragment) =>
SuperFormalParameterElementImpl2(firstFragment as ParameterElementImpl);
}
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 9d6ac84..9f50ea0 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -1079,7 +1079,7 @@
/// type parameters are known.
class ParameterMember extends VariableMember
with ParameterElementMixin
- implements ParameterElement, FormalParameterElement {
+ implements ParameterElement, FormalParameterElementOrMember {
@override
final List<TypeParameterElement> typeParameters;
@@ -1168,6 +1168,9 @@
String? get name3 => _element2.name3;
@override
+ String get nameShared => name;
+
+ @override
Element2 get nonSynthetic2 => _element2;
@deprecated
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index f541df5..c621481 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -90,7 +90,7 @@
implements
FunctionType,
SharedFunctionTypeStructure<DartType, TypeParameterElementImpl2,
- ParameterElementMixin> {
+ FormalParameterElementOrMember> {
@override
late int hashCode = _computeHashCode();
@@ -234,8 +234,13 @@
positionalParameterTypes.sublist(requiredPositionalParameterCount);
@override
- List<ParameterElementMixin> get sortedNamedParametersShared =>
- sortedNamedParameters;
+ // TODO(paulberry): see if this type can be changed to
+ // `List<FormalParameterElementImpl>`. See
+ // https://dart-review.googlesource.com/c/sdk/+/402341/comment/b1669e20_15938fcd/.
+ List<FormalParameterElementOrMember> get sortedNamedParametersShared =>
+ sortedNamedParameters
+ .map((p) => p.asElement2 as FormalParameterElementOrMember)
+ .toList();
@override
List<TypeParameterElementImpl2> get typeParameters => typeFormals
diff --git a/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart b/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart
index 95faa67..02d08a5 100644
--- a/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart
@@ -94,7 +94,7 @@
/// attempt to make one type schema a subtype of another.
class TypeConstraintGatherer extends shared.TypeConstraintGenerator<
DartType,
- ParameterElementMixin,
+ FormalParameterElementOrMember,
PromotableElementImpl2,
TypeParameterElementImpl2,
InterfaceType,
@@ -103,7 +103,7 @@
with
shared.TypeConstraintGeneratorMixin<
DartType,
- ParameterElementMixin,
+ FormalParameterElementOrMember,
PromotableElementImpl2,
TypeParameterElementImpl2,
InterfaceType,
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index ea80ad6..170b723 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -1890,6 +1890,20 @@
]);
}
+ test_instantiateGenericFunctionWithNamedParameterAsGenericArg() async {
+ // This test case reproduces the problem encountered in
+ // https://dart-review.googlesource.com/c/sdk/+/402341/comment/b1669e20_15938fcd/.
+ await assertNoErrorsInCode(r'''
+abstract class C<T> {
+ S f<S>(S Function(C<T>) g);
+}
+
+T h<T>(C<T> c, {bool b = false}) => throw '';
+
+T test<T>(C<T> c) => c.f(h);
+''');
+ }
+
test_integerLiteralOutOfRange_negative_leadingZeros() async {
await assertNoErrorsInCode('''
int x = -000923372036854775809;