Store resolution for catch with invalid parameters.

R=brianwilkerson@google.com, paulberry@google.com

Change-Id: I7137eca832b83a352e130d6f3041679611c7c117
Reviewed-on: https://dart-review.googlesource.com/66721
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Konstantin Shcheglov 2018-07-25 21:25:55 +00:00 committed by commit-bot@chromium.org
parent 54d46b801a
commit 372a24cb7c
7 changed files with 96 additions and 11 deletions

View file

@ -170,6 +170,7 @@ const List<ErrorCode> errorCodeValues = const [
CompileTimeErrorCode.INVALID_ANNOTATION,
CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY,
CompileTimeErrorCode.INVALID_ANNOTATION_GETTER,
CompileTimeErrorCode.INVALID_CATCH_ARGUMENTS,
CompileTimeErrorCode.INVALID_CONSTANT,
CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME,
CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS,

View file

@ -1470,6 +1470,9 @@ class CompileTimeErrorCode extends ErrorCode {
'INVALID_ANNOTATION_GETTER', "Getters cannot be used as annotations.",
correction: "Try using a top-level variable or a field.");
static const CompileTimeErrorCode INVALID_CATCH_ARGUMENTS =
const CompileTimeErrorCode.fromFasta('INVALID_CATCH_ARGUMENTS');
/**
* 15.31 Identifier Reference: It is a compile-time error if any of the
* identifiers async, await or yield is used as an identifier in a function

View file

@ -3518,6 +3518,55 @@ const bool b = a;
assertType(aRef, 'int');
}
test_invalid_catch_parameters_3() async {
addTestFile(r'''
main() {
try { } catch (x, y, z) { }
}
''');
await resolveTestFile();
expect(result.errors, isNotEmpty);
assertTypeDynamic(findNode.simple('x,'));
assertType(findNode.simple('y,'), 'StackTrace');
}
test_invalid_catch_parameters_empty() async {
addTestFile(r'''
main() {
try { } catch () { }
}
''');
await resolveTestFile();
expect(result.errors, isNotEmpty);
}
test_invalid_catch_parameters_named_stack() async {
addTestFile(r'''
main() {
try { } catch (e, {s}) { }
}
''');
await resolveTestFile();
expect(result.errors, isNotEmpty);
assertTypeDynamic(findNode.simple('e,'));
assertType(findNode.simple('s})'), useCFE ? 'StackTrace' : 'dynamic');
}
test_invalid_catch_parameters_optional_stack() async {
addTestFile(r'''
main() {
try { } catch (e, [s]) { }
}
''');
await resolveTestFile();
expect(result.errors, isNotEmpty);
assertTypeDynamic(findNode.simple('e,'));
assertType(findNode.simple('s])'), useCFE ? 'StackTrace' : 'dynamic');
}
test_invalid_const_methodInvocation() async {
addTestFile(r'''
const a = 'foo';

View file

@ -4302,6 +4302,16 @@ Message _withArgumentsInvalidCastTopLevelFunction(
arguments: {'type': _type, 'type2': _type2});
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeInvalidCatchArguments = messageInvalidCatchArguments;
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const MessageCode messageInvalidCatchArguments = const MessageCode(
"InvalidCatchArguments",
analyzerCode: "INVALID_CATCH_ARGUMENTS",
dart2jsCode: "*fatal*",
message: r"""Invalid catch arguments.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeInvalidCodePoint = messageInvalidCodePoint;

View file

@ -914,7 +914,7 @@ abstract class BodyBuilder extends ScopeListener<JumpTarget>
enterLocalScope(
null,
new FormalParameters<Expression, Statement, Arguments>(
parameters.positionalParameters, null, -1)
parameters.positionalParameters, null, -1, 0)
.computeFormalParameterScope(scope, member, this));
token = parser.parseExpression(parser.syntheticPreviousToken(token));
@ -2506,7 +2506,10 @@ abstract class BodyBuilder extends ScopeListener<JumpTarget>
popList(count, variables);
FormalParameters<Expression, Statement, Arguments> formals =
new FormalParameters<Expression, Statement, Arguments>(
variables, optional, beginToken.charOffset);
variables,
optional,
beginToken.charOffset,
endToken.end - beginToken.charOffset);
constantContext = pop();
push(formals);
if ((inCatchClause || functionNestingLevel != 0) &&
@ -2557,14 +2560,25 @@ abstract class BodyBuilder extends ScopeListener<JumpTarget>
stackTrace, coreTypes.stackTraceClass.rawType);
}
} else {
body = forest.block(
catchKeyword,
<Statement>[
compileTimeErrorInTry ??=
deprecated_buildCompileTimeErrorStatement(
"Invalid catch arguments.", catchKeyword.next.charOffset)
],
null);
buildCompileTimeError(fasta.messageInvalidCatchArguments,
catchParameters.charOffset, catchParameters.charLength);
var allFormals = <VariableDeclaration>[];
allFormals.addAll(catchParameters.required);
if (catchParameters.optional != null) {
allFormals.addAll(catchParameters.optional.formals);
}
var allCount = allFormals.length;
if (allCount >= 1) {
exception = allFormals[0];
forest.setParameterType(exception, type);
}
if (allCount >= 2) {
stackTrace = allFormals[1];
forest.setParameterType(
stackTrace, coreTypes.stackTraceClass.rawType);
}
}
}
push(forest.catchClause(onKeyword, type, catchKeyword, exception,
@ -4614,8 +4628,10 @@ class FormalParameters<Expression, Statement, Arguments> {
final List<VariableDeclaration> required;
final OptionalFormals optional;
final int charOffset;
final int charLength;
FormalParameters(this.required, this.optional, this.charOffset);
FormalParameters(
this.required, this.optional, this.charOffset, this.charLength);
FunctionNode addToFunction(FunctionNode function) {
function.requiredParameterCount = required.length;

View file

@ -203,6 +203,7 @@ InvalidCastLocalFunction/example: Fail
InvalidCastNewExpr/example: Fail
InvalidCastStaticMethod/example: Fail
InvalidCastTopLevelFunction/example: Fail
InvalidCatchArguments/example: Fail
InvalidInitializer/example: Fail
InvalidInlineFunctionType/analyzerCode: Fail
InvalidPackageUri/analyzerCode: Fail

View file

@ -2455,6 +2455,11 @@ InvalidCastTopLevelFunction:
analyzerCode: INVALID_CAST_FUNCTION
dart2jsCode: "*ignored*"
InvalidCatchArguments:
template: "Invalid catch arguments."
analyzerCode: INVALID_CATCH_ARGUMENTS
dart2jsCode: "*fatal*"
InvalidUseOfNullAwareAccess:
template: "Cannot use '?.' here."
tip: "Try using '.'."