Skip to content

Commit b7c6ad1

Browse files
stereotype441commit-bot@chromium.org
authored andcommitted
Remove hack that builds FunctionExpressionInvocation with synthetic arguments.
Now that we have an AST and visitor support for the FunctionReference structure (which represents `Expression<TypeArguments>` for various kinds of expressions), we no longer need to error recover this as a FunctionExpressionInvocation with synthetic arguments. The resolver still doesn't resolve the syntax properly, but that's ok because it's not permitted in valid code (for now we just treat it as having type `dynamic`). Fixes #46150. Change-Id: I357175cc16bcf2f9027be2e1da66bb6ca70a9400 Bug: #46020 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/199682 Commit-Queue: Paul Berry <[email protected]> Reviewed-by: Konstantin Shcheglov <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
1 parent 46b04e6 commit b7c6ad1

File tree

9 files changed

+37
-40
lines changed

9 files changed

+37
-40
lines changed

pkg/analyzer/lib/src/dart/resolver/exit_detector.dart

+7
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,13 @@ class ExitDetector extends GeneralizingAstVisitor<bool> {
304304
return node.argumentList.accept(this)!;
305305
}
306306

307+
@override
308+
bool visitFunctionReference(FunctionReference node) {
309+
// Note: `node.function` could be a reference to a method
310+
// (`Target.methodName`) so we need to visit it in case the target exits.
311+
return node.function.accept(this)!;
312+
}
313+
307314
@override
308315
bool visitGenericFunctionType(GenericFunctionType node) => false;
309316

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

-8
Original file line numberDiff line numberDiff line change
@@ -3532,14 +3532,6 @@ class AstBuilder extends StackListener {
35323532
typeArguments.leftBracket,
35333533
typeArguments.rightBracket,
35343534
);
3535-
// Since analyzer visitors don't yet support constructor tear-offs, create
3536-
// a FunctionExpressionInvocation with a synthetic argument list instead.
3537-
// TODO(paulberry): once we have visitor support for constructor
3538-
// tear-offs, fall through and return a FunctionReference instead since
3539-
// that should lead to better quality error recovery.
3540-
push(ast.functionExpressionInvocation(receiver, typeArguments,
3541-
_syntheticArgumentList(typeArguments.rightBracket)));
3542-
return;
35433535
}
35443536
push(ast.functionReference(
35453537
function: receiver, typeArguments: typeArguments));

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

