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

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

Issue 8774024: Parse method names that include type variables. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 9 years, 1 month 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
diff --git a/compiler/java/com/google/dart/compiler/parser/DartParser.java b/compiler/java/com/google/dart/compiler/parser/DartParser.java
index d003a246519cda6e252fdfc8b8610a6aaa41ad40..52fc45067e17a5d50203226d17950380ab68bff8 100644
--- a/compiler/java/com/google/dart/compiler/parser/DartParser.java
+++ b/compiler/java/com/google/dart/compiler/parser/DartParser.java
@@ -770,11 +770,11 @@ public class DartParser extends CompletionHooksParserBase {
* ;
*
* namedConstructorDeclaration
- * : identifier '.' identifier formalParameterList
+ * : identifier typeArguments? '.' identifier formalParameterList
* ;
*
* constructorDeclaration
- * : identifier formalParameterList
+ * : identifier typeArguments? formalParameterList
* | namedConstructorDeclaration
* ;
*
@@ -886,33 +886,19 @@ public class DartParser extends CompletionHooksParserBase {
break;
}
- case VOID:
case IDENTIFIER: {
- // Check to see if it's a qualified ctor.
- {
- // Skip (PERIOD IDENTIFIER)* sequence.
- // Actually only one is valid, but it is OK for parser.
- int k = 1;
- while (peek(k) == Token.PERIOD && peek(k + 1) == Token.IDENTIFIER) {
mmendez 2011/12/02 13:20:13 This construct was removed, just double checking t
zundel 2011/12/02 13:46:02 It is too simplistic now, with the introduction of
- k += 2;
- }
- // If next token is LPAREN, then this is constructor.
- if (peek(k) == Token.LPAREN) {
- member = parseMethodOrAccessor(modifiers, null);
- break;
- }
- }
- // Check to see if it's a method.
- if (peek(1) == Token.LPAREN
- || peekPseudoKeyword(0, OPERATOR_KEYWORD)
- || peekPseudoKeyword(0, GETTER_KEYWORD)
- || peekPseudoKeyword(0, SETTER_KEYWORD)) {
+ // Check to see if it looks like the start of a method definition (sans type).
+ if (looksLikeMethodOrAccessorDefinition()) {
member = parseMethodOrAccessor(modifiers, null);
break;
}
+ }
+ //$FALL-THROUGH$
+
+ case VOID: {
- // The next token must be a type specification: either a method or field.
+ // The next token may be a type specification or parameterized constructor: either a method or field.
boolean isVoidType = peek(0) == Token.VOID;
DartTypeNode type = isVoidType ? parseVoidType() : parseTypeAnnotation();
if (peek(1) == Token.SEMICOLON
@@ -943,6 +929,70 @@ public class DartParser extends CompletionHooksParserBase {
}
/**
+ * Returns true if the beginning of a method definition follows.
+ *
+ * This test is needed to disambiguate between a method that returns a type
+ * and a plain method.
+ *
+ * Assumes the next token has already been determined to be an identifier.
+ *
+ * The following constructs will match:
+ *
+ * : get
+ * | set
+ * | operator
+ * | identifier typeArguments? DOT identifier (
+ * | identifier DOT identifier typeArguments DOT identifier (
+ * | identifier typeArguments? (
+ *
+ * @return <code>true</code> if the signature of a method has been found. No tokens are consumed.
+ */
+ private boolean looksLikeMethodOrAccessorDefinition() {
+ assert (peek(0).equals(Token.IDENTIFIER));
+ startLookahead(); // begin() equivalent
+ try {
+ // Simple checks
+ if (peekPseudoKeyword(0, GETTER_KEYWORD)
+ || peekPseudoKeyword(0, SETTER_KEYWORD)
+ || peekPseudoKeyword(0, OPERATOR_KEYWORD)) {
+ return true;
+ }
+
+ consume(Token.IDENTIFIER);
+
+ if (peek(0).equals(Token.PERIOD) && peek(1).equals(Token.IDENTIFIER)) {
+ // Case 1 a constructor of the form class.id
+ if (peek(0).equals(Token.LPAREN)) {
mmendez 2011/12/02 13:20:13 Is this code reachable? Haven't you already check
zundel 2011/12/02 13:46:02 Removed
+ return true;
+ }
+
+ // Case 2, a constructor of the form library.class.<typearguments?>.id
+ consume(Token.PERIOD);
+ consume(Token.IDENTIFIER);
+ parseTypeArgumentsOpt();
+ if (peek(0).equals(Token.PERIOD) && peek(1).equals(Token.IDENTIFIER) && peek(2).equals(Token.LPAREN)) {
mmendez 2011/12/02 13:20:13 Nit: long line
zundel 2011/12/02 13:46:02 Done.
+ return true;
+ }
+ }
+
+ // Case 1 class.id<typearguments>
+ // Case 3, id<typearguments?>
+ parseTypeArgumentsOpt();
mmendez 2011/12/02 13:20:13 Nit: with this code flow you could allow x.y<...>.
zundel 2011/12/02 13:46:02 I think it would accept x.y.<...><...>.z but rega
+
+ if (peek(0).equals(Token.PERIOD) && peek(1).equals(Token.IDENTIFIER)) {
+ // Case 1, a constructor of the form class<typearguments>.id
+ consume(Token.PERIOD);
+ consume(Token.IDENTIFIER);
+ }
+
+ // next token should be LPAREN
+ return (peek(0).equals(Token.LPAREN));
+ } finally {
+ rollback();
+ }
+ }
+
+ /**
* <pre>
* factoryConstructorDeclaration
* : FACTORY qualified ('.' identifier)? formalParameterList
@@ -1039,6 +1089,9 @@ public class DartParser extends CompletionHooksParserBase {
} else {
// Normal method or property.
name = parseIdentifier();
+
+ // TODO(zundel): something constructive with the type arguments
+ parseTypeArgumentsOpt();
mmendez 2011/12/02 13:20:13 Nit: ws
}
// Check for named constructor.
@@ -1155,7 +1208,7 @@ public class DartParser extends CompletionHooksParserBase {
* : (THIS '.')? identifier '=' conditionalExpression
* | THIS ('.' identifier)? arguments
* ;
- * </pre>
+ * </pre>
* @return true if initializer is a redirected constructor, false otherwise.
*/
private void parseInitializers(List<DartInitializer> initializers) {
@@ -2302,7 +2355,7 @@ public class DartParser extends CompletionHooksParserBase {
case NEW: {
beginNewExpression(); // DartNewExpression
consume(Token.NEW);
- return done(parseConstructor(false));
+ return done(parseConstructorInvocation(false));
}
case CONST: {
@@ -2313,7 +2366,7 @@ public class DartParser extends CompletionHooksParserBase {
if (literal != null) {
return done(literal);
}
- return done(parseConstructor(true));
+ return done(parseConstructorInvocation(true));
}
case LPAREN: {
@@ -2349,7 +2402,7 @@ public class DartParser extends CompletionHooksParserBase {
}
}
- private DartExpression parseConstructor(boolean isConst) {
+ private DartExpression parseConstructorInvocation(boolean isConst) {
List<DartTypeNode> parts = new ArrayList<DartTypeNode>();
beginConstructor();
do {

Powered by Google App Engine
This is Rietveld 408576698