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

Unified Diff: lib/compiler/implementation/scanner/parser.dart

Issue 10829334: Const variable declarations accepted in the parser. (Closed) Base URL: https://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
« no previous file with comments | « no previous file | tests/co19/co19-dart2js.status » ('j') | tests/language/const_var_test.dart » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/compiler/implementation/scanner/parser.dart
diff --git a/lib/compiler/implementation/scanner/parser.dart b/lib/compiler/implementation/scanner/parser.dart
index db3da46975f8984bce763df3da39552172d67443..41cedc126c0d6156488aff5ae4529502fee5da9c 100644
--- a/lib/compiler/implementation/scanner/parser.dart
+++ b/lib/compiler/implementation/scanner/parser.dart
@@ -150,7 +150,7 @@ class Parser {
String value = token.stringValue;
if (value === 'var') return parseType(token);
if (value !== 'this') {
- Token peek = peekAfterType(token);
+ Token peek = peekAfterExpectedType(token);
if (isIdentifier(peek) || optional('this', peek)) {
return parseType(token);
}
@@ -351,7 +351,7 @@ class Parser {
token = parseModifiers(token);
Token getOrSet = findGetOrSet(token);
if (token === getOrSet) token = token.next;
- Token peek = peekAfterType(token);
+ Token peek = peekAfterExpectedType(token);
if (isIdentifier(peek)) {
// Skip type.
token = peek;
@@ -463,13 +463,18 @@ class Parser {
return expect(';', token);
}
+ bool isModifier(Token token) {
+ final String value = token.stringValue;
+ return ('final' === value) ||
+ ('var' === value) ||
+ ('const' === value) ||
+ ('abstract' === value) ||
+ ('static' === value) ||
+ ('external' === value);
+ }
+
Token parseModifier(Token token) {
- assert(('final' === token.stringValue) ||
- ('var' === token.stringValue) ||
- ('const' === token.stringValue) ||
- ('abstract' === token.stringValue) ||
- ('static' === token.stringValue) ||
- ('external' === token.stringValue));
+ assert(isModifier(token));
listener.handleModifier(token);
return token.next;
}
@@ -477,13 +482,7 @@ class Parser {
Token parseModifiers(Token token) {
int count = 0;
while (token.kind === KEYWORD_TOKEN) {
- final String value = token.stringValue;
- if (('final' !== value) &&
- ('var' !== value) &&
- ('const' !== value) &&
- ('abstract' !== value) &&
- ('static' !== value) &&
- ('external' !== value))
+ if (!isModifier(token))
break;
token = parseModifier(token);
count++;
@@ -494,9 +493,6 @@ class Parser {
Token peekAfterType(Token token) {
// TODO(ahe): Also handle var?
- if ('void' !== token.stringValue && !isIdentifier(token)) {
- listener.unexpected(token);
- }
// We are looking at "identifier ...".
Token peek = token.next;
if (peek.kind === PERIOD_TOKEN) {
@@ -519,6 +515,17 @@ class Parser {
return peek;
}
+ /**
+ * Returns the token after the type which is expected to begin at [token].
+ * If [token] is not the start of a type, [Listener.unexpectedType] is called.
+ */
+ Token peekAfterExpectedType(Token token) {
+ if ('void' !== token.stringValue && !isIdentifier(token)) {
+ return listener.expectedType(token);
+ }
+ return peekAfterType(token);
+ }
+
Token parseClassBody(Token token) {
Token begin = token;
listener.beginClassBody(token);
@@ -544,7 +551,7 @@ class Parser {
if (isGetOrSet(token)) {
if (optional('<', token.next)) {
// For example: get<T> ...
- final Token peek = peekAfterType(token);
+ final Token peek = peekAfterExpectedType(token);
if (isGetOrSet(peek) && isIdentifier(peek.next)) {
// For example: get<T> get identifier
return peek;
@@ -560,7 +567,7 @@ class Parser {
}
}
} else if (token.stringValue !== 'operator') {
- final Token peek = peekAfterType(token);
+ final Token peek = peekAfterExpectedType(token);
if (isGetOrSet(peek) && isIdentifier(peek.next)) {
// type? get identifier
return peek;
@@ -580,7 +587,7 @@ class Parser {
token = parseModifiers(token);
Token getOrSet = findGetOrSet(token);
if (token === getOrSet) token = token.next;
- Token peek = peekAfterType(token);
+ Token peek = peekAfterExpectedType(token);
if (isIdentifier(peek) && token.stringValue !== 'operator') {
// Skip type.
token = peek;
@@ -791,6 +798,8 @@ class Parser {
return parseContinueStatement(token);
} else if (value === ';') {
return parseEmptyStatement(token);
+ } else if (value === 'const') {
+ return parseExpressionStatementOrConstDeclaration(token);
} else if (isIdentifier(token)) {
return parseExpressionStatementOrDeclaration(token);
} else {
@@ -822,6 +831,19 @@ class Parser {
}
}
+ Token peekIdentifierAfterTypeOpt(Token token) {
Johnni Winther 2012/08/15 12:58:21 Rename to peekIdentifierAfterOptionalType
Johnni Winther 2012/08/15 13:59:18 Done.
+ Token peek = peekIdentifierAfterType(token);
+ if (peek !== null) {
+ // We are looking at "type identifier".
+ return peek;
+ } else if (isIdentifier(token)) {
+ // We are looking at "identifier".
+ return token;
+ } else {
+ return null;
+ }
+ }
+
Token parseExpressionStatementOrDeclaration(Token token) {
assert(isIdentifier(token) || token.stringValue === 'void');
Token identifier = peekIdentifierAfterType(token);
@@ -860,6 +882,27 @@ class Parser {
return parseExpressionStatement(token);
}
+ Token parseExpressionStatementOrConstDeclaration(Token token) {
+ assert(token.stringValue === 'const');
+ if (isModifier(token.next)) {
+ return parseVariablesDeclaration(token);
+ }
+ Token identifier = peekIdentifierAfterTypeOpt(token.next);
+ if (identifier !== null) {
+ assert(isIdentifier(identifier));
+ Token afterId = identifier.next;
+ int afterIdKind = afterId.kind;
+ if (afterIdKind === EQ_TOKEN ||
+ afterIdKind === SEMICOLON_TOKEN ||
+ afterIdKind === COMMA_TOKEN) {
+ // We are looking at "const type identifier" followed by '=', ';', ','.
Johnni Winther 2012/08/15 12:58:21 ';', or ','
Johnni Winther 2012/08/15 13:59:18 Done.
+ return parseVariablesDeclaration(token);
+ }
+ // Fall-through to expression statement.
+ }
+ return parseExpressionStatement(token);
+ }
+
Token parseLabel(Token token) {
token = parseIdentifier(token);
Token colon = token;
@@ -1213,7 +1256,7 @@ class Parser {
Token parseSendOrFunctionLiteral(Token token) {
if (!mayParseFunctionExpressions) return parseSend(token);
- Token peek = peekAfterType(token);
+ Token peek = peekAfterExpectedType(token);
if (peek.kind === IDENTIFIER_TOKEN && isFunctionDeclaration(peek.next)) {
return parseFunctionExpression(token);
} else if (isFunctionDeclaration(token.next)) {
« no previous file with comments | « no previous file | tests/co19/co19-dart2js.status » ('j') | tests/language/const_var_test.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698