Skip to content

Commit dd8decb

Browse files
scheglovcommit-bot@chromium.org
authored andcommitted
Fix for explicit 'call' invocation and property get.
[email protected], [email protected] Bug: Change-Id: I17b11d2cfe53ed69ce251d8a7363f9aaf278e89b Reviewed-on: https://dart-review.googlesource.com/33145 Reviewed-by: Paul Berry <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent 60ee2c0 commit dd8decb

File tree

6 files changed

+110
-18
lines changed

6 files changed

+110
-18
lines changed

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -440,8 +440,13 @@ class ResolutionApplier extends GeneralizingAstVisitor {
440440

441441
node.staticInvokeType = invokeType;
442442
node.staticType = resultType;
443-
node.methodName.staticElement = invokeElement;
444-
node.methodName.staticType = invokeType;
443+
444+
if (node.methodName.name == 'call' && invokeElement == null) {
445+
// Don't resolve explicit call() invocation of function types.
446+
} else {
447+
node.methodName.staticElement = invokeElement;
448+
node.methodName.staticType = invokeType;
449+
}
445450

446451
if (invokeType is FunctionType) {
447452
if (node.typeArguments != null &&

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,8 @@ class ResolutionStorer extends TypeInferenceListener {
455455
_replaceType(invokeType, resultOffset);
456456

457457
if (!isImplicitCall) {
458-
throw new UnimplementedError(); // TODO(scheglov): handle this case
458+
_replaceReference(const NullNode('explicit-call'));
459+
_replaceType(const NullType());
459460
}
460461
super.genericExpressionExit("methodInvocation", expression, inferredType);
461462
}
@@ -495,8 +496,8 @@ class ResolutionStorer extends TypeInferenceListener {
495496

496497
@override
497498
void propertyGetExitCall(Expression expression, DartType inferredType) {
498-
throw new UnimplementedError(); // TODO(scheglov): handle this case
499-
// super.propertyGetExitCall(expression, inferredType);
499+
_recordReference(const NullNode('explicit-call'), expression.fileOffset);
500+
_recordType(const NullType(), expression.fileOffset);
500501
}
501502

502503
@override

pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -308,13 +308,6 @@ class NonErrorResolverTest_Kernel extends NonErrorResolverTest_Driver {
308308
return super.test_undefinedIdentifier_synthetic_whenMethodName();
309309
}
310310

311-
@override
312-
@failingTest
313-
@potentialAnalyzerProblem
314-
test_undefinedMethod_functionExpression_callMethod() async {
315-
return super.test_undefinedMethod_functionExpression_callMethod();
316-
}
317-
318311
@override
319312
@failingTest
320313
@potentialAnalyzerProblem

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,6 @@ class BaseAnalysisDriverTest {
6767

6868
bool get disableChangesAndCacheAllResults => false;
6969

70-
/**
71-
* Whether to enable the Dart 2.0 preview.
72-
*/
73-
bool previewDart2 = false;
74-
7570
/**
7671
* Whether to enable the Dart 2.0 Common Front End.
7772
*/

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

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3181,6 +3181,73 @@ void g(C c) {
31813181
_assertArgumentToParameter(arguments[2], methodElement.parameters[2]);
31823182
}
31833183

3184+
test_methodInvocation_explicitCall_classTarget() async {
3185+
addTestFile(r'''
3186+
class C {
3187+
double call(int p) => 0.0;
3188+
}
3189+
main() {
3190+
new C().call(0);
3191+
}
3192+
''');
3193+
AnalysisResult result = await driver.getResult(testFile);
3194+
expect(result.errors, isEmpty);
3195+
var typeProvider = result.unit.element.context.typeProvider;
3196+
3197+
ClassDeclaration cNode = result.unit.declarations[0];
3198+
ClassElement cElement = cNode.element;
3199+
MethodElement callElement = cElement.methods[0];
3200+
3201+
List<Statement> statements = _getMainStatements(result);
3202+
3203+
ExpressionStatement statement = statements[0];
3204+
MethodInvocation invocation = statement.expression;
3205+
3206+
expect(invocation.staticType, typeProvider.doubleType);
3207+
expect(invocation.staticInvokeType.toString(), '(int) → double');
3208+
3209+
SimpleIdentifier methodName = invocation.methodName;
3210+
expect(methodName.staticElement, same(callElement));
3211+
expect(methodName.staticType.toString(), '(int) → double');
3212+
}
3213+
3214+
test_methodInvocation_explicitCall_functionTarget() async {
3215+
addTestFile(r'''
3216+
main(double computation(int p)) {
3217+
computation.call(1);
3218+
}
3219+
''');
3220+
AnalysisResult result = await driver.getResult(testFile);
3221+
expect(result.errors, isEmpty);
3222+
var typeProvider = result.unit.element.context.typeProvider;
3223+
3224+
FunctionDeclaration main = result.unit.declarations[0];
3225+
FunctionElement mainElement = main.element;
3226+
ParameterElement parameter = mainElement.parameters[0];
3227+
3228+
BlockFunctionBody mainBody = main.functionExpression.body;
3229+
List<Statement> statements = mainBody.block.statements;
3230+
3231+
ExpressionStatement statement = statements[0];
3232+
MethodInvocation invocation = statement.expression;
3233+
3234+
expect(invocation.staticType, typeProvider.doubleType);
3235+
expect(invocation.staticInvokeType.toString(), '(int) → double');
3236+
3237+
SimpleIdentifier target = invocation.target;
3238+
expect(target.staticElement, same(parameter));
3239+
expect(target.staticType.toString(), '(int) → double');
3240+
3241+
SimpleIdentifier methodName = invocation.methodName;
3242+
if (useCFE) {
3243+
expect(methodName.staticElement, isNull);
3244+
expect(methodName.staticType, isNull);
3245+
} else {
3246+
expect(methodName.staticElement, same(parameter));
3247+
expect(methodName.staticType, parameter.type);
3248+
}
3249+
}
3250+
31843251
test_methodInvocation_instanceMethod_forwardingStub() async {
31853252
addTestFile(r'''
31863253
class A {
@@ -3839,6 +3906,38 @@ class C {
38393906
expect(identifier.staticType, typeProvider.intType);
38403907
}
38413908

3909+
test_prefixedIdentifier_explicitCall() async {
3910+
addTestFile(r'''
3911+
main(double computation(int p)) {
3912+
computation.call;
3913+
}
3914+
''');
3915+
AnalysisResult result = await driver.getResult(testFile);
3916+
expect(result.errors, isEmpty);
3917+
var typeProvider = result.unit.element.context.typeProvider;
3918+
3919+
FunctionDeclaration main = result.unit.declarations[0];
3920+
FunctionElement mainElement = main.element;
3921+
ParameterElement parameter = mainElement.parameters[0];
3922+
3923+
BlockFunctionBody mainBody = main.functionExpression.body;
3924+
List<Statement> statements = mainBody.block.statements;
3925+
3926+
ExpressionStatement statement = statements[0];
3927+
PrefixedIdentifier prefixed = statement.expression;
3928+
3929+
expect(prefixed.prefix.staticElement, same(parameter));
3930+
expect(prefixed.prefix.staticType.toString(), '(int) → double');
3931+
3932+
SimpleIdentifier methodName = prefixed.identifier;
3933+
expect(methodName.staticElement, isNull);
3934+
if (useCFE) {
3935+
expect(methodName.staticType, isNull);
3936+
} else {
3937+
expect(methodName.staticType, typeProvider.dynamicType);
3938+
}
3939+
}
3940+
38423941
test_prefixedIdentifier_importPrefix_className() async {
38433942
var libPath = _p('/test/lib/lib.dart');
38443943
provider.newFile(libPath, '''

pkg/front_end/testcases/ast_builder.status

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ accessors: Crash
99
annotation_top: Crash
1010
argument_mismatch: Crash
1111
bad_setter_abstract: Crash
12-
call: Crash
1312
cascade: Crash
1413
classes: Crash
1514
duplicated_named_args_3: Crash

0 commit comments

Comments
 (0)