mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 01:21:07 +00:00
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: https://github.com/dart-lang/sdk/issues/46020 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/199682 Commit-Queue: Paul Berry <paulberry@google.com> Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
parent
46b04e6c4a
commit
b7c6ad117f
|
@ -304,6 +304,13 @@ class ExitDetector extends GeneralizingAstVisitor<bool> {
|
|||
return node.argumentList.accept(this)!;
|
||||
}
|
||||
|
||||
@override
|
||||
bool visitFunctionReference(FunctionReference node) {
|
||||
// Note: `node.function` could be a reference to a method
|
||||
// (`Target.methodName`) so we need to visit it in case the target exits.
|
||||
return node.function.accept(this)!;
|
||||
}
|
||||
|
||||
@override
|
||||
bool visitGenericFunctionType(GenericFunctionType node) => false;
|
||||
|
||||
|
|
|
@ -3532,14 +3532,6 @@ class AstBuilder extends StackListener {
|
|||
typeArguments.leftBracket,
|
||||
typeArguments.rightBracket,
|
||||
);
|
||||
// Since analyzer visitors don't yet support constructor tear-offs, create
|
||||
// a FunctionExpressionInvocation with a synthetic argument list instead.
|
||||
// TODO(paulberry): once we have visitor support for constructor
|
||||
// tear-offs, fall through and return a FunctionReference instead since
|
||||
// that should lead to better quality error recovery.
|
||||
push(ast.functionExpressionInvocation(receiver, typeArguments,
|
||||
_syntheticArgumentList(typeArguments.rightBracket)));
|
||||
return;
|
||||
}
|
||||
push(ast.functionReference(
|
||||
function: receiver, typeArguments: typeArguments));
|
||||
|
|
|
@ -163,6 +163,12 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<void> {
|
|||
@override
|
||||
void visitFunctionExpression(FunctionExpression node) {}
|
||||
|
||||
@override
|
||||
void visitFunctionReference(covariant FunctionReferenceImpl node) {
|
||||
// TODO(paulberry): implement
|
||||
node.staticType = _dynamicType;
|
||||
}
|
||||
|
||||
/// The Dart Language Specification, 12.11.1: <blockquote>The static type of a new expression of
|
||||
/// either the form <i>new T.id(a<sub>1</sub>, …, a<sub>n</sub>)</i> or the form <i>new
|
||||
/// T(a<sub>1</sub>, …, a<sub>n</sub>)</i> is <i>T</i>.</blockquote>
|
||||
|
|
|
@ -36,23 +36,9 @@ class FunctionReferenceParserTest extends FastaParserTestCase {
|
|||
}
|
||||
|
||||
void test_feature_disabled() {
|
||||
var expression =
|
||||
(parseStatement('f<a, b>;', featureSet: preConstructorTearoffs)
|
||||
as ExpressionStatement)
|
||||
.expression;
|
||||
// TODO(paulberry): once we have visitor support for FunctionReference, this
|
||||
// should be parsed as a FunctionReference, so we should be able to validate
|
||||
// it using `expect_f_a_b`. But for now it's parsed as a
|
||||
// FunctionExpressionInvocation with synthetic arguments.
|
||||
var functionExpressionInvocation =
|
||||
expression as FunctionExpressionInvocation;
|
||||
expect(
|
||||
(functionExpressionInvocation.function as SimpleIdentifier).name, 'f');
|
||||
expect(functionExpressionInvocation.argumentList.arguments, isEmpty);
|
||||
var typeArgs = functionExpressionInvocation.typeArguments!.arguments;
|
||||
expect(typeArgs, hasLength(2));
|
||||
expect(((typeArgs[0] as TypeName).name as SimpleIdentifier).name, 'a');
|
||||
expect(((typeArgs[1] as TypeName).name as SimpleIdentifier).name, 'b');
|
||||
expect_f_a_b((parseStatement('f<a, b>;', featureSet: preConstructorTearoffs)
|
||||
as ExpressionStatement)
|
||||
.expression);
|
||||
listener.assertErrors([
|
||||
expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 1, 6),
|
||||
]);
|
||||
|
|
|
@ -1449,8 +1449,8 @@ var c = Future<int>.sync(() => 3).then<int>((e) => e);
|
|||
expect(body.expression, isMethodInvocation);
|
||||
var methodInvocation = body.expression as MethodInvocationImpl;
|
||||
var target = methodInvocation.target!;
|
||||
expect(target, isFunctionExpressionInvocation);
|
||||
expect(target.toSource(), 'C<E>()');
|
||||
expect(target, isFunctionReference);
|
||||
expect(target.toSource(), 'C<E>');
|
||||
expect(methodInvocation.methodName.name, 'n');
|
||||
expect(methodInvocation.argumentList, isNotNull);
|
||||
expect(methodInvocation.typeArguments!.arguments, hasLength(1));
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:analyzer/dart/analysis/features.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
import 'package:analyzer/src/dart/resolver/exit_detector.dart';
|
||||
import 'package:analyzer/src/generated/engine.dart';
|
||||
import 'package:analyzer/src/test_utilities/find_node.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
@ -143,6 +145,11 @@ void f() { // ref
|
|||
/// See [ExitDetectorResolvedStatementTest] for tests that require the AST to be resolved.
|
||||
@reflectiveTest
|
||||
class ExitDetectorParsedStatementTest extends ParseBase {
|
||||
@override
|
||||
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
|
||||
..contextFeatures = FeatureSet.forTesting(
|
||||
sdkVersion: '2.13', additionalFeatures: [Feature.constructor_tearoffs]);
|
||||
|
||||
test_asExpression() async {
|
||||
_assertFalse('a as Object;');
|
||||
}
|
||||
|
@ -514,6 +521,18 @@ class ExitDetectorParsedStatementTest extends ParseBase {
|
|||
_assertTrue("(throw 42)(g);");
|
||||
}
|
||||
|
||||
test_functionReference() async {
|
||||
_assertFalse('a<int>;');
|
||||
}
|
||||
|
||||
test_functionReference_method() async {
|
||||
_assertFalse('(a).m<int>;');
|
||||
}
|
||||
|
||||
test_functionReference_method_throw() async {
|
||||
_assertTrue('(throw 42).m<int>;');
|
||||
}
|
||||
|
||||
test_identifier_prefixedIdentifier() async {
|
||||
_assertFalse('a.b;');
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
|
||||
import 'package:analyzer/src/error/codes.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../dart/resolution/context_collection_resolution.dart';
|
||||
|
@ -26,10 +25,6 @@ main() {
|
|||
Foo<int>.bar.baz();
|
||||
}
|
||||
''', [
|
||||
// TODO(paulberry): the INVOCATION_OF_NON_FUNCTION_EXPRESSION error is
|
||||
// bogus, and should go away once we implement visitor and resolution
|
||||
// support for constructor tearoffs.
|
||||
error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 67, 3),
|
||||
error(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 70, 5),
|
||||
]);
|
||||
}
|
||||
|
@ -45,10 +40,6 @@ main() {
|
|||
Foo<int>.bar.baz();
|
||||
}
|
||||
''', [
|
||||
// TODO(paulberry): the INVOCATION_OF_NON_FUNCTION_EXPRESSION error is
|
||||
// bogus, and should go away once we implement visitor and resolution
|
||||
// support for constructor tearoffs.
|
||||
error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 80, 3),
|
||||
error(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 83, 5),
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -92,8 +92,6 @@ main() {
|
|||
Foo<int>();
|
||||
Foo<int>.bar();
|
||||
Foo<int>.bar.baz();
|
||||
//^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.INVOCATION_OF_NON_FUNCTION_EXPRESSION
|
||||
// ^^^^^
|
||||
// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
|
||||
// [cfe] This requires the 'constructor-tearoffs' language feature to be enabled.
|
||||
|
|
|
@ -94,8 +94,6 @@ main() {
|
|||
Foo<int>();
|
||||
Foo<int>.bar();
|
||||
Foo<int>.bar.baz();
|
||||
//^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.INVOCATION_OF_NON_FUNCTION_EXPRESSION
|
||||
// ^^^^^
|
||||
// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
|
||||
// [cfe] This requires the 'constructor-tearoffs' language feature to be enabled.
|
||||
|
|
Loading…
Reference in a new issue