Skip to content

Commit f7eba23

Browse files
scheglovcommit-bot@chromium.org
authored andcommitted
Create new style GenericFunctionTypeElementImpl for function typed parameters.
ParameterElement.parameters/typeParameters always return empty lists. This was initially landed as https://dart-review.googlesource.com/c/sdk/+/3401, but was rolled back because of dartdoc breakage. [email protected] Bug: Change-Id: I328355fa4520536dfd0029966ad9f9af2e63a7d2 Reviewed-on: https://dart-review.googlesource.com/5000 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent a3b9b8b commit f7eba23

File tree

13 files changed

+282
-349
lines changed

13 files changed

+282
-349
lines changed

pkg/analysis_server/test/services/correction/fix_test.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2433,6 +2433,7 @@ main() {
24332433
''');
24342434
}
24352435

2436+
@failingTest
24362437
test_createLocalVariable_functionType_synthetic() async {
24372438
await resolveTestUnit('''
24382439
foo(f(int p)) {}
@@ -2647,6 +2648,7 @@ class MyEmulator extends Emulator {
26472648
''');
26482649
}
26492650

2651+
@failingTest
26502652
test_createMissingOverrides_functionTypedParameter() async {
26512653
await resolveTestUnit('''
26522654
abstract class A {

pkg/analyzer/lib/src/dart/element/builder.dart

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,8 +1447,9 @@ abstract class _BaseElementBuilder extends RecursiveAstVisitor<Object> {
14471447
_visitChildren(holder, node);
14481448
ParameterElementImpl element = node.element;
14491449
element.metadata = _createElementAnnotations(node.metadata);
1450-
element.parameters = holder.parameters;
1451-
element.typeParameters = holder.typeParameters;
1450+
if (node.parameters != null) {
1451+
_createGenericFunctionType(element, holder);
1452+
}
14521453
holder.validate();
14531454
return null;
14541455
}
@@ -1476,8 +1477,7 @@ abstract class _BaseElementBuilder extends RecursiveAstVisitor<Object> {
14761477
_visitChildren(holder, node);
14771478
ParameterElementImpl element = node.element;
14781479
element.metadata = _createElementAnnotations(node.metadata);
1479-
element.parameters = holder.parameters;
1480-
element.typeParameters = holder.typeParameters;
1480+
_createGenericFunctionType(element, holder);
14811481
holder.validate();
14821482
return null;
14831483
}
@@ -1555,6 +1555,22 @@ abstract class _BaseElementBuilder extends RecursiveAstVisitor<Object> {
15551555
}).toList();
15561556
}
15571557

1558+
/**
1559+
* If the [holder] has type parameters or formal parameters for the
1560+
* given [parameter], wrap them into a new [GenericFunctionTypeElementImpl]
1561+
* and set [FunctionTypeImpl] for the [parameter].
1562+
*/
1563+
void _createGenericFunctionType(
1564+
ParameterElementImpl parameter, ElementHolder holder) {
1565+
var typeElement = new GenericFunctionTypeElementImpl.forOffset(-1);
1566+
typeElement.enclosingElement = parameter;
1567+
typeElement.typeParameters = holder.typeParameters;
1568+
typeElement.parameters = holder.parameters;
1569+
var type = new FunctionTypeImpl(typeElement);
1570+
typeElement.type = type;
1571+
parameter.type = type;
1572+
}
1573+
15581574
/**
15591575
* Return the body of the function that contains the given [parameter], or
15601576
* `null` if no function body could be found.

pkg/analyzer/lib/src/dart/element/element.dart

Lines changed: 20 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -4738,7 +4738,9 @@ class FieldFormalParameterElementImpl extends ParameterElementImpl
47384738

47394739
@override
47404740
DartType get type {
4741-
if (_unlinkedParam != null && _unlinkedParam.type == null) {
4741+
if (_unlinkedParam != null &&
4742+
_unlinkedParam.type == null &&
4743+
field != null) {
47424744
_type ??= field?.type ?? DynamicTypeImpl.instance;
47434745
}
47444746
return super.type;
@@ -8009,20 +8011,6 @@ class ParameterElementImpl extends VariableElementImpl
80098011
*/
80108012
final kernel.VariableDeclaration _kernel;
80118013

8012-
/**
8013-
* A list containing all of the parameters defined by this parameter element.
8014-
* There will only be parameters if this parameter is a function typed
8015-
* parameter.
8016-
*/
8017-
List<ParameterElement> _parameters = ParameterElement.EMPTY_LIST;
8018-
8019-
/**
8020-
* A list containing all of the type parameters defined for this parameter
8021-
* element. There will only be parameters if this parameter is a function
8022-
* typed parameter.
8023-
*/
8024-
List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
8025-
80268014
/**
80278015
* The kind of this parameter.
80288016
*/
@@ -8354,19 +8342,7 @@ class ParameterElementImpl extends VariableElementImpl
83548342

83558343
@override
83568344
List<ParameterElement> get parameters {
8357-
_resynthesizeTypeAndParameters();
8358-
return _parameters;
8359-
}
8360-
8361-
/**
8362-
* Set the parameters defined by this executable element to the given
8363-
* [parameters].
8364-
*/
8365-
void set parameters(List<ParameterElement> parameters) {
8366-
for (ParameterElement parameter in parameters) {
8367-
(parameter as ParameterElementImpl).enclosingElement = this;
8368-
}
8369-
this._parameters = parameters;
8345+
return const <ParameterElement>[];
83708346
}
83718347

83728348
@override
@@ -8386,17 +8362,8 @@ class ParameterElementImpl extends VariableElementImpl
83868362
}
83878363

