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); |