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

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

Issue 10913153: Parse methods named 'get' or 'set' (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Store type annotations Created 8 years, 3 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 | « dart/lib/compiler/implementation/scanner/listener.dart ('k') | dart/tests/co19/co19-dart2js.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: dart/lib/compiler/implementation/scanner/parser.dart
diff --git a/dart/lib/compiler/implementation/scanner/parser.dart b/dart/lib/compiler/implementation/scanner/parser.dart
index 0e618a50aeaad948e4cc5e0bb315e2067be2f9e8..a5cf90c2fc14ff0dd1f26d93f2c871710c99632d 100644
--- a/dart/lib/compiler/implementation/scanner/parser.dart
+++ b/dart/lib/compiler/implementation/scanner/parser.dart
@@ -285,7 +285,6 @@ class Parser {
Token parseTypeOpt(Token token) {
String value = token.stringValue;
- if (value === 'var') return parseType(token);
if (value !== 'this') {
Token peek = peekAfterExpectedType(token);
if (isIdentifier(peek) || optional('this', peek)) {
@@ -506,16 +505,42 @@ class Parser {
Token parseTopLevelMember(Token token) {
Token start = token;
listener.beginTopLevelMember(token);
- token = parseModifiers(token);
- Token getOrSet = findGetOrSet(token);
- if (token === getOrSet) token = token.next;
- Token peek = peekAfterExpectedType(token);
- if (isIdentifier(peek)) {
- // Skip type.
- token = peek;
+
+ Link<Token> identifiers = findMemberName(token);
+ if (identifiers.isEmpty()) {
+ return listener.unexpected(start);
}
- if (token === getOrSet) token = token.next;
- token = parseIdentifier(token);
+ Token name = identifiers.head;
+ identifiers = identifiers.tail;
+ if (!identifiers.isEmpty()) {
+ if (optional('operator', identifiers.head)) {
ngeoffray 2012/09/10 14:24:49 'operator' does not apply to top level methods.
ahe 2012/09/10 19:03:02 Done.
+ name = identifiers.head;
+ identifiers = identifiers.tail;
+ }
+ }
+ Token getOrSet;
+ if (!identifiers.isEmpty()) {
+ String value = identifiers.head.stringValue;
+ if ((value === 'get') || (value === 'set')) {
+ getOrSet = identifiers.head;
+ identifiers = identifiers.tail;
+ }
+ }
+ Token type;
+ if (!identifiers.isEmpty()) {
+ if (isValidTypeReference(identifiers.head)) {
+ type = identifiers.head;
+ identifiers = identifiers.tail;
+ }
+ }
+ parseModifierList(identifiers.reverse());
+ if (type === null) {
+ listener.handleNoType(token);
+ } else {
+ parseReturnTypeOpt(type);
+ }
+ token = parseIdentifier(name);
+
bool isField;
while (true) {
// Loop to allow the listener to rewrite the token stream for
@@ -555,6 +580,39 @@ class Parser {
return token.next;
}
+ Link<Token> findMemberName(Token token) {
+ Link<Token> identifiers = const EmptyLink<Token>();
+ while (token.kind !== EOF_TOKEN) {
+ String value = token.stringValue;
+ if ((value === '(') || (value === '{') || (value === '=>')) {
+ // A method.
+ return identifiers;
+ } else if ((value === '=') || (value === ';') || (value === ',')) {
+ // A field or abstract getter.
+ return identifiers;
+ }
+ identifiers = identifiers.prepend(token);
+ if (isValidTypeReference(token)) {
+ // type ...
+ if (optional('.', token.next)) {
+ // type '.' ...
+ if (isIdentifier(token.next.next)) {
+ // type '.' identifier
+ token = token.next.next;
+ }
+ }
+ if (optional('<', token.next)) {
+ if (token.next is BeginGroupToken) {
+ BeginGroupToken beginGroup = token.next;
+ token = beginGroup.endGroup;
+ }
+ }
+ }
+ token = token.next;
+ }
+ return listener.unexpected(token);
+ }
+
Token parseVariableInitializerOpt(Token token) {
if (optional('=', token)) {
Token assignment = token;
@@ -637,6 +695,20 @@ class Parser {
return token.next;
}
+ void parseModifierList(Link<Token> tokens) {
+ int count = 0;
+ for (; !tokens.isEmpty(); tokens = tokens.tail) {
+ Token token = tokens.head;
+ if (isModifier(token)) {
+ parseModifier(token);
+ } else {
+ listener.unexpected(token);
+ }
+ count++;
+ }
+ listener.handleModifiers(count);
+ }
+
Token parseModifiers(Token token) {
int count = 0;
while (token.kind === KEYWORD_TOKEN) {
@@ -705,35 +777,6 @@ class Parser {
return (value === 'get') || (value === 'set');
}
- Token findGetOrSet(Token token) {
- if (isGetOrSet(token)) {
- if (optional('<', token.next)) {
- // For example: get<T> ...
- final Token peek = peekAfterExpectedType(token);
- if (isGetOrSet(peek) && isIdentifier(peek.next)) {
- // For example: get<T> get identifier
- return peek;
- }
- } else {
- // For example: get ...
- if (isGetOrSet(token.next) && isIdentifier(token.next.next)) {
- // For example: get get identifier
- return token.next;
- } else {
- // For example: get identifier
- return token;
- }
- }
- } else if (token.stringValue !== 'operator') {
- final Token peek = peekAfterExpectedType(token);
- if (isGetOrSet(peek) && isIdentifier(peek.next)) {
- // type? get identifier
- return peek;
- }
- }
- return null;
- }
-
Token parseMember(Token token) {
token = parseMetadataStar(token);
String value = token.stringValue;
@@ -743,19 +786,44 @@ class Parser {
}
Token start = token;
listener.beginMember(token);
- token = parseModifiers(token);
- Token getOrSet = findGetOrSet(token);
- if (token === getOrSet) token = token.next;
- Token peek = peekAfterExpectedType(token);
- if (isIdentifier(peek) && token.stringValue !== 'operator') {
- // Skip type.
- token = peek;
+
+ Link<Token> identifiers = findMemberName(token);
+ if (identifiers.isEmpty()) {
+ return listener.unexpected(start);
}
- if (token === getOrSet) token = token.next;
- if (optional('operator', token)) {
- token = parseOperatorName(token);
+ Token name = identifiers.head;
+ identifiers = identifiers.tail;
+ if (!identifiers.isEmpty()) {
+ if (optional('operator', identifiers.head)) {
+ name = identifiers.head;
+ identifiers = identifiers.tail;
+ }
+ }
+ Token getOrSet;
+ if (!identifiers.isEmpty()) {
+ if (isGetOrSet(identifiers.head)) {
+ getOrSet = identifiers.head;
+ identifiers = identifiers.tail;
+ }
+ }
+ Token type;
+ if (!identifiers.isEmpty()) {
+ if (isValidTypeReference(identifiers.head)) {
+ type = identifiers.head;
+ identifiers = identifiers.tail;
+ }
+ }
+ parseModifierList(identifiers.reverse());
+ if (type === null) {
+ listener.handleNoType(token);
} else {
- token = parseIdentifier(token);
+ parseReturnTypeOpt(type);
+ }
+
+ if (optional('operator', name)) {
+ token = parseOperatorName(name);
+ } else {
+ token = parseIdentifier(name);
}
bool isField;
while (true) {
« no previous file with comments | « dart/lib/compiler/implementation/scanner/listener.dart ('k') | dart/tests/co19/co19-dart2js.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698