83888364
@override
8389-
List<TypeParameterElement> get typeParameters => _typeParameters;
8390-
8391-
/**
8392-
* Set the type parameters defined by this parameter element to the given
8393-
* [typeParameters].
8394-
*/
8395-
void set typeParameters(List<TypeParameterElement> typeParameters) {
8396-
for (TypeParameterElement parameter in typeParameters) {
8397-
(parameter as TypeParameterElementImpl).enclosingElement = this;
8398-
}
8399-
this._typeParameters = typeParameters;
8365+
List<TypeParameterElement> get typeParameters {
8366+
return const <TypeParameterElement>[];
84008367
}
84018368

84028369
@override
@@ -8450,17 +8417,6 @@ class ParameterElementImpl extends VariableElementImpl
84508417
FormalParameter computeNode() =>
84518418
getNodeMatching((node) => node is FormalParameter);
84528419

8453-
@override
8454-
ElementImpl getChild(String identifier) {
8455-
for (ParameterElement parameter in _parameters) {
8456-
ParameterElementImpl parameterImpl = parameter;
8457-
if (parameterImpl.identifier == identifier) {
8458-
return parameterImpl;
8459-
}
8460-
}
8461-
return null;
8462-
}
8463-
84648420
/**
84658421
* Set the visible range for this element to the range starting at the given
84668422
* [offset] with the given [length].
@@ -8482,61 +8438,27 @@ class ParameterElementImpl extends VariableElementImpl
84828438
* been build yet, build them and remember in the corresponding fields.
84838439
*/
84848440
void _resynthesizeTypeAndParameters() {
8441+
// TODO(scheglov) Don't resynthesize parameters.
84858442
if (_kernel != null && _type == null) {
84868443
kernel.DartType type = _kernel.type;
84878444
_type = enclosingUnit._kernelContext.getType(this, type);
8488-
if (type is kernel.FunctionType && type.typedefReference == null) {
8489-
_parameters = new List<ParameterElement>(
8490-
type.positionalParameters.length + type.namedParameters.length);
8491-
int index = 0;
8492-
for (int i = 0; i < type.positionalParameters.length; i++) {
8493-
String name = i < type.positionalParameterNames.length
8494-
? type.positionalParameterNames[i]
8495-
: null;
8496-
_parameters[index++] = new ParameterElementImpl.forKernel(
8497-
enclosingElement,
8498-
new kernel.VariableDeclaration(name,
8499-
type: type.positionalParameters[i]),
8500-
i < type.requiredParameterCount
8501-
? ParameterKind.REQUIRED
8502-
: ParameterKind.POSITIONAL);
8503-
}
8504-
for (int i = 0; i < type.namedParameters.length; i++) {
8505-
_parameters[index++] = new ParameterElementImpl.forKernel(
8506-
enclosingElement,
8507-
new kernel.VariableDeclaration(type.namedParameters[i].name,
8508-
type: type.namedParameters[i].type),
8509-
ParameterKind.NAMED);
8510-
}
8511-
} else {
8512-
_parameters = const <ParameterElement>[];
8513-
}
85148445
}
85158446
if (_unlinkedParam != null && _declaredType == null && _type == null) {
85168447
if (_unlinkedParam.isFunctionTyped) {
85178448
CompilationUnitElementImpl enclosingUnit = this.enclosingUnit;
8518-
FunctionElementImpl parameterTypeElement =
8519-
new FunctionElementImpl_forFunctionTypedParameter(
8520-
enclosingUnit, this);
8521-
if (!isSynthetic) {
8522-
parameterTypeElement.enclosingElement = this;
8523-
}
8524-
List<ParameterElement> subParameters = ParameterElementImpl
8525-
.resynthesizeList(_unlinkedParam.parameters, this,
8526-
synthetic: isSynthetic);
8527-
if (isSynthetic) {
8528-
parameterTypeElement.parameters = subParameters;
8529-
} else {
8530-
_parameters = subParameters;
8531-
parameterTypeElement.shareParameters(subParameters);
8532-
}
8533-
parameterTypeElement.returnType = enclosingUnit.resynthesizerContext
8449+
8450+
var typeElement = new GenericFunctionTypeElementImpl.forOffset(-1);
8451+
typeElement.enclosingElement = this;
8452+
8453+
typeElement.parameters = ParameterElementImpl.resynthesizeList(
8454+
_unlinkedParam.parameters, typeElement,
8455+
synthetic: isSynthetic);
8456+
8457+
typeElement.returnType = enclosingUnit.resynthesizerContext
85348458
.resolveTypeRef(this, _unlinkedParam.type);
8535-
FunctionTypeImpl parameterType =
8536-
new FunctionTypeImpl.elementWithNameAndArgs(parameterTypeElement,
8537-
null, typeParameterContext.allTypeParameterTypes, false);
8538-
parameterTypeElement.type = parameterType;
8539-
_type = parameterType;
8459+
8460+
_type = new FunctionTypeImpl(typeElement);
8461+
typeElement.type = _type;
85408462
} else {
85418463
_type = enclosingUnit.resynthesizerContext
85428464
.resolveLinkedType(this, _unlinkedParam.inferredTypeSlot);
@@ -9666,7 +9588,7 @@ abstract class TypeParameterizedElementMixin
96669588
* Find out how many type parameters are in scope in this context.
96679589
*/
96689590
int get typeParameterNestingLevel =>
9669-
_nestingLevel ??= unlinkedTypeParams.length +
9591+
_nestingLevel ??= (unlinkedTypeParams?.length ?? 0) +
96709592
(enclosingTypeParameterContext?.typeParameterNestingLevel ?? 0);
96719593

96729594
@override

pkg/analyzer/lib/src/generated/declaration_resolver.dart

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
131131
normalParameter.element = element;
132132
_setGenericFunctionType(normalParameter.type, element.type);
133133
}
134+
134135
Expression defaultValue = node.defaultValue;
135136
if (defaultValue != null) {
136137
_walk(
@@ -139,9 +140,14 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
139140
defaultValue.accept(this);
140141
});
141142
}
142-
_walk(new ElementWalker.forParameter(element), () {
143+
144+
bool isFunctionTyped = normalParameter is FunctionTypedFormalParameter ||
145+
normalParameter is FieldFormalParameter &&
146+
normalParameter.parameters != null;
147+
_walk(new ElementWalker.forParameter(element, isFunctionTyped), () {
143148
normalParameter.accept(this);
144149
});
150+
145151
_resolveMetadata(node, node.metadata, element);
146152
return null;
147153
}
@@ -199,7 +205,8 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
199205
if (node.parent is! DefaultFormalParameter) {
200206
ParameterElement element =
201207
_match(node.identifier, _walker.getParameter());
202-
_walk(new ElementWalker.forParameter(element), () {
208+
bool isFunctionTyped = node.parameters != null;
209+
_walk(new ElementWalker.forParameter(element, isFunctionTyped), () {
203210
super.visitFieldFormalParameter(node);
204211
});
205212
_resolveMetadata(node, node.metadata, element);
@@ -268,7 +275,7 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
268275
if (node.parent is! DefaultFormalParameter) {
269276
ParameterElement element =
270277
_match(node.identifier, _walker.getParameter());
271-
_walk(new ElementWalker.forParameter(element), () {
278+
_walk(new ElementWalker.forParameter(element, true), () {
272279
super.visitFunctionTypedFormalParameter(node);
273280
});
274281
_resolveMetadata(node, node.metadata, element);
@@ -407,7 +414,7 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
407414
_match(node.identifier, _walker.getParameter());
408415
(node as SimpleFormalParameterImpl).element = element;
409416
_setGenericFunctionType(node.type, element.type);
410-
_walk(new ElementWalker.forParameter(element), () {
417+
_walk(new ElementWalker.forParameter(element, false), () {
411418
super.visitSimpleFormalParameter(node);
412419
});
413420
_resolveMetadata(node, node.metadata, element);
@@ -509,7 +516,7 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
509516
}
510517

511518
void _matchOffset(Element element, int offset) {
512-
if (element.nameOffset != 0 && element.nameOffset != offset) {
519+
if (element.nameOffset > 0 && element.nameOffset != offset) {
513520
throw new StateError('Element offset mismatch');
514521
} else {
515522
(element as ElementImpl).nameOffset = offset;
@@ -695,10 +702,18 @@ class ElementWalker {
695702
* Creates an [ElementWalker] which walks the child elements of a parameter
696703
* element.
697704
*/
698-
ElementWalker.forParameter(ParameterElement element)
705+
ElementWalker.forParameter(ParameterElement element, bool functionTyped)
699706
: element = element,
700707
_parameters = element.parameters,
701-
_typeParameters = element.typeParameters;
708+
_typeParameters = element.typeParameters {
709+
// If the parameter node is function typed, extract type parameters and
710+
// formal parameters from its generic function type element.
711+
if (functionTyped) {
712+
GenericFunctionTypeElement typeElement = element.type.element;
713+
_typeParameters = typeElement.typeParameters;
714+
_parameters = typeElement.parameters;
715+
}
716+
}
702717

703718
/**
704719
* Creates an [ElementWalker] which walks the child elements of a typedef

0 commit comments

Comments
 (0)