Restore 'parameters' and 'typeParameters' for ParameterElementImpl.
This partially reverts https://dart-review.googlesource.com/c/sdk/+/5000
which was done during moving toward integration with Kernel, which
we don't do anymore.
With summary2 the FunctionType of a function type parameter is purely
synthetic, without its original element. However parameters in
function typed parameters still exist as nodes, so they must have
elements.
R=brianwilkerson@google.com
Change-Id: I6689b05459f3989a20839346013c80a86ac8dc7e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/99709
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 1c3c7e2..2159a8a 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -7941,6 +7941,16 @@
/// The unlinked representation of the parameter in the summary.
final UnlinkedParam unlinkedParam;
+ /// A list containing all of the parameters defined by this parameter element.
+ /// There will only be parameters if this parameter is a function typed
+ /// parameter.
+ List<ParameterElement> _parameters;
+
+ /// A list containing all of the type parameters defined for this parameter
+ /// element. There will only be parameters if this parameter is a function
+ /// typed parameter.
+ List<TypeParameterElement> _typeParameters;
+
/// The kind of this parameter.
ParameterKind _parameterKind;
@@ -8275,7 +8285,39 @@
@override
List<ParameterElement> get parameters {
- return const <ParameterElement>[];
+ if (_parameters != null) return _parameters;
+
+ if (linkedNode != null) {
+ var context = enclosingUnit.linkedContext;
+ var formalParameters = context.getFormalParameters(linkedNode);
+ if (formalParameters != null) {
+ var containerRef = reference.getChild('@parameter');
+ return _parameters = ParameterElementImpl.forLinkedNodeList(
+ this,
+ context,
+ containerRef,
+ formalParameters,
+ );
+ } else {
+ return _parameters ??= const <ParameterElement>[];
+ }
+ }
+
+ if (unlinkedParam != null) {
+ _resynthesizeTypeAndParameters();
+ return _parameters ??= const <ParameterElement>[];
+ }
+
+ return _parameters ??= const <ParameterElement>[];
+ }
+
+ /// Set the parameters defined by this executable element to the given
+ /// [parameters].
+ void set parameters(List<ParameterElement> parameters) {
+ for (ParameterElement parameter in parameters) {
+ (parameter as ParameterElementImpl).enclosingElement = this;
+ }
+ this._parameters = parameters;
}
@override
@@ -8301,7 +8343,18 @@
@override
List<TypeParameterElement> get typeParameters {
- return const <TypeParameterElement>[];
+ if (_typeParameters != null) return _typeParameters;
+
+ return _typeParameters ??= const <TypeParameterElement>[];
+ }
+
+ /// Set the type parameters defined by this parameter element to the given
+ /// [typeParameters].
+ void set typeParameters(List<TypeParameterElement> typeParameters) {
+ for (TypeParameterElement parameter in typeParameters) {
+ (parameter as TypeParameterElementImpl).enclosingElement = this;
+ }
+ this._typeParameters = typeParameters;
}
@override
@@ -8373,9 +8426,10 @@
var typeElement = new GenericFunctionTypeElementImpl.forOffset(-1);
typeElement.enclosingElement = this;
- typeElement.parameters = ParameterElementImpl.resynthesizeList(
+ _parameters = ParameterElementImpl.resynthesizeList(
unlinkedParam.parameters, typeElement,
synthetic: isSynthetic);
+ typeElement.parameters = _parameters;
typeElement.returnType = enclosingUnit.resynthesizerContext
.resolveTypeRef(this, unlinkedParam.type);
diff --git a/pkg/analyzer/lib/src/generated/declaration_resolver.dart b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
index 7175395..b956a8a 100644
--- a/pkg/analyzer/lib/src/generated/declaration_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
@@ -137,10 +137,7 @@
});
}
- bool isFunctionTyped = normalParameter is FunctionTypedFormalParameter ||
- normalParameter is FieldFormalParameter &&
- normalParameter.parameters != null;
- _walk(new ElementWalker.forParameter(element, isFunctionTyped), () {
+ _walk(new ElementWalker.forParameter(element), () {
normalParameter.accept(this);
});
@@ -202,8 +199,7 @@
if (node.parent is! DefaultFormalParameter) {
ParameterElement element =
_match(node.identifier, _walker.getParameter());
- bool isFunctionTyped = node.parameters != null;
- _walk(new ElementWalker.forParameter(element, isFunctionTyped), () {
+ _walk(new ElementWalker.forParameter(element), () {
super.visitFieldFormalParameter(node);
});
resolveMetadata(node, node.metadata, element);
@@ -264,7 +260,7 @@
if (node.parent is! DefaultFormalParameter) {
ParameterElement element =
_match(node.identifier, _walker.getParameter());
- _walk(new ElementWalker.forParameter(element, true), () {
+ _walk(new ElementWalker.forParameter(element), () {
super.visitFunctionTypedFormalParameter(node);
});
resolveMetadata(node, node.metadata, element);
@@ -405,7 +401,7 @@
_match(node.identifier, _walker.getParameter());
(node as SimpleFormalParameterImpl).declaredElement = element;
_setGenericFunctionType(node.type, element.type);
- _walk(new ElementWalker.forParameter(element, false), () {
+ _walk(new ElementWalker.forParameter(element), () {
super.visitSimpleFormalParameter(node);
});
resolveMetadata(node, node.metadata, element);
@@ -851,18 +847,10 @@
/// Creates an [ElementWalker] which walks the child elements of a parameter
/// element.
- ElementWalker.forParameter(ParameterElement element, bool functionTyped)
+ ElementWalker.forParameter(ParameterElement element)
: element = element,
_parameters = element.parameters,
- _typeParameters = element.typeParameters {
- // If the parameter node is function typed, extract type parameters and
- // formal parameters from its generic function type element.
- if (functionTyped) {
- GenericFunctionTypeElement typeElement = element.type.element;
- _typeParameters = typeElement.typeParameters;
- _parameters = typeElement.parameters;
- }
- }
+ _typeParameters = element.typeParameters;
/// Creates an [ElementWalker] which walks the child elements of a typedef
/// element.
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 9295e4f..49ba32d 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -5948,8 +5948,7 @@
new CaughtException(new AnalysisException(), null));
} else {
nameScope = new EnclosedScope(nameScope);
- GenericFunctionTypeElement typeElement = parameterElement.type.element;
- List<TypeParameterElement> typeParameters = typeElement.typeParameters;
+ var typeParameters = parameterElement.typeParameters;
int length = typeParameters.length;
for (int i = 0; i < length; i++) {
nameScope.define(typeParameters[i]);
@@ -8316,7 +8315,10 @@
TypeAnnotation returnType, FormalParameterList parameterList) {
DartType type = parameter.type;
GenericFunctionTypeElementImpl typeElement = type.element;
- typeElement.returnType = _computeReturnType(returnType);
+ // With summary2 we use synthetic FunctionType(s).
+ if (typeElement != null) {
+ typeElement.returnType = _computeReturnType(returnType);
+ }
}
}
diff --git a/pkg/analyzer/lib/src/summary2/lazy_ast.dart b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
index b423a53..773b59f 100644
--- a/pkg/analyzer/lib/src/summary2/lazy_ast.dart
+++ b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
@@ -561,6 +561,7 @@
final LinkedNode data;
bool _hasDefaultValue = false;
+ bool _hasFormalParameters = false;
bool _hasMetadata = false;
bool _hasType = false;
@@ -600,6 +601,25 @@
}
}
+ static void readFormalParameters(
+ AstBinaryReader reader,
+ FormalParameter node,
+ ) {
+ var lazy = get(node);
+ if (lazy != null && !lazy._hasFormalParameters) {
+ if (node is FunctionTypedFormalParameter) {
+ node.parameters = reader.readNode(
+ lazy.data.functionTypedFormalParameter_formalParameters,
+ );
+ } else if (node is FieldFormalParameter) {
+ node.parameters = reader.readNode(
+ lazy.data.fieldFormalParameter_formalParameters,
+ );
+ }
+ lazy._hasFormalParameters = true;
+ }
+ }
+
static void readMetadata(
AstBinaryReader reader,
FormalParameter node,
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index 201d7f0..86bc82a 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -255,6 +255,18 @@
} else if (node is FunctionExpression) {
LazyFunctionExpression.readFormalParameters(_astReader, node);
return node.parameters?.parameters;
+ } else if (node is FormalParameter) {
+ if (node is DefaultFormalParameter) {
+ return getFormalParameters(node.parameter);
+ } else if (node is FieldFormalParameter) {
+ LazyFormalParameter.readFormalParameters(_astReader, node);
+ return node.parameters?.parameters;
+ } else if (node is FunctionTypedFormalParameter) {
+ LazyFormalParameter.readFormalParameters(_astReader, node);
+ return node.parameters.parameters;
+ } else {
+ return null;
+ }
} else if (node is FunctionTypeAlias) {
LazyFunctionTypeAlias.readFormalParameters(_astReader, node);
return node.parameters.parameters;
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 3da22d1..9c5be7a 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -1834,6 +1834,7 @@
AstTestFactory.functionTypedFormalParameter(
AstTestFactory.typeName4('R'), 'g', [eNode]);
ParameterElementImpl gElement = ElementFactory.requiredParameter('g');
+ gElement.typeParameters = [elementE];
gNode.identifier.staticElement = gElement;
FunctionTypeImpl gType =
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index c383abb..3ca6771 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -726,12 +726,7 @@
writeIf(e.isCovariant, 'covariant ');
writeIf(e.isFinal, 'final ');
- if (e.parameters.isNotEmpty) {
- var type = e.type as FunctionType;
- writeType2(type.returnType);
- } else {
- writeType2(e.type);
- }
+ writeType2(e.type);
if (e is FieldFormalParameterElement) {
buffer.write('this.');
@@ -741,8 +736,9 @@
writeCodeRange(e);
if (e.parameters.isNotEmpty) {
- writeList('(', ')', e.parameters, ', ', writeParameterElement,
- includeEmpty: true);
+ buffer.write('/*');
+ writeList('(', ')', e.parameters, ', ', writeParameterElement);
+ buffer.write('*/');
}
writeVariableTypeInferenceError(e);
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index d87436d..47de718 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -602,7 +602,7 @@
checkElementText(library, r'''
class C {
dynamic x;
- C((double) → dynamic this.x);
+ C((double) → dynamic this.x/*(double b)*/);
}
''');
}
@@ -617,7 +617,7 @@
checkElementText(library, r'''
class C {
dynamic x;
- C((double) → int this.x);
+ C((double) → int this.x/*(double b)*/);
}
''');
}
@@ -5793,7 +5793,7 @@
test_function_parameter_parameters() async {
var library = await checkLibrary('f(g(x, y)) {}');
checkElementText(library, r'''
-dynamic f((dynamic, dynamic) → dynamic g) {}
+dynamic f((dynamic, dynamic) → dynamic g/*(dynamic x, dynamic y)*/) {}
''');
}
@@ -5856,7 +5856,7 @@
test_function_type_parameter_with_function_typed_parameter() async {
var library = await checkLibrary('void f<T, U>(T x(U u)) {}');
checkElementText(library, r'''
-void f<T, U>((U) → T x) {}
+void f<T, U>((U) → T x/*(U u)*/) {}
''');
}
@@ -5955,7 +5955,7 @@
void f(int Function(int a, String b) p(num c)) => null;
''');
checkElementText(library, r'''
-void f((num) → (int, String) → int p) {}
+void f((num) → (int, String) → int p/*(num c)*/) {}
''');
}
@@ -6584,7 +6584,7 @@
var v = h(/*info:INFERRED_TYPE_CLOSURE*/(y) {});
''');
checkElementText(library, r'''
-typedef F = void Function((String) → int g);
+typedef F = void Function((String) → int g/*(String s)*/);
dynamic v;
dynamic h(((String) → int) → void f) {}
''');
@@ -6603,7 +6603,7 @@
void f(int x, (U) → int g) {}
}
abstract class D<V, W> {
- void f(int x, (V) → W g);
+ void f(int x, (V) → W g/*(V s)*/);
}
''');
}
@@ -6640,7 +6640,7 @@
void f(int x, (String) → int g) {}
}
abstract class D {
- void f(int x, (String) → int g);
+ void f(int x, (String) → int g/*(String s)*/);
}
''');
}
@@ -6652,7 +6652,7 @@
''');
checkElementText(library, r'''
dynamic v;
-dynamic f((int, () → void) → void g) {}
+dynamic f((int, () → void) → void g/*(int x, () → void h)*/) {}
''');
}
@@ -6663,7 +6663,7 @@
''');
checkElementText(library, r'''
dynamic v;
-dynamic f({(int, () → void) → void g}) {}
+dynamic f({(int, () → void) → void g/*(int x, () → void h)*/}) {}
''');
}
@@ -6675,7 +6675,7 @@
void set f((String) → int g) {}
}
abstract class D {
- void set f((String) → int g);
+ void set f((String) → int g/*(String s)*/);
}
''');
}
@@ -6758,8 +6758,8 @@
''');
checkElementText(library, r'''
List<((String) → int) → Object> v;
-int f((String) → int x) {}
-String g((String) → int x) {}
+int f((String) → int x/*(String y)*/) {}
+String g((String) → int x/*(String y)*/) {}
''');
}
@@ -8121,7 +8121,7 @@
var library = await checkLibrary('class C { void f<T, U>(T x(U u)) {} }');
checkElementText(library, r'''
class C {
- void f<T, U>((U) → T x) {}
+ void f<T, U>((U) → T x/*(U u)*/) {}
}
''');
}
@@ -8522,7 +8522,7 @@
var library = await checkLibrary('class C { f(g(x, y)) {} }');
checkElementText(library, r'''
class C {
- dynamic f((dynamic, dynamic) → dynamic g) {}
+ dynamic f((dynamic, dynamic) → dynamic g/*(dynamic x, dynamic y)*/) {}
}
''');
}
@@ -8531,7 +8531,7 @@
var library = await checkLibrary('class C<A, B> { f(A g(B x)) {} }');
checkElementText(library, r'''
class C<A, B> {
- dynamic f((B) → A g) {}
+ dynamic f((B) → A g/*(B x)*/) {}
}
''');
}
@@ -9501,14 +9501,14 @@
test_typedef_parameter_parameters() async {
var library = await checkLibrary('typedef F(g(x, y));');
checkElementText(library, r'''
-typedef F = dynamic Function((dynamic, dynamic) → dynamic g);
+typedef F = dynamic Function((dynamic, dynamic) → dynamic g/*(dynamic x, dynamic y)*/);
''');
}
test_typedef_parameter_parameters_in_generic_class() async {
var library = await checkLibrary('typedef F<A, B>(A g(B x));');
checkElementText(library, r'''
-typedef F<A, B> = dynamic Function((B) → A g);
+typedef F<A, B> = dynamic Function((B) → A g/*(B x)*/);
''');
}