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

Unified Diff: compiler/java/com/google/dart/compiler/parser/DartParser.java

Issue 10837286: Support new optional parameter syntax (issue 4289) (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 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: compiler/java/com/google/dart/compiler/parser/DartParser.java
===================================================================
--- compiler/java/com/google/dart/compiler/parser/DartParser.java (revision 10825)
+++ compiler/java/com/google/dart/compiler/parser/DartParser.java (working copy)
@@ -1849,16 +1849,27 @@
/**
* <pre>
* formalParameterList
- * : '(' restFormalParameter? ')'
- * | '(' namedFormalParameters ')'
- * | '(' legacyNormalFormalParameter normalFormalParameterTail? ')'
+ * : '(' ')'
+ * | '(' normalFormalParameters (',' optionalFormalParameters)? ')'
+ * | '(' optionalFormalParameters ')'
* ;
*
- * normalFormalParameterTail
- * : ',' namedFormalParameters
- * | ',' restFormalParameter
- * | ',' legacyNormalFormalParameter normalFormalParameterTail?
+ * normalFormalParameters
+ * : normalFormalParameter (',' normalFormalParameter)*
* ;
+ *
+ * optionalFormalParameters
+ * : optionalPositionalFormalParameters
+ * | namedFormalParameters
+ * ;
+ *
+ * optionalPositionalFormalParameters
+ * : '[' defaultFormalParameter (',' defaultFormalParameter)* ']'
+ * ;
+ *
+ * namedFormalParameters
+ * : '{' defaultNamedParameter (',' defaultNamedParameter)* '}'
+ * ;
* </pre>
*/
@Terminals(tokens = {Token.COMMA, Token.RPAREN})
@@ -1867,23 +1878,40 @@
List<DartParameter> params = new ArrayList<DartParameter>();
expect(Token.LPAREN);
boolean done = optional(Token.RPAREN);
+ boolean isOptional = false;
boolean isNamed = false;
while (!done) {
- if (!isNamed && optional(Token.LBRACK)) {
+ if (!isOptional && optional(Token.LBRACK)) {
+ if (isNamed) {
+ reportErrorWithoutAdvancing(ParserErrorCode.CANNOT_MIX_OPTIONAL_AND_NAMED_PARAMETERS);
+ }
+ isOptional = true;
+ }
+ if (!isNamed && optional(Token.LBRACE)) {
+ if (isOptional) {
+ reportErrorWithoutAdvancing(ParserErrorCode.CANNOT_MIX_OPTIONAL_AND_NAMED_PARAMETERS);
+ }
isNamed = true;
}
- DartParameter param = parseFormalParameter(isNamed);
+ DartParameter param = parseFormalParameter(isOptional, isNamed);
params.add(param);
- if (isNamed && optional(Token.RBRACK)) {
+ if (isOptional && optional(Token.RBRACK)) {
expectCloseParen();
break;
}
+ if (isNamed && optional(Token.RBRACE)) {
+ expectCloseParen();
+ break;
+ }
// Ensure termination if token is anything other than COMMA.
// Must keep Token.COMMA in sync with @Terminals above
if (!optional(Token.COMMA)) {
+ if (isOptional && !optional(Token.RBRACE)) {
+ reportErrorWithoutAdvancing(ParserErrorCode.MISSING_OPTIONAL_PARAMETER_END);
+ }
if (isNamed && !optional(Token.RBRACK)) {
reportErrorWithoutAdvancing(ParserErrorCode.MISSING_NAMED_PARAMETER_END);
}
@@ -1904,16 +1932,16 @@
* | simpleFormalParameter
* ;
*
- * namedFormalParameters
- * : '[' defaultFormalParameter (',' defaultFormalParameter)* ']'
- * ;
- *
* defaultFormalParameter
* : normalFormalParameter ('=' constantExpression)?
* ;
+ *
+ * defaultNamedParameter
+ * : normalFormalParameter (':' constantExpression)?
+ * ;
* </pre>
*/
- private DartParameter parseFormalParameter(boolean isNamed) {
+ private DartParameter parseFormalParameter(boolean isOptional, boolean isNamed) {
beginFormalParameter();
DartExpression paramName = null;
DartTypeNode type = null;
@@ -1922,6 +1950,11 @@
boolean hasVar = false;
Modifiers modifiers = Modifiers.NONE;
+ if (isOptional) {
+ modifiers = modifiers.makeOptional();
+ // TODO(brianwilkerson) Remove the line below when we no longer need to support the old syntax.
+ modifiers = modifiers.makeNamed();
+ }
if (isNamed) {
modifiers = modifiers.makeNamed();
}
@@ -1940,8 +1973,10 @@
} else if ((peek(0) != Token.ELLIPSIS)
&& (peek(1) != Token.COMMA)
&& (peek(1) != Token.RPAREN)
+ && (peek(1) != Token.RBRACE)
&& (peek(1) != Token.RBRACK)
&& (peek(1) != Token.ASSIGN)
+ && (peek(1) != Token.COLON)
&& (peek(1) != Token.LPAREN)
&& (peek(0) != Token.THIS)) {
// Must be a type specification.
@@ -1974,15 +2009,34 @@
switch (peek(0)) {
case COMMA:
case RPAREN:
+ case RBRACE:
case RBRACK:
// It is a simple parameter.
break;
case ASSIGN:
+ // Default parameter -- only allowed for optional parameters.
+ if (isOptional) {
+ consume(Token.ASSIGN);
+ defaultExpr = parseExpression();
+ } else if (isNamed) {
+ reportError(position(), ParserErrorCode.INVALID_SEPARATOR_FOR_NAMED);
+ consume(Token.ASSIGN);
+ defaultExpr = parseExpression();
+ } else {
+ reportError(position(), ParserErrorCode.DEFAULT_POSITIONAL_PARAMETER);
+ }
+ break;
+
+ case COLON:
// Default parameter -- only allowed for named parameters.
if (isNamed) {
- consume(Token.ASSIGN);
+ consume(Token.COLON);
defaultExpr = parseExpression();
+ } else if (isOptional) {
+ reportError(position(), ParserErrorCode.INVALID_SEPARATOR_FOR_OPTIONAL);
+ consume(Token.COLON);
+ defaultExpr = parseExpression();
} else {
reportError(position(), ParserErrorCode.DEFAULT_POSITIONAL_PARAMETER);
}

Powered by Google App Engine
This is Rietveld 408576698