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

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

Issue 11776037: Initial support for mixins in dartc. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Forgot MixinScope.java Created 7 years, 11 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
diff --git a/compiler/java/com/google/dart/compiler/parser/DartParser.java b/compiler/java/com/google/dart/compiler/parser/DartParser.java
index d0615c55e8b46dfa1b49f6f694aaf87f4ca7cfa8..7ff83e9f8421b7a6cb725d59fba1a1a61d21df63 100644
--- a/compiler/java/com/google/dart/compiler/parser/DartParser.java
+++ b/compiler/java/com/google/dart/compiler/parser/DartParser.java
@@ -28,6 +28,7 @@ import com.google.dart.compiler.ast.DartCascadeExpression;
import com.google.dart.compiler.ast.DartCase;
import com.google.dart.compiler.ast.DartCatchBlock;
import com.google.dart.compiler.ast.DartClass;
+import com.google.dart.compiler.ast.DartClassTypeAlias;
import com.google.dart.compiler.ast.DartConditional;
import com.google.dart.compiler.ast.DartContinueStatement;
import com.google.dart.compiler.ast.DartDeclaration;
@@ -351,7 +352,7 @@ public class DartParser extends CompletionHooksParserBase {
} else if (peekPseudoKeyword(0, TYPEDEF_KEYWORD)
&& (peek(1).equals(Token.IDENTIFIER) || peek(1).equals(Token.VOID))) {
consume(Token.IDENTIFIER);
- node = done(parseFunctionTypeAlias());
+ node = done(parseTypeAlias());
} else if (looksLikeDirective()) {
reportErrorWithoutAdvancing(ParserErrorCode.DIRECTIVE_OUT_OF_ORDER);
metadata = parseDirectives(unit, metadata);
@@ -977,22 +978,62 @@ public class DartParser extends CompletionHooksParserBase {
// Parse the extends and implements clauses.
DartTypeNode superType = null;
+ int withOffset = -1;
int implementsOffset = -1;
+ List<DartTypeNode> mixins = null;
List<DartTypeNode> interfaces = null;
if (isParsingInterface) {
if (optional(Token.EXTENDS)) {
interfaces = parseTypeAnnotationList();
}
} else {
- if (optional(Token.EXTENDS)) {
- superType = parseTypeAnnotation();
+ boolean foundClause = true;
+ while (foundClause) {
+ if (optional(Token.EXTENDS)) {
+ if (mixins != null) {
+ reportErrorAtPosition(withOffset, withOffset + "with".length(),
+ ParserErrorCode.WITH_BEFORE_EXTENDS);
+ }
+ if (interfaces != null) {
+ reportErrorAtPosition(implementsOffset, implementsOffset + "implements".length(),
+ ParserErrorCode.IMPLEMENTS_BEFORE_EXTENDS);
+ }
+ if (superType == null) {
+ superType = parseTypeAnnotation();
+ } else {
+ reportError(position(), ParserErrorCode.MULTIPLE_EXTENDS_CLAUSES);
+ parseTypeAnnotation();
+ }
+ } else if (optional(Token.WITH)) {
+ if (mixins == null) {
+ withOffset = position();
+ mixins = parseTypeAnnotationList();
+ if (interfaces != null) {
+ reportErrorAtPosition(implementsOffset, implementsOffset + "implements".length(),
+ ParserErrorCode.IMPLEMENTS_BEFORE_WITH);
+ }
+ } else {
+ reportError(position(), ParserErrorCode.MULTIPLE_WITH_CLAUSES);
+ parseTypeAnnotationList();
+ }
+ } else if (optionalPseudoKeyword(IMPLEMENTS_KEYWORD)) {
+ if (interfaces == null) {
+ implementsOffset = position();
+ interfaces = parseTypeAnnotationList();
+ } else {
+ reportError(position(), ParserErrorCode.MULTIPLE_IMPLEMENTS_CLAUSES);
+ parseTypeAnnotationList();
+ }
+ } else {
+ foundClause = false;
+ }
}
- if (optionalPseudoKeyword(IMPLEMENTS_KEYWORD)) {
- implementsOffset = position();
- interfaces = parseTypeAnnotationList();
+ if (mixins != null && superType == null) {
+ reportErrorAtPosition(withOffset, withOffset + "with".length(),
+ ParserErrorCode.WITH_WITHOUT_EXTENDS);
}
}
-
+
// Deal with factory clause for interfaces.
DartParameterizedTypeNode defaultClass = null;
int defaultTokenOffset = -1;
@@ -1036,13 +1077,13 @@ public class DartParser extends CompletionHooksParserBase {
}
if (isParsingInterface) {
- return done(new DartClass(tokenOffset, tokenLength, name, superType, implementsOffset,
- interfaces, defaultTokenOffset, openBraceOffset, closeBraceOffset, members,
- typeParameters, defaultClass));
+ return done(new DartClass(tokenOffset, tokenLength, name, null, superType, implementsOffset,
+ interfaces, mixins, defaultTokenOffset, openBraceOffset, closeBraceOffset, members,
+ typeParameters, defaultClass, true, Modifiers.NONE));
} else {
return done(new DartClass(tokenOffset, tokenLength, name, nativeName, superType,
- implementsOffset, interfaces, defaultTokenOffset, openBraceOffset, closeBraceOffset,
- members, typeParameters, modifiers));
+ implementsOffset, interfaces, mixins, defaultTokenOffset, openBraceOffset,
+ closeBraceOffset, members, typeParameters, null, false, modifiers));
}
}
@@ -1148,37 +1189,128 @@ public class DartParser extends CompletionHooksParserBase {
}
/**
+ * Parse a type alias.
+ *
+ * <pre>
+ * typeAlias ::=
+ * 'typedef' typeAliasBody
+ *
+ * typeAliasBody ::=
+ * classTypeAlias
+ * | functionTypeAlias
+ *
+ * classTypeAlias ::=
+ * identifier typeParameters? '=' 'abstract'? mixinApplication
+ *
+ * mixinApplication ::=
+ * qualified withClause implementsClause? ';'
+ *
+ * functionTypeAlias ::=
+ * functionPrefix typeParameterList? formalParameterList ';'
+ *
+ * functionPrefix ::=
+ * returnType? name
+ * </pre>
+ *
+ * @return the type alias that was parsed
+ */
+ private DartNodeWithMetadata parseTypeAlias() {
+ if (match(Token.IDENTIFIER)) {
+ Token next = peek(1);
+ if (next == Token.LT) {
+ int offset = skipTypeArguments(1, new DepthCounter());
+ next = peek(offset);
+ if (next != null && next == Token.ASSIGN) {
+ return parseClassTypeAlias();
+ }
+ } else if (next == Token.ASSIGN) {
+ return parseClassTypeAlias();
+ }
+ }
+ return parseFunctionTypeAlias();
+ }
+
+ /**
+ * Parse a class type alias.
+ *
+ * <pre>
+ * classTypeAlias ::=
+ * identifier typeParameters? '=' 'abstract'? mixinApplication
+ *
+ * mixinApplication ::=
+ * type withClause implementsClause? ';'
+ * </pre>
+ *
+ * @return the class type alias that was parsed
+ */
+ private DartClassTypeAlias parseClassTypeAlias() {
+ beginClassTypeInterface();
+
+ Modifiers modifiers = Modifiers.NONE;
+ if (optionalPseudoKeyword(ABSTRACT_KEYWORD)) {
+ modifiers = modifiers.makeAbstract();
+ }
+
+ DartIdentifier name = parseIdentifier();
+ if (PSEUDO_KEYWORDS_SET.contains(name.getName())) {
+ reportError(name, ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
+ }
+ List<DartTypeParameter> typeParameters = parseTypeParametersOpt();
+
+ expect(Token.ASSIGN);
+
+ DartTypeNode superType = parseTypeAnnotation();
+
+ List<DartTypeNode> mixins = null;
+ if (optional(Token.WITH)) {
+ mixins = parseTypeAnnotationList();
+ }
+
+ List<DartTypeNode> interfaces = null;
+ if (optionalPseudoKeyword(IMPLEMENTS_KEYWORD)) {
+ interfaces = parseTypeAnnotationList();
+ }
+
+ expect(Token.SEMICOLON);
+ return done(new DartClassTypeAlias(name, typeParameters, modifiers, superType, mixins,
+ interfaces));
+ }
+
+ /**
+ * Parse a function type alias.
+ *
* <pre>
- * functionTypeAlias
- * : TYPEDEF functionPrefix typeParameters?
- * formalParameterList ';'
+ * functionTypeAlias ::=
+ * functionPrefix typeParameterList? formalParameterList ';'
*
- * functionPrefix
- * : returnType? identifier
+ * functionPrefix ::=
+ * returnType? name
* </pre>
+ *
+ * @return the function type alias that was parsed
*/
private DartFunctionTypeAlias parseFunctionTypeAlias() {
beginFunctionTypeInterface();
-
+
DartTypeNode returnType = null;
if (peek(0) == Token.VOID) {
returnType = parseVoidType();
} else if (!isFunctionTypeAliasName()) {
returnType = parseTypeAnnotation();
}
-
+
DartIdentifier name = parseIdentifier();
if (PSEUDO_KEYWORDS_SET.contains(name.getName())) {
reportError(name, ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
}
-
+
List<DartTypeParameter> typeParameters = parseTypeParametersOpt();
FormalParameters params = parseFormalParameterList();
expect(Token.SEMICOLON);
validateNoDefaultParameterValues(
params.val,
ParserErrorCode.DEFAULT_VALUE_CAN_NOT_BE_SPECIFIED_IN_TYPEDEF);
-
+
return done(new DartFunctionTypeAlias(name, returnType, params.val, typeParameters));
}

Powered by Google App Engine
This is Rietveld 408576698