fix bug in invalid constructor initializer recovery

Fix https://github.com/dart-lang/sdk/issues/37600
Fix https://github.com/dart-lang/sdk/issues/37029
Fix https://github.com/dart-lang/sdk/issues/37049
Fix https://github.com/dart-lang/sdk/issues/37110
Fix https://github.com/dart-lang/sdk/issues/37147

Change-Id: I9bc94991e71550410c02332bfd80faef50c229a5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/110140
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Dan Rubel <danrubel@google.com>
This commit is contained in:
Dan Rubel 2019-07-23 16:42:54 +00:00 committed by commit-bot@chromium.org
parent babefb8c01
commit 76128480ae
2 changed files with 76 additions and 20 deletions

View file

@ -413,33 +413,46 @@ class AstBuilder extends StackListener {
initializerObject.target, initializerObject);
}
if (initializerObject is CascadeExpression) {
return buildInitializerTargetExpressionRecovery(
initializerObject.target, initializerObject);
}
throw new UnsupportedError('unsupported initializer:'
' ${initializerObject.runtimeType} :: $initializerObject');
}
AstNode buildInitializerTargetExpressionRecovery(
Expression target, Object initializerObject) {
if (target is FunctionExpressionInvocation) {
Expression targetFunct = target.function;
if (targetFunct is SuperExpression) {
// TODO(danrubel): Consider generating this error in the parser
// This error is also reported in the body builder
handleRecoverableError(messageInvalidSuperInInitializer,
targetFunct.superKeyword, targetFunct.superKeyword);
return ast.superConstructorInvocation(
targetFunct.superKeyword, null, null, target.argumentList);
ArgumentList argumentList;
while (true) {
if (target is FunctionExpressionInvocation) {
argumentList = (target as FunctionExpressionInvocation).argumentList;
target = (target as FunctionExpressionInvocation).function;
} else if (target is MethodInvocation) {
argumentList = (target as MethodInvocation).argumentList;
target = (target as MethodInvocation).target;
} else if (target is PropertyAccess) {
argumentList = null;
target = (target as PropertyAccess).target;
} else {
break;
}
if (targetFunct is ThisExpression) {
// TODO(danrubel): Consider generating this error in the parser
// This error is also reported in the body builder
handleRecoverableError(messageInvalidThisInInitializer,
targetFunct.thisKeyword, targetFunct.thisKeyword);
return ast.redirectingConstructorInvocation(
targetFunct.thisKeyword, null, null, target.argumentList);
}
throw new UnsupportedError('unsupported initializer:'
' ${initializerObject.runtimeType} :: $initializerObject'
' %% targetFunct : ${targetFunct.runtimeType} :: $targetFunct');
}
if (target is SuperExpression) {
// TODO(danrubel): Consider generating this error in the parser
// This error is also reported in the body builder
handleRecoverableError(messageInvalidSuperInInitializer,
target.superKeyword, target.superKeyword);
return ast.superConstructorInvocation(
target.superKeyword, null, null, argumentList);
} else if (target is ThisExpression) {
// TODO(danrubel): Consider generating this error in the parser
// This error is also reported in the body builder
handleRecoverableError(messageInvalidThisInInitializer,
target.thisKeyword, target.thisKeyword);
return ast.redirectingConstructorInvocation(
target.thisKeyword, null, null, argumentList);
}
throw new UnsupportedError('unsupported initializer:'
' ${initializerObject.runtimeType} :: $initializerObject'

View file

@ -1018,6 +1018,17 @@ main() { // missing async
]);
}
void test_constructor_super_cascade_synthetic() {
// https://github.com/dart-lang/sdk/issues/37110
parseCompilationUnit('class B extends A { B(): super.. {} }', errors: [
expectedError(ParserErrorCode.INVALID_SUPER_IN_INITIALIZER, 25, 5),
expectedError(ParserErrorCode.EXPECTED_TOKEN, 30, 2),
expectedError(ParserErrorCode.MISSING_IDENTIFIER, 33, 1),
expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 34, 1),
expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 36, 1),
]);
}
void test_constructor_super_field() {
// https://github.com/dart-lang/sdk/issues/36262
// https://github.com/dart-lang/sdk/issues/31198
@ -1035,6 +1046,22 @@ main() { // missing async
]);
}
void test_constructor_super_named_method() {
// https://github.com/dart-lang/sdk/issues/37600
parseCompilationUnit('class B extends A { B(): super.c().create() {} }',
errors: [
expectedError(ParserErrorCode.INVALID_SUPER_IN_INITIALIZER, 25, 5),
]);
}
void test_constructor_super_named_method_method() {
// https://github.com/dart-lang/sdk/issues/37600
parseCompilationUnit('class B extends A { B(): super.c().create().x() {} }',
errors: [
expectedError(ParserErrorCode.INVALID_SUPER_IN_INITIALIZER, 25, 5),
]);
}
void test_constructor_this_field() {
// https://github.com/dart-lang/sdk/issues/36262
// https://github.com/dart-lang/sdk/issues/31198
@ -1051,6 +1078,22 @@ main() { // missing async
]);
}
void test_constructor_this_named_method() {
// https://github.com/dart-lang/sdk/issues/37600
parseCompilationUnit('class B extends A { B(): super.c().create() {} }',
errors: [
expectedError(ParserErrorCode.INVALID_SUPER_IN_INITIALIZER, 25, 5),
]);
}
void test_constructor_this_named_method_field() {
// https://github.com/dart-lang/sdk/issues/37600
parseCompilationUnit('class B extends A { B(): super.c().create().x {} }',
errors: [
expectedError(ParserErrorCode.INVALID_SUPER_IN_INITIALIZER, 25, 5),
]);
}
@override
void test_expectedListOrMapLiteral() {
// The fasta parser returns an 'IntegerLiteralImpl' when parsing '1'.