Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1294)

Unified Diff: pkg/front_end/lib/src/fasta/parser/parser.dart

Issue 2926953004: Various semantic checks on formal parameters. (Closed)
Patch Set: Added missing FASTA_IGNORED and rebased on aa8ca9244a3cc5fa7c3816a9340558e7d2f37ae1. Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/front_end/lib/src/fasta/parser/parser.dart
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index f95b1edd485c2545dcf0ce01db269d3c473939b8..61e9506ee85292badebb4c7b7777e84946fbe566 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -18,6 +18,7 @@ import '../fasta_codes.dart'
codeAwaitNotAsync,
codeBuiltInIdentifierAsType,
codeBuiltInIdentifierInDeclaration,
+ codeCatchSyntax,
codeEmptyNamedParameterList,
codeEmptyOptionalParameterList,
codeEncoding,
@@ -34,15 +35,19 @@ import '../fasta_codes.dart'
codeExpectedString,
codeExtraneousModifier,
codeFactoryNotSync,
+ codeFunctionTypeDefaultValue,
codeGeneratorReturnsValue,
+ codeGetterWithFormals,
codeInvalidAwaitFor,
codeInvalidInlineFunctionType,
codeInvalidSyncModifier,
codeInvalidVoid,
+ codeNoFormals,
codeNonAsciiIdentifier,
codeNonAsciiWhitespace,
codeOnlyTry,
codePositionalParameterWithEquals,
+ codePrivateNamedParameter,
codeRequiredParameterWithDefault,
codeSetterNotSync,
codeStackOverflow,
@@ -716,6 +721,7 @@ class Parser {
Token nameToken;
if (inFunctionType) {
if (isNamedParameter || token.isIdentifier) {
+ nameToken = token;
token = parseIdentifier(
token, IdentifierContext.formalParameterDeclaration);
} else {
@@ -733,6 +739,9 @@ class Parser {
token, IdentifierContext.formalParameterDeclaration);
}
}
+ if (isNamedParameter && nameToken.lexeme.startsWith("_")) {
+ reportRecoverableErrorCode(nameToken, codePrivateNamedParameter);
+ }
token = listener.injectGenericCommentTypeList(token);
if (optional('(', token)) {
@@ -764,7 +773,6 @@ class Parser {
}
String value = token.stringValue;
if ((identical('=', value)) || (identical(':', value))) {
- // TODO(ahe): Validate that these are only used for optional parameters.
Token equal = token;
token = parseExpression(token.next);
listener.handleValuedFormalParameter(equal, token);
@@ -772,6 +780,10 @@ class Parser {
reportRecoverableErrorCode(equal, codeRequiredParameterWithDefault);
} else if (parameterKind.isPositional && identical(':', value)) {
reportRecoverableErrorCode(equal, codePositionalParameterWithEquals);
+ } else if (inFunctionType ||
+ memberKind == MemberKind.FunctionTypeAlias ||
+ memberKind == MemberKind.FunctionTypedParameter) {
+ reportRecoverableErrorCode(equal.next, codeFunctionTypeDefaultValue);
}
} else {
listener.handleFormalParameterWithoutValue(token);
@@ -1375,11 +1387,14 @@ class Parser {
Token token =
parseIdentifier(name, IdentifierContext.topLevelFunctionDeclaration);
+ bool isGetter = false;
if (getOrSet == null) {
token = parseTypeVariablesOpt(token);
} else {
+ isGetter = optional("get", getOrSet);
listener.handleNoTypeVariables(token);
}
+ checkFormals(isGetter, name, token);
token = parseFormalParametersOpt(token, MemberKind.TopLevelMethod);
AsyncModifier savedAsyncModifier = asyncState;
Token asyncToken = token;
@@ -1395,6 +1410,16 @@ class Parser {
return token;
}
+ void checkFormals(bool isGetter, Token name, Token token) {
+ if (optional("(", token)) {
+ if (isGetter) {
+ reportRecoverableErrorCode(token, codeGetterWithFormals);
+ }
+ } else if (!isGetter) {
+ reportRecoverableErrorCodeWithToken(name, codeNoFormals);
+ }
+ }
+
/// Looks ahead to find the name of a member. Returns a link of the modifiers,
/// set/get, (operator) name, and either the start of the method body or the
/// end of the declaration.
@@ -1694,7 +1719,10 @@ class Parser {
}
typeRequired = false;
} else if (optional("static", token)) {
- if (memberKind == MemberKind.NonStaticMethod) {
+ if (parameterKind != null) {
+ reportRecoverableErrorCodeWithToken(
+ token, codeExtraneousModifier);
+ } else if (memberKind == MemberKind.NonStaticMethod) {
memberKind = MemberKind.StaticMethod;
} else if (memberKind == MemberKind.NonStaticField) {
memberKind = MemberKind.StaticField;
@@ -2070,11 +2098,14 @@ class Parser {
token = parseQualifiedRestOpt(
token, IdentifierContext.methodDeclarationContinuation);
+ bool isGetter = false;
if (getOrSet == null) {
token = parseTypeVariablesOpt(token);
} else {
+ isGetter = optional("get", getOrSet);
listener.handleNoTypeVariables(token);
}
+ checkFormals(isGetter, name, token);
token = parseFormalParametersOpt(
token,
staticModifier != null
@@ -3660,7 +3691,24 @@ class Parser {
Token catchKeyword = null;
if (identical(value, 'catch')) {
catchKeyword = token;
- // TODO(ahe): Validate the "parameters".
+ Token openParens = catchKeyword.next;
+ Token exceptionName = openParens.next;
+ Token commaOrCloseParens = exceptionName.next;
+ Token traceName = commaOrCloseParens.next;
+ Token closeParens = traceName.next;
+ if (!optional("(", openParens)) {
+ // Handled below by parseFormalParameters.
+ } else if (!exceptionName.isIdentifier) {
+ reportRecoverableErrorCode(exceptionName, codeCatchSyntax);
+ } else if (optional(")", commaOrCloseParens)) {
+ // OK: `catch (identifier)`.
+ } else if (!optional(",", commaOrCloseParens)) {
+ reportRecoverableErrorCode(exceptionName, codeCatchSyntax);
+ } else if (!traceName.isIdentifier) {
+ reportRecoverableErrorCode(exceptionName, codeCatchSyntax);
+ } else if (!optional(")", closeParens)) {
+ reportRecoverableErrorCode(exceptionName, codeCatchSyntax);
+ }
token = parseFormalParameters(token.next, MemberKind.Catch);
}
listener.endCatchClause(token);

Powered by Google App Engine
This is Rietveld 408576698