Skip to content

Commit 7612848

Browse files
Dan Rubelcommit-bot@chromium.org
authored andcommitted
fix bug in invalid constructor initializer recovery
Fix #37600 Fix #37029 Fix #37049 Fix #37110 Fix #37147 Change-Id: I9bc94991e71550410c02332bfd80faef50c229a5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/110140 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Dan Rubel <[email protected]>
1 parent babefb8 commit 7612848

File tree

2 files changed

+76
-20
lines changed

2 files changed

+76
-20
lines changed

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

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -413,33 +413,46 @@ class AstBuilder extends StackListener {
413413
initializerObject.target, initializerObject);
414414
}
415415

416+
if (initializerObject is CascadeExpression) {
417+
return buildInitializerTargetExpressionRecovery(
418+
initializerObject.target, initializerObject);
419+
}
420+
416421
throw new UnsupportedError('unsupported initializer:'
417422
' ${initializerObject.runtimeType} :: $initializerObject');
418423
}
419424

420425
AstNode buildInitializerTargetExpressionRecovery(
421426
Expression target, Object initializerObject) {
422-
if (target is FunctionExpressionInvocation) {
423-
Expression targetFunct = target.function;
424-
if (targetFunct is SuperExpression) {
425-
// TODO(danrubel): Consider generating this error in the parser
426-
// This error is also reported in the body builder
427-
handleRecoverableError(messageInvalidSuperInInitializer,
428-
targetFunct.superKeyword, targetFunct.superKeyword);
429-
return ast.superConstructorInvocation(
430-
targetFunct.superKeyword, null, null, target.argumentList);
431-
}
432-
if (targetFunct is ThisExpression) {
433-
// TODO(danrubel): Consider generating this error in the parser
434-
// This error is also reported in the body builder
435-
handleRecoverableError(messageInvalidThisInInitializer,
436-
targetFunct.thisKeyword, targetFunct.thisKeyword);
437-
return ast.redirectingConstructorInvocation(
438-
targetFunct.thisKeyword, null, null, target.argumentList);
427+
ArgumentList argumentList;
428+
while (true) {
429+
if (target is FunctionExpressionInvocation) {
430+
argumentList = (target as FunctionExpressionInvocation).argumentList;
431+
target = (target as FunctionExpressionInvocation).function;
432+
} else if (target is MethodInvocation) {
433+
argumentList = (target as MethodInvocation).argumentList;
434+
target = (target as MethodInvocation).target;
435+
} else if (target is PropertyAccess) {
436+
argumentList = null;
437+
target = (target as PropertyAccess).target;
438+
} else {
439+
break;
439440
}
440-
throw new UnsupportedError('unsupported initializer:'
441-
' ${initializerObject.runtimeType} :: $initializerObject'
442-
' %% targetFunct : ${targetFunct.runtimeType} :: $targetFunct');
441+
}
442+
if (target is SuperExpression) {
443+
// TODO(danrubel): Consider generating this error in the parser
444+
// This error is also reported in the body builder
445+
handleRecoverableError(messageInvalidSuperInInitializer,
446+
target.superKeyword, target.superKeyword);
447+
return ast.superConstructorInvocation(
448+
target.superKeyword, null, null, argumentList);
449+
} else if (target is ThisExpression) {
450+
// TODO(danrubel): Consider generating this error in the parser
451+
// This error is also reported in the body builder
452+
handleRecoverableError(messageInvalidThisInInitializer,
453+
target.thisKeyword, target.thisKeyword);
454+
return ast.redirectingConstructorInvocation(
455+
target.thisKeyword, null, null, argumentList);
443456
}
444457
throw new UnsupportedError('unsupported initializer:'
445458
' ${initializerObject.runtimeType} :: $initializerObject'

pkg/analyzer/test/generated/parser_fasta_test.dart

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,6 +1018,17 @@ main() { // missing async
10181018
]);
10191019
}
10201020

1021+
void test_constructor_super_cascade_synthetic() {
1022+
// https://github.com/dart-lang/sdk/issues/37110
1023+
parseCompilationUnit('class B extends A { B(): super.. {} }', errors: [
1024+
expectedError(ParserErrorCode.INVALID_SUPER_IN_INITIALIZER, 25, 5),
1025+
expectedError(ParserErrorCode.EXPECTED_TOKEN, 30, 2),
1026+
expectedError(ParserErrorCode.MISSING_IDENTIFIER, 33, 1),
1027+
expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 34, 1),
1028+
expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 36, 1),
1029+
]);
1030+
}
1031+
10211032
void test_constructor_super_field() {
10221033
// https://github.com/dart-lang/sdk/issues/36262
10231034
// https://github.com/dart-lang/sdk/issues/31198
@@ -1035,6 +1046,22 @@ main() { // missing async
10351046
]);
10361047
}
10371048

1049+
void test_constructor_super_named_method() {
1050+
// https://github.com/dart-lang/sdk/issues/37600
1051+
parseCompilationUnit('class B extends A { B(): super.c().create() {} }',
1052+
errors: [
1053+
expectedError(ParserErrorCode.INVALID_SUPER_IN_INITIALIZER, 25, 5),
1054+
]);
1055+
}
1056+
1057+
void test_constructor_super_named_method_method() {
1058+
// https://github.com/dart-lang/sdk/issues/37600
1059+
parseCompilationUnit('class B extends A { B(): super.c().create().x() {} }',
1060+
errors: [
1061+
expectedError(ParserErrorCode.INVALID_SUPER_IN_INITIALIZER, 25, 5),
1062+
]);
1063+
}
1064+
10381065
void test_constructor_this_field() {
10391066
// https://github.com/dart-lang/sdk/issues/36262
10401067
// https://github.com/dart-lang/sdk/issues/31198
@@ -1051,6 +1078,22 @@ main() { // missing async
10511078
]);
10521079
}
10531080

1081+
void test_constructor_this_named_method() {
1082+
// https://github.com/dart-lang/sdk/issues/37600
1083+
parseCompilationUnit('class B extends A { B(): super.c().create() {} }',
1084+
errors: [
1085+
expectedError(ParserErrorCode.INVALID_SUPER_IN_INITIALIZER, 25, 5),
1086+
]);
1087+
}
1088+
1089+
void test_constructor_this_named_method_field() {
1090+
// https://github.com/dart-lang/sdk/issues/37600
1091+
parseCompilationUnit('class B extends A { B(): super.c().create().x {} }',
1092+
errors: [
1093+
expectedError(ParserErrorCode.INVALID_SUPER_IN_INITIALIZER, 25, 5),
1094+
]);
1095+
}
1096+
10541097
@override
10551098
void test_expectedListOrMapLiteral() {
10561099
// The fasta parser returns an 'IntegerLiteralImpl' when parsing '1'.

0 commit comments

Comments
 (0)