+6
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,12 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<void> {
163163
@override
164164
void visitFunctionExpression(FunctionExpression node) {}
165165

166+
@override
167+
void visitFunctionReference(covariant FunctionReferenceImpl node) {
168+
// TODO(paulberry): implement
169+
node.staticType = _dynamicType;
170+
}
171+
166172
/// The Dart Language Specification, 12.11.1: <blockquote>The static type of a new expression of
167173
/// either the form <i>new T.id(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> or the form <i>new
168174
/// T(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> is <i>T</i>.</blockquote>

pkg/analyzer/test/generated/function_reference_parser_test.dart

+3-17
Original file line numberDiff line numberDiff line change
@@ -36,23 +36,9 @@ class FunctionReferenceParserTest extends FastaParserTestCase {
3636
}
3737

3838
void test_feature_disabled() {
39-
var expression =
40-
(parseStatement('f<a, b>;', featureSet: preConstructorTearoffs)
41-
as ExpressionStatement)
42-
.expression;
43-
// TODO(paulberry): once we have visitor support for FunctionReference, this
44-
// should be parsed as a FunctionReference, so we should be able to validate
45-
// it using `expect_f_a_b`. But for now it's parsed as a
46-
// FunctionExpressionInvocation with synthetic arguments.
47-
var functionExpressionInvocation =
48-
expression as FunctionExpressionInvocation;
49-
expect(
50-
(functionExpressionInvocation.function as SimpleIdentifier).name, 'f');
51-
expect(functionExpressionInvocation.argumentList.arguments, isEmpty);
52-
var typeArgs = functionExpressionInvocation.typeArguments!.arguments;
53-
expect(typeArgs, hasLength(2));
54-
expect(((typeArgs[0] as TypeName).name as SimpleIdentifier).name, 'a');
55-
expect(((typeArgs[1] as TypeName).name as SimpleIdentifier).name, 'b');
39+
expect_f_a_b((parseStatement('f<a, b>;', featureSet: preConstructorTearoffs)
40+
as ExpressionStatement)
41+
.expression);
5642
listener.assertErrors([
5743
expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 1, 6),
5844
]);

pkg/analyzer/test/generated/simple_parser_test.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -1449,8 +1449,8 @@ var c = Future<int>.sync(() => 3).then<int>((e) => e);
14491449
expect(body.expression, isMethodInvocation);
14501450
var methodInvocation = body.expression as MethodInvocationImpl;
14511451
var target = methodInvocation.target!;
1452-
expect(target, isFunctionExpressionInvocation);
1453-
expect(target.toSource(), 'C<E>()');
1452+
expect(target, isFunctionReference);
1453+
expect(target.toSource(), 'C<E>');
14541454
expect(methodInvocation.methodName.name, 'n');
14551455
expect(methodInvocation.argumentList, isNotNull);
14561456
expect(methodInvocation.typeArguments!.arguments, hasLength(1));

pkg/analyzer/test/src/dart/resolver/exit_detector_test.dart

+19
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
import 'package:analyzer/dart/analysis/features.dart';
56
import 'package:analyzer/dart/ast/ast.dart';
67
import 'package:analyzer/src/dart/resolver/exit_detector.dart';
8+
import 'package:analyzer/src/generated/engine.dart';
79
import 'package:analyzer/src/test_utilities/find_node.dart';
810
import 'package:test/test.dart';
911
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -143,6 +145,11 @@ void f() { // ref
143145
/// See [ExitDetectorResolvedStatementTest] for tests that require the AST to be resolved.
144146
@reflectiveTest
145147
class ExitDetectorParsedStatementTest extends ParseBase {
148+
@override
149+
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
150+
..contextFeatures = FeatureSet.forTesting(
151+
sdkVersion: '2.13', additionalFeatures: [Feature.constructor_tearoffs]);
152+
146153
test_asExpression() async {
147154
_assertFalse('a as Object;');
148155
}
@@ -514,6 +521,18 @@ class ExitDetectorParsedStatementTest extends ParseBase {
514521
_assertTrue("(throw 42)(g);");
515522
}
516523

524+
test_functionReference() async {
525+
_assertFalse('a<int>;');
526+
}
527+
528+
test_functionReference_method() async {
529+
_assertFalse('(a).m<int>;');
530+
}
531+
532+
test_functionReference_method_throw() async {
533+
_assertTrue('(throw 42).m<int>;');
534+
}
535+
517536
test_identifier_prefixedIdentifier() async {
518537
_assertFalse('a.b;');
519538
}

pkg/analyzer/test/src/diagnostics/experiment_not_enabled_test.dart

-9
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
6-
import 'package:analyzer/src/error/codes.dart';
76
import 'package:test_reflective_loader/test_reflective_loader.dart';
87

98
import '../dart/resolution/context_collection_resolution.dart';
@@ -26,10 +25,6 @@ main() {
2625
Foo<int>.bar.baz();
2726
}
2827
''', [
29-
// TODO(paulberry): the INVOCATION_OF_NON_FUNCTION_EXPRESSION error is
30-
// bogus, and should go away once we implement visitor and resolution
31-
// support for constructor tearoffs.
32-
error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 67, 3),
3328
error(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 70, 5),
3429
]);
3530
}
@@ -45,10 +40,6 @@ main() {
4540
Foo<int>.bar.baz();
4641
}
4742
''', [
48-
// TODO(paulberry): the INVOCATION_OF_NON_FUNCTION_EXPRESSION error is
49-
// bogus, and should go away once we implement visitor and resolution
50-
// support for constructor tearoffs.
51-
error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 80, 3),
5243
error(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 83, 5),
5344
]);
5445
}

tests/language/constructor/reference_test.dart

-2
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,6 @@ main() {
9292
Foo<int>();
9393
Foo<int>.bar();
9494
Foo<int>.bar.baz();
95-
//^^^
96-
// [analyzer] COMPILE_TIME_ERROR.INVOCATION_OF_NON_FUNCTION_EXPRESSION
9795
// ^^^^^
9896
// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
9997
// [cfe] This requires the 'constructor-tearoffs' language feature to be enabled.

tests/language_2/constructor/reference_test.dart

-2
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,6 @@ main() {
9494
Foo<int>();
9595
Foo<int>.bar();
9696
Foo<int>.bar.baz();
97-
//^^^
98-
// [analyzer] COMPILE_TIME_ERROR.INVOCATION_OF_NON_FUNCTION_EXPRESSION
9997
// ^^^^^
10098
// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
10199
// [cfe] This requires the 'constructor-tearoffs' language feature to be enabled.

0 commit comments

Comments
 (0)