Skip to content

Commit be2bf3f

Browse files
scheglovcommit-bot@chromium.org
authored andcommitted
Create local function parameters.
[email protected] Bug: Change-Id: I58715cc989d346d525a55e01dc14f91c8a436a82 Reviewed-on: https://dart-review.googlesource.com/23280 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent fed1e4b commit be2bf3f

File tree

4 files changed

+180
-10
lines changed

4 files changed

+180
-10
lines changed

pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import 'package:analyzer/src/generated/engine.dart';
3131
import 'package:analyzer/src/generated/error_verifier.dart';
3232
import 'package:analyzer/src/generated/resolver.dart';
3333
import 'package:analyzer/src/generated/source.dart';
34+
import 'package:analyzer/src/generated/utilities_dart.dart';
3435
import 'package:analyzer/src/kernel/resynthesize.dart';
3536
import 'package:analyzer/src/services/lint.dart';
3637
import 'package:analyzer/src/task/dart.dart';
@@ -51,6 +52,7 @@ class LibraryAnalyzer {
5152
final bool _enableKernelDriver;
5253
final bool _previewDart2;
5354
final KernelDriver _kernelDriver;
55+
final KernelResynthesizer _kernelResynthesizer;
5456

5557
final bool Function(Uri) _isLibraryUri;
5658
final AnalysisContextImpl _context;
@@ -83,7 +85,9 @@ class LibraryAnalyzer {
8385
: _typeProvider = _context.typeProvider,
8486
_enableKernelDriver = enableKernelDriver,
8587
_previewDart2 = previewDart2,
86-
_kernelDriver = kernelDriver;
88+
_kernelDriver = kernelDriver,
89+
_kernelResynthesizer =
90+
(_resynthesizer is KernelResynthesizer) ? _resynthesizer : null;
8791

8892
/**
8993
* Compute analysis results for all units of the library.
@@ -885,9 +889,42 @@ class LibraryAnalyzer {
885889
var element =
886890
new FunctionElementImpl(declaration.name, declaration.fileOffset);
887891
kernel.FunctionType kernelType = declaration.type;
888-
// TODO(scheglov) Cast one time.
889-
element.returnType = (_resynthesizer as KernelResynthesizer)
890-
.getType(context, kernelType.returnType);
892+
893+
// Set formal parameters.
894+
{
895+
var astParameters = <ParameterElement>[];
896+
var kernelFunction = functionDeclaration.function;
897+
898+
// Add positional parameters
899+
var kernelPositionalParameters = kernelFunction.positionalParameters;
900+
for (var i = 0; i < kernelPositionalParameters.length; i++) {
901+
var kernelParameter = kernelPositionalParameters[i];
902+
var astParameter = new ParameterElementImpl(
903+
kernelParameter.name, kernelParameter.fileOffset);
904+
astParameter.parameterKind =
905+
i < kernelFunction.requiredParameterCount
906+
? ParameterKind.REQUIRED
907+
: ParameterKind.POSITIONAL;
908+
astParameter.type =
909+
_kernelResynthesizer.getType(context, kernelParameter.type);
910+
astParameters.add(astParameter);
911+
}
912+
913+
// Add named parameters.
914+
for (var kernelParameter in kernelFunction.namedParameters) {
915+
var astParameter = new ParameterElementImpl(
916+
kernelParameter.name, kernelParameter.fileOffset);
917+
astParameter.parameterKind = ParameterKind.NAMED;
918+
astParameter.type =
919+
_kernelResynthesizer.getType(context, kernelParameter.type);
920+
astParameters.add(astParameter);
921+
}
922+
923+
element.parameters = astParameters;
924+
}
925+
926+
element.returnType =
927+
_kernelResynthesizer.getType(context, kernelType.returnType);
891928
element.type = new FunctionTypeImpl(element);
892929
return element;
893930
} else {

pkg/analyzer/lib/src/fasta/resolution_applier.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ class ResolutionApplier extends GeneralizingAstVisitor {
6262
FunctionExpression functionExpression = node.functionExpression;
6363
functionExpression.element = element;
6464
functionExpression.typeParameters?.accept(this);
65-
functionExpression.parameters?.accept(this);
6665
functionExpression.body?.accept(this);
6766
}
6867

pkg/analyzer/lib/src/fasta/resolution_storer.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:analyzer/src/fasta/resolution_applier.dart';
66
import 'package:front_end/src/fasta/type_inference/type_inference_listener.dart';
77
import 'package:kernel/ast.dart';
88

9+
/// TODO(scheglov) document
910
class FunctionReferenceDartType implements DartType {
1011
final FunctionDeclaration function;
1112
final DartType type;
@@ -86,6 +87,7 @@ class InstrumentedResolutionStorer extends ResolutionStorer {
8687
}
8788
}
8889

90+
/// TODO(scheglov) document
8991
class MemberReferenceDartType implements DartType {
9092
final Member member;
9193
final List<DartType> typeArguments;

pkg/analyzer/test/src/dart/analysis/driver_test.dart

Lines changed: 137 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
2323
import 'package:analyzer/src/generated/resolver.dart' show ResolverErrorCode;
2424
import 'package:analyzer/src/generated/sdk.dart';
2525
import 'package:analyzer/src/generated/source.dart';
26+
import 'package:analyzer/src/generated/utilities_dart.dart';
2627
import 'package:analyzer/src/summary/idl.dart';
2728
import 'package:analyzer/src/summary/package_bundle_reader.dart';
2829
import 'package:front_end/byte_store.dart';
@@ -66,10 +67,11 @@ class AnalysisDriverResolutionTest extends BaseAnalysisDriverTest {
6667
test_local_function() async {
6768
addTestFile(r'''
6869
void main() {
69-
double f() {}
70-
var v = f();
70+
double f(int a, String b) {}
71+
var v = f(1, '2');
7172
}
7273
''');
74+
String fTypeString = '(int, String) → double';
7375

7476
AnalysisResult result = await driver.getResult(testFile);
7577
List<Statement> mainStatements = _getMainStatements(result);
@@ -82,7 +84,7 @@ void main() {
8284
FunctionExpression fExpression = fNode.functionExpression;
8385
FunctionElement fElement = fNode.element;
8486
expect(fElement, isNotNull);
85-
expect(fElement.type.toString(), '() → double');
87+
expect(fElement.type.toString(), fTypeString);
8688

8789
expect(fNode.name.staticElement, same(fElement));
8890
expect(fNode.name.staticType, fElement.type);
@@ -93,15 +95,83 @@ void main() {
9395

9496
expect(fExpression.element, same(fElement));
9597

98+
{
99+
var parameters = fElement.parameters;
100+
expect(parameters, hasLength(2));
101+
102+
expect(parameters[0].name, 'a');
103+
expect(parameters[0].nameOffset, 29);
104+
expect(parameters[0].parameterKind, ParameterKind.REQUIRED);
105+
expect(parameters[0].type, typeProvider.intType);
106+
107+
expect(parameters[1].name, 'b');
108+
expect(parameters[1].nameOffset, 39);
109+
expect(parameters[1].parameterKind, ParameterKind.REQUIRED);
110+
expect(parameters[1].type, typeProvider.stringType);
111+
}
112+
96113
VariableDeclarationStatement vStatement = mainStatements[1];
97114
VariableDeclaration vDeclaration = vStatement.variables.variables[0];
98115
expect(vDeclaration.element.type, same(doubleType));
99116

100117
MethodInvocation fInvocation = vDeclaration.initializer;
101118
expect(fInvocation.methodName.staticElement, same(fElement));
102-
expect(fInvocation.methodName.staticType.toString(), '() → double');
119+
expect(fInvocation.methodName.staticType.toString(), fTypeString);
103120
expect(fInvocation.staticType, same(doubleType));
104-
expect(fInvocation.staticInvokeType.toString(), '() → double');
121+
expect(fInvocation.staticInvokeType.toString(), fTypeString);
122+
}
123+
124+
test_local_function_namedParameters() async {
125+
addTestFile(r'''
126+
void main() {
127+
double f(int a, {String b, bool c}) {}
128+
}
129+
''');
130+
String fTypeString = '(int, {b: String, c: bool}) → double';
131+
132+
AnalysisResult result = await driver.getResult(testFile);
133+
List<Statement> mainStatements = _getMainStatements(result);
134+
135+
var typeProvider = result.unit.element.context.typeProvider;
136+
InterfaceType doubleType = typeProvider.doubleType;
137+
138+
FunctionDeclarationStatement fStatement = mainStatements[0];
139+
FunctionDeclaration fNode = fStatement.functionDeclaration;
140+
FunctionExpression fExpression = fNode.functionExpression;
141+
FunctionElement fElement = fNode.element;
142+
expect(fElement, isNotNull);
143+
expect(fElement.type.toString(), fTypeString);
144+
145+
expect(fNode.name.staticElement, same(fElement));
146+
expect(fNode.name.staticType, fElement.type);
147+
148+
TypeName fReturnTypeNode = fNode.returnType;
149+
expect(fReturnTypeNode.name.staticElement, same(doubleType.element));
150+
expect(fReturnTypeNode.type, doubleType);
151+
152+
expect(fExpression.element, same(fElement));
153+
154+
{
155+
var parameters = fElement.parameters;
156+
expect(parameters, hasLength(3));
157+
158+
expect(parameters[0].name, 'a');
159+
expect(parameters[0].nameOffset, 29);
160+
expect(parameters[0].parameterKind, ParameterKind.REQUIRED);
161+
expect(parameters[0].type, typeProvider.intType);
162+
163+
expect(parameters[1].name, 'b');
164+
expect(parameters[1].nameOffset, 40);
165+
expect(parameters[1].parameterKind, ParameterKind.NAMED);
166+
expect(parameters[1].type, typeProvider.stringType);
167+
168+
expect(parameters[2].name, 'c');
169+
expect(parameters[2].nameOffset, 48);
170+
expect(parameters[2].parameterKind, ParameterKind.NAMED);
171+
expect(parameters[2].type, typeProvider.boolType);
172+
}
173+
174+
// TODO(scheglov) Add invocation test when we can resolve named parameters.
105175
}
106176

107177
test_local_function_noReturnType() async {
@@ -129,6 +199,68 @@ void main() {
129199
expect(fExpression.element, same(fElement));
130200
}
131201

202+
test_local_function_optionalParameters() async {
203+
addTestFile(r'''
204+
void main() {
205+
double f(int a, [String b, bool c]) {}
206+
var v = f(1, '2', true);
207+
}
208+
''');
209+
String fTypeString = '(int, [String, bool]) → double';
210+
211+
AnalysisResult result = await driver.getResult(testFile);
212+
List<Statement> mainStatements = _getMainStatements(result);
213+
214+
var typeProvider = result.unit.element.context.typeProvider;
215+
InterfaceType doubleType = typeProvider.doubleType;
216+
217+
FunctionDeclarationStatement fStatement = mainStatements[0];
218+
FunctionDeclaration fNode = fStatement.functionDeclaration;
219+
FunctionExpression fExpression = fNode.functionExpression;
220+
FunctionElement fElement = fNode.element;
221+
expect(fElement, isNotNull);
222+
expect(fElement.type.toString(), fTypeString);
223+
224+
expect(fNode.name.staticElement, same(fElement));
225+
expect(fNode.name.staticType, fElement.type);
226+
227+
TypeName fReturnTypeNode = fNode.returnType;
228+
expect(fReturnTypeNode.name.staticElement, same(doubleType.element));
229+
expect(fReturnTypeNode.type, doubleType);
230+
231+
expect(fExpression.element, same(fElement));
232+
233+
{
234+
var parameters = fElement.parameters;
235+
expect(parameters, hasLength(3));
236+
237+
expect(parameters[0].name, 'a');
238+
expect(parameters[0].nameOffset, 29);
239+
expect(parameters[0].parameterKind, ParameterKind.REQUIRED);
240+
expect(parameters[0].type, typeProvider.intType);
241+
242+
expect(parameters[1].name, 'b');
243+
expect(parameters[1].nameOffset, 40);
244+
expect(parameters[1].parameterKind, ParameterKind.POSITIONAL);
245+
expect(parameters[1].type, typeProvider.stringType);
246+
247+
expect(parameters[2].name, 'c');
248+
expect(parameters[2].nameOffset, 48);
249+
expect(parameters[2].parameterKind, ParameterKind.POSITIONAL);
250+
expect(parameters[2].type, typeProvider.boolType);
251+
}
252+
253+
VariableDeclarationStatement vStatement = mainStatements[1];
254+
VariableDeclaration vDeclaration = vStatement.variables.variables[0];
255+
expect(vDeclaration.element.type, same(doubleType));
256+
257+
MethodInvocation fInvocation = vDeclaration.initializer;
258+
expect(fInvocation.methodName.staticElement, same(fElement));
259+
expect(fInvocation.methodName.staticType.toString(), fTypeString);
260+
expect(fInvocation.staticType, same(doubleType));
261+
expect(fInvocation.staticInvokeType.toString(), fTypeString);
262+
}
263+
132264
test_local_variable() async {
133265
String content = r'''
134266
void main() {

0 commit comments

Comments
 (0)