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

Unified Diff: pkg/compiler/lib/src/parser/listener.dart

Issue 1311783012: Split parser/listener.dart, parser/class_element_listener.dart and tokens/token.dart into smaller l… (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 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
Index: pkg/compiler/lib/src/parser/listener.dart
diff --git a/pkg/compiler/lib/src/parser/listener.dart b/pkg/compiler/lib/src/parser/listener.dart
index 145264193a261e5d5027e7b42d86fad0e4548b78..5252d469e4fe5a7f9f11886b708d10a3aa56a015 100644
--- a/pkg/compiler/lib/src/parser/listener.dart
+++ b/pkg/compiler/lib/src/parser/listener.dart
@@ -4,69 +4,22 @@
library dart2js.parser.listener;
-import '../compiler.dart' show
- Compiler;
-import '../dart_types.dart' show DynamicType;
-import '../diagnostics/diagnostic_listener.dart';
-import '../diagnostics/invariant.dart' show
- invariant;
import '../diagnostics/messages.dart';
import '../diagnostics/spannable.dart' show
Spannable,
SpannableAssertionFailure;
-import '../elements/elements.dart' show
- CompilationUnitElement,
- ConstructorElement,
- Element,
- ElementKind,
- GetterElement,
- LibraryElement,
- MetadataAnnotation,
- MethodElement,
- SetterElement;
-import '../elements/modelx.dart' show
- BaseFunctionElementX,
- ConstructorElementX,
- CompilationUnitElementX,
- DeclarationSite,
- ElementX,
- EnumClassElementX,
- FieldElementX,
- GetterElementX,
- LibraryElementX,
- MetadataAnnotationX,
- MethodElementX,
- MixinApplicationElementX,
- SetterElementX,
- TypedefElementX,
- VariableList;
-import '../native/native.dart' as native;
-import '../string_validator.dart' show
- StringValidator;
-import '../tokens/keyword.dart' show
- Keyword;
+import '../tokens/precedence_constants.dart' as Precedence show
+ EOF_INFO,
+ IDENTIFIER_INFO;
import '../tokens/token.dart' show
- BAD_INPUT_INFO,
BadInputToken,
BeginGroupToken,
- EOF_INFO,
- EOF_TOKEN,
ErrorToken,
- IDENTIFIER_INFO,
- INDEX_INFO,
- KeywordToken,
StringToken,
Token,
UnmatchedToken,
UnterminatedToken;
import '../tree/tree.dart';
-import '../util/util.dart' show
- Link;
-
-import 'class_element_parser.dart' show
- PartialClassElement;
-import 'parser.dart' show
- Parser;
const bool VERBOSE = false;
@@ -644,7 +597,8 @@ class Listener {
Token synthesizeIdentifier(Token token) {
Token synthesizedToken =
- new StringToken.fromString(IDENTIFIER_INFO, '?', token.charOffset);
+ new StringToken.fromString(
+ Precedence.IDENTIFIER_INFO, '?', token.charOffset);
synthesizedToken.next = token.next;
return synthesizedToken;
}
@@ -740,7 +694,7 @@ class Listener {
}
skipToEof(Token token) {
- while (!identical(token.info, EOF_INFO)) {
+ while (!identical(token.info, Precedence.EOF_INFO)) {
token = token.next;
}
return token;
@@ -837,1837 +791,3 @@ class ParserError {
ParserError(this.reason);
toString() => reason;
}
-
-typedef int IdGenerator();
-
-/**
- * A parser event listener designed to work with [PartialParser]. It
- * builds elements representing the top-level declarations found in
- * the parsed compilation unit and records them in
- * [compilationUnitElement].
- */
-class ElementListener extends Listener {
- final IdGenerator idGenerator;
- final DiagnosticListener listener;
- final CompilationUnitElementX compilationUnitElement;
- final StringValidator stringValidator;
- Link<StringQuoting> interpolationScope;
-
- Link<Node> nodes = const Link<Node>();
-
- Link<MetadataAnnotation> metadata = const Link<MetadataAnnotation>();
-
- /// Records a stack of booleans for each member parsed (a stack is used to
- /// support nested members which isn't currently possible, but it also serves
- /// as a simple way to tell we're currently parsing a member). In this case,
- /// member refers to members of a library or a class (but currently, classes
- /// themselves are not considered members). If the top of the stack
- /// (memberErrors.head) is true, the current member has already reported at
- /// least one parse error.
- Link<bool> memberErrors = const Link<bool>();
-
- bool suppressParseErrors = false;
-
- ElementListener(
- DiagnosticListener listener,
- this.compilationUnitElement,
- this.idGenerator)
- : this.listener = listener,
- stringValidator = new StringValidator(listener),
- interpolationScope = const Link<StringQuoting>();
-
- bool get currentMemberHasParseError {
- return !memberErrors.isEmpty && memberErrors.head;
- }
-
- void pushQuoting(StringQuoting quoting) {
- interpolationScope = interpolationScope.prepend(quoting);
- }
-
- StringQuoting popQuoting() {
- StringQuoting result = interpolationScope.head;
- interpolationScope = interpolationScope.tail;
- return result;
- }
-
- StringNode popLiteralString() {
- StringNode node = popNode();
- // TODO(lrn): Handle interpolations in script tags.
- if (node.isInterpolation) {
- listener.internalError(node,
- "String interpolation not supported in library tags.");
- return null;
- }
- return node;
- }
-
- bool allowLibraryTags() {
- // Library tags are only allowed in the library file itself, not
- // in sourced files.
- LibraryElement library = compilationUnitElement.implementationLibrary;
- return !compilationUnitElement.hasMembers &&
- library.entryCompilationUnit == compilationUnitElement;
- }
-
- void endLibraryName(Token libraryKeyword, Token semicolon) {
- Expression name = popNode();
- addLibraryTag(new LibraryName(libraryKeyword, name,
- popMetadata(compilationUnitElement)));
- }
-
- void endImport(Token importKeyword, Token deferredKeyword, Token asKeyword,
- Token semicolon) {
- NodeList combinators = popNode();
- bool isDeferred = deferredKeyword != null;
- Identifier prefix;
- if (asKeyword != null) {
- prefix = popNode();
- }
- StringNode uri = popLiteralString();
- addLibraryTag(new Import(importKeyword, uri, prefix, combinators,
- popMetadata(compilationUnitElement),
- isDeferred: isDeferred));
- }
-
- void endEnum(Token enumKeyword, Token endBrace, int count) {
- NodeList names = makeNodeList(count, enumKeyword.next.next, endBrace, ",");
- Identifier name = popNode();
-
- int id = idGenerator();
- Element enclosing = compilationUnitElement;
- pushElement(new EnumClassElementX(name.source, enclosing, id,
- new Enum(enumKeyword, name, names)));
- rejectBuiltInIdentifier(name);
- }
-
- void endExport(Token exportKeyword, Token semicolon) {
- NodeList combinators = popNode();
- StringNode uri = popNode();
- addLibraryTag(new Export(exportKeyword, uri, combinators,
- popMetadata(compilationUnitElement)));
- }
-
- void endCombinators(int count) {
- if (0 == count) {
- pushNode(null);
- } else {
- pushNode(makeNodeList(count, null, null, " "));
- }
- }
-
- void endHide(Token hideKeyword) => pushCombinator(hideKeyword);
-
- void endShow(Token showKeyword) => pushCombinator(showKeyword);
-
- void pushCombinator(Token keywordToken) {
- NodeList identifiers = popNode();
- pushNode(new Combinator(identifiers, keywordToken));
- }
-
- void endIdentifierList(int count) {
- pushNode(makeNodeList(count, null, null, ","));
- }
-
- void endTypeList(int count) {
- pushNode(makeNodeList(count, null, null, ","));
- }
-
- void endPart(Token partKeyword, Token semicolon) {
- StringNode uri = popLiteralString();
- addLibraryTag(new Part(partKeyword, uri,
- popMetadata(compilationUnitElement)));
- }
-
- void endPartOf(Token partKeyword, Token semicolon) {
- Expression name = popNode();
- addPartOfTag(new PartOf(partKeyword, name,
- popMetadata(compilationUnitElement)));
- }
-
- void addPartOfTag(PartOf tag) {
- compilationUnitElement.setPartOf(tag, listener);
- }
-
- void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
- if (periodBeforeName != null) {
- popNode(); // Discard name.
- }
- popNode(); // Discard node (Send or Identifier).
- pushMetadata(new PartialMetadataAnnotation(beginToken, endToken));
- }
-
- void endTopLevelDeclaration(Token token) {
- if (!metadata.isEmpty) {
- recoverableError(metadata.head.beginToken,
- 'Metadata not supported here.');
- metadata = const Link<MetadataAnnotation>();
- }
- }
-
- void endClassDeclaration(int interfacesCount, Token beginToken,
- Token extendsKeyword, Token implementsKeyword,
- Token endToken) {
- makeNodeList(interfacesCount, implementsKeyword, null, ","); // interfaces
- popNode(); // superType
- popNode(); // typeParameters
- Identifier name = popNode();
- int id = idGenerator();
- PartialClassElement element = new PartialClassElement(
- name.source, beginToken, endToken, compilationUnitElement, id);
- pushElement(element);
- rejectBuiltInIdentifier(name);
- }
-
- void rejectBuiltInIdentifier(Identifier name) {
- if (name.token is KeywordToken) {
- Keyword keyword = (name.token as KeywordToken).keyword;
- if (!keyword.isPseudo) {
- recoverableError(name, "Illegal name '${keyword.syntax}'.");
- }
- }
- }
-
- void endFunctionTypeAlias(Token typedefKeyword, Token endToken) {
- popNode(); // TODO(karlklose): do not throw away typeVariables.
- Identifier name = popNode();
- popNode(); // returnType
- pushElement(
- new PartialTypedefElement(
- name.source, compilationUnitElement, typedefKeyword, endToken));
- rejectBuiltInIdentifier(name);
- }
-
- void endNamedMixinApplication(Token classKeyword,
- Token implementsKeyword,
- Token endToken) {
- NodeList interfaces = (implementsKeyword != null) ? popNode() : null;
- MixinApplication mixinApplication = popNode();
- Modifiers modifiers = popNode();
- NodeList typeParameters = popNode();
- Identifier name = popNode();
- NamedMixinApplication namedMixinApplication = new NamedMixinApplication(
- name, typeParameters, modifiers, mixinApplication, interfaces,
- classKeyword, endToken);
-
- int id = idGenerator();
- Element enclosing = compilationUnitElement;
- pushElement(new MixinApplicationElementX(name.source, enclosing, id,
- namedMixinApplication,
- modifiers));
- rejectBuiltInIdentifier(name);
- }
-
- void endMixinApplication() {
- NodeList mixins = popNode();
- TypeAnnotation superclass = popNode();
- pushNode(new MixinApplication(superclass, mixins));
- }
-
- void handleVoidKeyword(Token token) {
- pushNode(new TypeAnnotation(new Identifier(token), null));
- }
-
- void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
- bool hasParseError = currentMemberHasParseError;
- memberErrors = memberErrors.tail;
- Identifier name = popNode();
- popNode(); // type
- Modifiers modifiers = popNode();
- PartialFunctionElement element = new PartialFunctionElement(
- name.source, beginToken, getOrSet, endToken,
- modifiers, compilationUnitElement);
- element.hasParseError = hasParseError;
- pushElement(element);
- }
-
- void endTopLevelFields(int count, Token beginToken, Token endToken) {
- bool hasParseError = currentMemberHasParseError;
- memberErrors = memberErrors.tail;
- void buildFieldElement(Identifier name, VariableList fields) {
- pushElement(
- new FieldElementX(name, compilationUnitElement, fields));
- }
- NodeList variables = makeNodeList(count, null, null, ",");
- popNode(); // type
- Modifiers modifiers = popNode();
- buildFieldElements(modifiers, variables, compilationUnitElement,
- buildFieldElement,
- beginToken, endToken, hasParseError);
- }
-
- void buildFieldElements(Modifiers modifiers,
- NodeList variables,
- Element enclosingElement,
- void buildFieldElement(Identifier name,
- VariableList fields),
- Token beginToken, Token endToken,
- bool hasParseError) {
- VariableList fields =
- new PartialFieldList(beginToken, endToken, modifiers, hasParseError);
- for (Link<Node> variableNodes = variables.nodes;
- !variableNodes.isEmpty;
- variableNodes = variableNodes.tail) {
- Expression initializedIdentifier = variableNodes.head;
- Identifier identifier = initializedIdentifier.asIdentifier();
- if (identifier == null) {
- identifier = initializedIdentifier.asSendSet().selector.asIdentifier();
- }
- buildFieldElement(identifier, fields);
- }
- }
-
- void handleIdentifier(Token token) {
- pushNode(new Identifier(token));
- }
-
- void handleQualified(Token period) {
- Identifier last = popNode();
- Expression first = popNode();
- pushNode(new Send(first, last));
- }
-
- void handleNoType(Token token) {
- pushNode(null);
- }
-
- void endTypeVariable(Token token) {
- TypeAnnotation bound = popNode();
- Identifier name = popNode();
- pushNode(new TypeVariable(name, bound));
- rejectBuiltInIdentifier(name);
- }
-
- void endTypeVariables(int count, Token beginToken, Token endToken) {
- pushNode(makeNodeList(count, beginToken, endToken, ','));
- }
-
- void handleNoTypeVariables(token) {
- pushNode(null);
- }
-
- void endTypeArguments(int count, Token beginToken, Token endToken) {
- pushNode(makeNodeList(count, beginToken, endToken, ','));
- }
-
- void handleNoTypeArguments(Token token) {
- pushNode(null);
- }
-
- void endType(Token beginToken, Token endToken) {
- NodeList typeArguments = popNode();
- Expression typeName = popNode();
- pushNode(new TypeAnnotation(typeName, typeArguments));
- }
-
- void handleParenthesizedExpression(BeginGroupToken token) {
- Expression expression = popNode();
- pushNode(new ParenthesizedExpression(expression, token));
- }
-
- void handleModifier(Token token) {
- pushNode(new Identifier(token));
- }
-
- void handleModifiers(int count) {
- if (count == 0) {
- pushNode(Modifiers.EMPTY);
- } else {
- NodeList modifierNodes = makeNodeList(count, null, null, ' ');
- pushNode(new Modifiers(modifierNodes));
- }
- }
-
- Token expected(String string, Token token) {
- if (token is ErrorToken) {
- reportErrorToken(token);
- } else if (identical(';', string)) {
- // When a semicolon is missing, it often leads to an error on the
- // following line. So we try to find the token preceding the semicolon
- // and report that something is missing *after* it.
- Token preceding = findPrecedingToken(token);
- if (preceding == token) {
- reportError(
- token, MessageKind.MISSING_TOKEN_BEFORE_THIS, {'token': string});
- } else {
- reportError(
- preceding, MessageKind.MISSING_TOKEN_AFTER_THIS, {'token': string});
- }
- return token;
- } else {
- reportFatalError(
- token,
- MessageTemplate.TEMPLATES[MessageKind.MISSING_TOKEN_BEFORE_THIS]
- .message({'token': string}, true).toString());
- }
- return skipToEof(token);
- }
-
- /// Finds the preceding token via the begin token of the last AST node pushed
- /// on the [nodes] stack.
- Token findPrecedingToken(Token token) {
- Token result;
- Link<Node> nodes = this.nodes;
- while (!nodes.isEmpty) {
- result = findPrecedingTokenFromNode(nodes.head, token);
- if (result != null) {
- return result;
- }
- nodes = nodes.tail;
- }
- if (compilationUnitElement != null) {
- if (compilationUnitElement is CompilationUnitElementX) {
- CompilationUnitElementX unit = compilationUnitElement;
- Link<Element> members = unit.localMembers;
- while (!members.isEmpty) {
- ElementX member = members.head;
- DeclarationSite site = member.declarationSite;
- if (site is PartialElement) {
- result = findPrecedingTokenFromToken(site.endToken, token);
- if (result != null) {
- return result;
- }
- }
- members = members.tail;
- }
- result =
- findPrecedingTokenFromNode(compilationUnitElement.partTag, token);
- if (result != null) {
- return result;
- }
- }
- }
- return token;
- }
-
- Token findPrecedingTokenFromNode(Node node, Token token) {
- if (node != null) {
- return findPrecedingTokenFromToken(node.getBeginToken(), token);
- }
- return null;
- }
-
- Token findPrecedingTokenFromToken(Token start, Token token) {
- if (start != null) {
- Token current = start;
- while (current.kind != EOF_TOKEN && current.next != token) {
- current = current.next;
- }
- if (current.kind != EOF_TOKEN) {
- return current;
- }
- }
- return null;
- }
-
- Token expectedIdentifier(Token token) {
- if (token is KeywordToken) {
- reportError(
- token, MessageKind.EXPECTED_IDENTIFIER_NOT_RESERVED_WORD,
- {'keyword': token.value});
- } else if (token is ErrorToken) {
- reportErrorToken(token);
- return synthesizeIdentifier(token);
- } else {
- reportFatalError(token,
- "Expected identifier, but got '${token.value}'.");
- }
- return token;
- }
-
- Token expectedType(Token token) {
- pushNode(null);
- if (token is ErrorToken) {
- reportErrorToken(token);
- return synthesizeIdentifier(token);
- } else {
- reportFatalError(
- token, "Expected a type, but got '${token.value}'.");
- return skipToEof(token);
- }
- }
-
- Token expectedExpression(Token token) {
- if (token is ErrorToken) {
- reportErrorToken(token);
- pushNode(new ErrorExpression(token));
- return token.next;
- } else {
- reportFatalError(token,
- "Expected an expression, but got '${token.value}'.");
- pushNode(null);
- return skipToEof(token);
- }
- }
-
- Token unexpected(Token token) {
- if (token is ErrorToken) {
- reportErrorToken(token);
- } else {
- String message = "Unexpected token '${token.value}'.";
- if (token.info == BAD_INPUT_INFO) {
- message = token.value;
- }
- reportFatalError(token, message);
- }
- return skipToEof(token);
- }
-
- Token expectedBlockToSkip(Token token) {
- if (identical(token.stringValue, 'native')) {
- return native.handleNativeBlockToSkip(this, token);
- } else {
- return unexpected(token);
- }
- }
-
- Token expectedFunctionBody(Token token) {
- if (token is ErrorToken) {
- reportErrorToken(token);
- } else {
- String printString = token.value;
- reportFatalError(token,
- "Expected a function body, but got '$printString'.");
- }
- return skipToEof(token);
- }
-
- Token expectedClassBody(Token token) {
- if (token is ErrorToken) {
- reportErrorToken(token);
- } else {
- reportFatalError(token,
- "Expected a class body, but got '${token.value}'.");
- }
- return skipToEof(token);
- }
-
- Token expectedClassBodyToSkip(Token token) {
- return unexpected(token);
- }
-
- Token expectedDeclaration(Token token) {
- if (token is ErrorToken) {
- reportErrorToken(token);
- } else {
- reportFatalError(token,
- "Expected a declaration, but got '${token.value}'.");
- }
- return skipToEof(token);
- }
-
- Token unmatched(Token token) {
- if (token is ErrorToken) {
- reportErrorToken(token);
- } else {
- String begin = token.value;
- String end = closeBraceFor(begin);
- reportError(
- token, MessageKind.UNMATCHED_TOKEN, {'begin': begin, 'end': end});
- }
- Token next = token.next;
- while (next is ErrorToken) {
- next = next.next;
- }
- return next;
- }
-
- void recoverableError(Spannable node, String message) {
- // TODO(johnniwinther): Make recoverable errors non-fatal.
- reportFatalError(node, message);
- }
-
- void pushElement(Element element) {
- popMetadata(element);
- compilationUnitElement.addMember(element, listener);
- }
-
- Link<MetadataAnnotation> popMetadata(ElementX element) {
- var result = const Link<MetadataAnnotation>();
- for (Link link = metadata; !link.isEmpty; link = link.tail) {
- element.addMetadata(link.head);
- // Reverse the list as is implicitly done by addMetadata.
- result = result.prepend(link.head);
- }
- metadata = const Link<MetadataAnnotation>();
- return result;
- }
-
- void pushMetadata(MetadataAnnotation annotation) {
- metadata = metadata.prepend(annotation);
- }
-
- void addLibraryTag(LibraryTag tag) {
- if (!allowLibraryTags()) {
- recoverableError(tag, 'Library tags not allowed here.');
- }
- LibraryElementX implementationLibrary =
- compilationUnitElement.implementationLibrary;
- implementationLibrary.addTag(tag, listener);
- }
-
- void pushNode(Node node) {
- nodes = nodes.prepend(node);
- if (VERBOSE) log("push $nodes");
- }
-
- Node popNode() {
- assert(!nodes.isEmpty);
- Node node = nodes.head;
- nodes = nodes.tail;
- if (VERBOSE) log("pop $nodes");
- return node;
- }
-
- void log(message) {
- print(message);
- }
-
- NodeList makeNodeList(int count, Token beginToken, Token endToken,
- String delimiter) {
- Link<Node> poppedNodes = const Link<Node>();
- for (; count > 0; --count) {
- // This effectively reverses the order of nodes so they end up
- // in correct (source) order.
- poppedNodes = poppedNodes.prepend(popNode());
- }
- return new NodeList(beginToken, poppedNodes, endToken, delimiter);
- }
-
- void beginLiteralString(Token token) {
- String source = token.value;
- StringQuoting quoting = StringValidator.quotingFromString(source);
- pushQuoting(quoting);
- // Just wrap the token for now. At the end of the interpolation,
- // when we know how many there are, go back and validate the tokens.
- pushNode(new LiteralString(token, null));
- }
-
- void handleStringPart(Token token) {
- // Just push an unvalidated token now, and replace it when we know the
- // end of the interpolation.
- pushNode(new LiteralString(token, null));
- }
-
- void endLiteralString(int count) {
- StringQuoting quoting = popQuoting();
-
- Link<StringInterpolationPart> parts =
- const Link<StringInterpolationPart>();
- // Parts of the string interpolation are popped in reverse order,
- // starting with the last literal string part.
- bool isLast = true;
- for (int i = 0; i < count; i++) {
- LiteralString string = popNode();
- DartString validation =
- stringValidator.validateInterpolationPart(string.token, quoting,
- isFirst: false,
- isLast: isLast);
- // Replace the unvalidated LiteralString with a new LiteralString
- // object that has the validation result included.
- string = new LiteralString(string.token, validation);
- Expression expression = popNode();
- parts = parts.prepend(new StringInterpolationPart(expression, string));
- isLast = false;
- }
-
- LiteralString string = popNode();
- DartString validation =
- stringValidator.validateInterpolationPart(string.token, quoting,
- isFirst: true,
- isLast: isLast);
- string = new LiteralString(string.token, validation);
- if (isLast) {
- pushNode(string);
- } else {
- NodeList partNodes = new NodeList(null, parts, null, "");
- pushNode(new StringInterpolation(string, partNodes));
- }
- }
-
- void handleStringJuxtaposition(int stringCount) {
- assert(stringCount != 0);
- Expression accumulator = popNode();
- stringCount--;
- while (stringCount > 0) {
- Expression expression = popNode();
- accumulator = new StringJuxtaposition(expression, accumulator);
- stringCount--;
- }
- pushNode(accumulator);
- }
-
- void beginMember(Token token) {
- memberErrors = memberErrors.prepend(false);
- }
-
- void beginTopLevelMember(Token token) {
- beginMember(token);
- }
-
- void endFields(fieldCount, start, token) {
- memberErrors = memberErrors.tail;
- }
-
- void endMethod(getOrSet, start, token) {
- memberErrors = memberErrors.tail;
- }
-
- void beginFactoryMethod(Token token) {
- memberErrors = memberErrors.prepend(false);
- }
-
- void endFactoryMethod(Token beginToken, Token endToken) {
- memberErrors = memberErrors.tail;
- }
-
- /// Don't call this method. Should only be used as a last resort when there
- /// is no feasible way to recover from a parser error.
- void reportFatalError(Spannable spannable, String message) {
- reportError(spannable, MessageKind.GENERIC, {'text': message});
- // Some parse errors are infeasible to recover from, so we throw an error.
- throw new ParserError(message);
- }
-
- void reportError(Spannable spannable,
- MessageKind errorCode,
- [Map arguments = const {}]) {
- if (currentMemberHasParseError) return; // Error already reported.
- if (suppressParseErrors) return;
- if (!memberErrors.isEmpty) {
- memberErrors = memberErrors.tail.prepend(true);
- }
- listener.reportError(spannable, errorCode, arguments);
- }
-}
-
-class NodeListener extends ElementListener {
- NodeListener(
- DiagnosticListener listener,
- CompilationUnitElement element)
- : super(listener, element, null);
-
- void addLibraryTag(LibraryTag tag) {
- pushNode(tag);
- }
-
- void addPartOfTag(PartOf tag) {
- pushNode(tag);
- }
-
- void endClassDeclaration(int interfacesCount, Token beginToken,
- Token extendsKeyword, Token implementsKeyword,
- Token endToken) {
- NodeList body = popNode();
- NodeList interfaces =
- makeNodeList(interfacesCount, implementsKeyword, null, ",");
- Node supertype = popNode();
- NodeList typeParameters = popNode();
- Identifier name = popNode();
- Modifiers modifiers = popNode();
- pushNode(new ClassNode(modifiers, name, typeParameters, supertype,
- interfaces, beginToken, extendsKeyword, body,
- endToken));
- }
-
- void endCompilationUnit(int count, Token token) {
- pushNode(makeNodeList(count, null, null, '\n'));
- }
-
- void endFunctionTypeAlias(Token typedefKeyword, Token endToken) {
- NodeList formals = popNode();
- NodeList typeParameters = popNode();
- Identifier name = popNode();
- TypeAnnotation returnType = popNode();
- pushNode(new Typedef(returnType, name, typeParameters, formals,
- typedefKeyword, endToken));
- }
-
- void endNamedMixinApplication(Token classKeyword,
- Token implementsKeyword,
- Token endToken) {
- NodeList interfaces = (implementsKeyword != null) ? popNode() : null;
- Node mixinApplication = popNode();
- Modifiers modifiers = popNode();
- NodeList typeParameters = popNode();
- Identifier name = popNode();
- pushNode(new NamedMixinApplication(name, typeParameters,
- modifiers, mixinApplication,
- interfaces,
- classKeyword, endToken));
- }
-
- void endEnum(Token enumKeyword, Token endBrace, int count) {
- NodeList names = makeNodeList(count, enumKeyword.next.next, endBrace, ",");
- Identifier name = popNode();
- pushNode(new Enum(enumKeyword, name, names));
- }
-
- void endClassBody(int memberCount, Token beginToken, Token endToken) {
- pushNode(makeNodeList(memberCount, beginToken, endToken, null));
- }
-
- void endTopLevelFields(int count, Token beginToken, Token endToken) {
- NodeList variables = makeNodeList(count, null, endToken, ",");
- TypeAnnotation type = popNode();
- Modifiers modifiers = popNode();
- pushNode(new VariableDefinitions(type, modifiers, variables));
- }
-
- void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
- popNode(); // body
- popNode(); // formalParameters
- Identifier name = popNode();
- popNode(); // type
- Modifiers modifiers = popNode();
- PartialFunctionElement element = new PartialFunctionElement(
- name.source, beginToken, getOrSet, endToken,
- modifiers, compilationUnitElement);
- pushElement(element);
- }
-
- void endFormalParameter(Token thisKeyword) {
- Expression name = popNode();
- if (thisKeyword != null) {
- Identifier thisIdentifier = new Identifier(thisKeyword);
- if (name.asSend() == null) {
- name = new Send(thisIdentifier, name);
- } else {
- name = name.asSend().copyWithReceiver(thisIdentifier, false);
- }
- }
- TypeAnnotation type = popNode();
- Modifiers modifiers = popNode();
- NodeList metadata = popNode();
- pushNode(new VariableDefinitions.forParameter(
- metadata, type, modifiers, new NodeList.singleton(name)));
- }
-
- void endFormalParameters(int count, Token beginToken, Token endToken) {
- pushNode(makeNodeList(count, beginToken, endToken, ","));
- }
-
- void handleNoFormalParameters(Token token) {
- pushNode(null);
- }
-
- void endArguments(int count, Token beginToken, Token endToken) {
- pushNode(makeNodeList(count, beginToken, endToken, ","));
- }
-
- void handleNoArguments(Token token) {
- pushNode(null);
- }
-
- void endConstructorReference(Token start, Token periodBeforeName,
- Token endToken) {
- Identifier name = null;
- if (periodBeforeName != null) {
- name = popNode();
- }
- NodeList typeArguments = popNode();
- Node classReference = popNode();
- if (typeArguments != null) {
- classReference = new TypeAnnotation(classReference, typeArguments);
- } else {
- Identifier identifier = classReference.asIdentifier();
- Send send = classReference.asSend();
- if (identifier != null) {
- // TODO(ahe): Should be:
- // classReference = new Send(null, identifier);
- classReference = identifier;
- } else if (send != null) {
- classReference = send;
- } else {
- internalError(node: classReference);
- }
- }
- Node constructor = classReference;
- if (name != null) {
- // Either typeName<args>.name or x.y.name.
- constructor = new Send(classReference, name);
- }
- pushNode(constructor);
- }
-
- void endRedirectingFactoryBody(Token beginToken,
- Token endToken) {
- pushNode(new RedirectingFactoryBody(beginToken, endToken, popNode()));
- }
-
- void endReturnStatement(bool hasExpression,
- Token beginToken, Token endToken) {
- Expression expression = hasExpression ? popNode() : null;
- pushNode(new Return(beginToken, endToken, expression));
- }
-
- void endYieldStatement(Token yieldToken, Token starToken, Token endToken) {
- Expression expression = popNode();
- pushNode(new Yield(yieldToken, starToken, expression, endToken));
- }
-
- void endExpressionStatement(Token token) {
- pushNode(new ExpressionStatement(popNode(), token));
- }
-
- void handleOnError(Token token, var errorInformation) {
- listener.internalError(token, "'${token.value}': ${errorInformation}");
- }
-
- Token expectedFunctionBody(Token token) {
- if (identical(token.stringValue, 'native')) {
- return native.handleNativeFunctionBody(this, token);
- } else if (token is ErrorToken) {
- pushNode(null);
- reportErrorToken(token);
- } else {
- reportFatalError(token,
- "Expected a function body, but got '${token.value}'.");
- }
- return skipToEof(token);
- }
-
- Token expectedClassBody(Token token) {
- if (token is ErrorToken) {
- reportErrorToken(token);
- return skipToEof(token);
- } else {
- reportFatalError(token,
- "Expected a class body, but got '${token.value}'.");
- return skipToEof(token);
- }
- }
-
- void handleLiteralInt(Token token) {
- pushNode(new LiteralInt(token, (t, e) => handleOnError(t, e)));
- }
-
- void handleLiteralDouble(Token token) {
- pushNode(new LiteralDouble(token, (t, e) => handleOnError(t, e)));
- }
-
- void handleLiteralBool(Token token) {
- pushNode(new LiteralBool(token, (t, e) => handleOnError(t, e)));
- }
-
- void handleLiteralNull(Token token) {
- pushNode(new LiteralNull(token));
- }
-
- void endLiteralSymbol(Token hashToken, int identifierCount) {
- NodeList identifiers = makeNodeList(identifierCount, null, null, '.');
- pushNode(new LiteralSymbol(hashToken, identifiers));
- }
-
- void handleBinaryExpression(Token token) {
- Node argument = popNode();
- Node receiver = popNode();
- String tokenString = token.stringValue;
- if (identical(tokenString, '.') ||
- identical(tokenString, '..') ||
- identical(tokenString, '?.')) {
- Send argumentSend = argument.asSend();
- if (argumentSend == null) {
- // TODO(ahe): The parser should diagnose this problem, not
- // this listener.
- reportFatalError(argument,
- 'Expected an identifier.');
- }
- if (argumentSend.receiver != null) internalError(node: argument);
- if (argument is SendSet) internalError(node: argument);
- pushNode(argument.asSend().copyWithReceiver(receiver,
- identical(tokenString, '?.')));
- } else {
- NodeList arguments = new NodeList.singleton(argument);
- pushNode(new Send(receiver, new Operator(token), arguments));
- }
- if (identical(tokenString, '===')) {
- listener.reportError(token, MessageKind.UNSUPPORTED_EQ_EQ_EQ,
- {'lhs': receiver, 'rhs': argument});
- }
- if (identical(tokenString, '!==')) {
- listener.reportError(token, MessageKind.UNSUPPORTED_BANG_EQ_EQ,
- {'lhs': receiver, 'rhs': argument});
- }
- }
-
- void beginCascade(Token token) {
- pushNode(new CascadeReceiver(popNode(), token));
- }
-
- void endCascade() {
- pushNode(new Cascade(popNode()));
- }
-
- void handleAsOperator(Token operathor, Token endToken) {
- TypeAnnotation type = popNode();
- Expression expression = popNode();
- NodeList arguments = new NodeList.singleton(type);
- pushNode(new Send(expression, new Operator(operathor), arguments));
- }
-
- void handleAssignmentExpression(Token token) {
- Node arg = popNode();
- Node node = popNode();
- Send send = node.asSend();
- if (send == null || !(send.isPropertyAccess || send.isIndex)) {
- reportNotAssignable(node);
- }
- if (send.asSendSet() != null) internalError(node: send);
- NodeList arguments;
- if (send.isIndex) {
- Link<Node> link = const Link<Node>().prepend(arg);
- link = link.prepend(send.arguments.head);
- arguments = new NodeList(null, link);
- } else {
- arguments = new NodeList.singleton(arg);
- }
- Operator op = new Operator(token);
- pushNode(new SendSet(send.receiver, send.selector, op, arguments,
- send.isConditional));
- }
-
- void reportNotAssignable(Node node) {
- // TODO(ahe): The parser should diagnose this problem, not this
- // listener.
- reportFatalError(node,
- 'Not assignable.');
- }
-
- void handleConditionalExpression(Token question, Token colon) {
- Node elseExpression = popNode();
- Node thenExpression = popNode();
- Node condition = popNode();
- pushNode(new Conditional(
- condition, thenExpression, elseExpression, question, colon));
- }
-
- void endSend(Token token) {
- NodeList arguments = popNode();
- Node selector = popNode();
- // TODO(ahe): Handle receiver.
- pushNode(new Send(null, selector, arguments));
- }
-
- void endFunctionBody(int count, Token beginToken, Token endToken) {
- if (count == 0 && beginToken == null) {
- pushNode(new EmptyStatement(endToken));
- } else {
- pushNode(new Block(makeNodeList(count, beginToken, endToken, null)));
- }
- }
-
- void handleAsyncModifier(Token asyncToken, Token starToken) {
- if (asyncToken != null) {
- pushNode(new AsyncModifier(asyncToken, starToken));
- } else {
- pushNode(null);
- }
- }
-
- void skippedFunctionBody(Token token) {
- pushNode(new Block(new NodeList.empty()));
- }
-
- void handleNoFunctionBody(Token token) {
- pushNode(new EmptyStatement(token));
- }
-
- void endFunction(Token getOrSet, Token endToken) {
- Statement body = popNode();
- AsyncModifier asyncModifier = popNode();
- NodeList initializers = popNode();
- NodeList formals = popNode();
- // The name can be an identifier or a send in case of named constructors.
- Expression name = popNode();
- TypeAnnotation type = popNode();
- Modifiers modifiers = popNode();
- pushNode(new FunctionExpression(name, formals, body, type,
- modifiers, initializers, getOrSet,
- asyncModifier));
- }
-
- void endFunctionDeclaration(Token endToken) {
- pushNode(new FunctionDeclaration(popNode()));
- }
-
- void endVariablesDeclaration(int count, Token endToken) {
- // TODO(ahe): Pick one name for this concept, either
- // VariablesDeclaration or VariableDefinitions.
- NodeList variables = makeNodeList(count, null, endToken, ",");
- TypeAnnotation type = popNode();
- Modifiers modifiers = popNode();
- pushNode(new VariableDefinitions(type, modifiers, variables));
- }
-
- void endInitializer(Token assignmentOperator) {
- Expression initializer = popNode();
- NodeList arguments =
- initializer == null ? null : new NodeList.singleton(initializer);
- Expression name = popNode();
- Operator op = new Operator(assignmentOperator);
- pushNode(new SendSet(null, name, op, arguments));
- }
-
- void endIfStatement(Token ifToken, Token elseToken) {
- Statement elsePart = (elseToken == null) ? null : popNode();
- Statement thenPart = popNode();
- ParenthesizedExpression condition = popNode();
- pushNode(new If(condition, thenPart, elsePart, ifToken, elseToken));
- }
-
- void endForStatement(int updateExpressionCount,
- Token beginToken, Token endToken) {
- Statement body = popNode();
- NodeList updates = makeNodeList(updateExpressionCount, null, null, ',');
- Statement condition = popNode();
- Node initializer = popNode();
- pushNode(new For(initializer, condition, updates, body, beginToken));
- }
-
- void handleNoExpression(Token token) {
- pushNode(null);
- }
-
- void endDoWhileStatement(Token doKeyword, Token whileKeyword,
- Token endToken) {
- Expression condition = popNode();
- Statement body = popNode();
- pushNode(new DoWhile(body, condition, doKeyword, whileKeyword, endToken));
- }
-
- void endWhileStatement(Token whileKeyword, Token endToken) {
- Statement body = popNode();
- Expression condition = popNode();
- pushNode(new While(condition, body, whileKeyword));
- }
-
- void endBlock(int count, Token beginToken, Token endToken) {
- pushNode(new Block(makeNodeList(count, beginToken, endToken, null)));
- }
-
- void endThrowExpression(Token throwToken, Token endToken) {
- Expression expression = popNode();
- pushNode(new Throw(expression, throwToken, endToken));
- }
-
- void endAwaitExpression(Token awaitToken, Token endToken) {
- Expression expression = popNode();
- pushNode(new Await(awaitToken, expression));
- }
-
- void endRethrowStatement(Token throwToken, Token endToken) {
- pushNode(new Rethrow(throwToken, endToken));
- if (identical(throwToken.stringValue, 'throw')) {
- listener.reportError(throwToken,
- MessageKind.UNSUPPORTED_THROW_WITHOUT_EXP);
- }
- }
-
- void handleUnaryPrefixExpression(Token token) {
- pushNode(new Send.prefix(popNode(), new Operator(token)));
- }
-
- void handleSuperExpression(Token token) {
- pushNode(new Identifier(token));
- }
-
- void handleThisExpression(Token token) {
- pushNode(new Identifier(token));
- }
-
- void handleUnaryAssignmentExpression(Token token, bool isPrefix) {
- Node node = popNode();
- Send send = node.asSend();
- if (send == null) {
- reportNotAssignable(node);
- }
- if (!(send.isPropertyAccess || send.isIndex)) {
- reportNotAssignable(node);
- }
- if (send.asSendSet() != null) internalError(node: send);
- Node argument = null;
- if (send.isIndex) argument = send.arguments.head;
- Operator op = new Operator(token);
-
- if (isPrefix) {
- pushNode(new SendSet.prefix(send.receiver, send.selector, op, argument,
- send.isConditional));
- } else {
- pushNode(new SendSet.postfix(send.receiver, send.selector, op, argument,
- send.isConditional));
- }
- }
-
- void handleUnaryPostfixAssignmentExpression(Token token) {
- handleUnaryAssignmentExpression(token, false);
- }
-
- void handleUnaryPrefixAssignmentExpression(Token token) {
- handleUnaryAssignmentExpression(token, true);
- }
-
- void endInitializers(int count, Token beginToken, Token endToken) {
- pushNode(makeNodeList(count, beginToken, null, ','));
- }
-
- void handleNoInitializers() {
- pushNode(null);
- }
-
- void endFields(int count, Token beginToken, Token endToken) {
- NodeList variables = makeNodeList(count, null, endToken, ",");
- TypeAnnotation type = popNode();
- Modifiers modifiers = popNode();
- pushNode(new VariableDefinitions(type, modifiers, variables));
- }
-
- void endMethod(Token getOrSet, Token beginToken, Token endToken) {
- Statement body = popNode();
- AsyncModifier asyncModifier = popNode();
- NodeList initializers = popNode();
- NodeList formalParameters = popNode();
- Expression name = popNode();
- TypeAnnotation returnType = popNode();
- Modifiers modifiers = popNode();
- pushNode(new FunctionExpression(name, formalParameters, body, returnType,
- modifiers, initializers, getOrSet,
- asyncModifier));
- }
-
- void handleLiteralMap(int count, Token beginToken, Token constKeyword,
- Token endToken) {
- NodeList entries = makeNodeList(count, beginToken, endToken, ',');
- NodeList typeArguments = popNode();
- pushNode(new LiteralMap(typeArguments, entries, constKeyword));
- }
-
- void endLiteralMapEntry(Token colon, Token endToken) {
- Expression value = popNode();
- Expression key = popNode();
- pushNode(new LiteralMapEntry(key, colon, value));
- }
-
- void handleLiteralList(int count, Token beginToken, Token constKeyword,
- Token endToken) {
- NodeList elements = makeNodeList(count, beginToken, endToken, ',');
- pushNode(new LiteralList(popNode(), elements, constKeyword));
- }
-
- void handleIndexedExpression(Token openSquareBracket,
- Token closeSquareBracket) {
- NodeList arguments =
- makeNodeList(1, openSquareBracket, closeSquareBracket, null);
- Node receiver = popNode();
- Token token = new StringToken.fromString(INDEX_INFO, '[]',
- openSquareBracket.charOffset);
- Node selector = new Operator(token);
- pushNode(new Send(receiver, selector, arguments));
- }
-
- void handleNewExpression(Token token) {
- NodeList arguments = popNode();
- Node name = popNode();
- pushNode(new NewExpression(token, new Send(null, name, arguments)));
- }
-
- void handleConstExpression(Token token) {
- // [token] carries the 'const' information.
- handleNewExpression(token);
- }
-
- void handleOperator(Token token) {
- pushNode(new Operator(token));
- }
-
- void handleOperatorName(Token operatorKeyword, Token token) {
- Operator op = new Operator(token);
- pushNode(new Send(new Identifier(operatorKeyword), op, null));
- }
-
- void handleNamedArgument(Token colon) {
- Expression expression = popNode();
- Identifier name = popNode();
- pushNode(new NamedArgument(name, colon, expression));
- }
-
- void endOptionalFormalParameters(int count,
- Token beginToken, Token endToken) {
- pushNode(makeNodeList(count, beginToken, endToken, ','));
- }
-
- void handleFunctionTypedFormalParameter(Token endToken) {
- NodeList formals = popNode();
- Identifier name = popNode();
- TypeAnnotation returnType = popNode();
- pushNode(null); // Signal "no type" to endFormalParameter.
- pushNode(new FunctionExpression(name, formals, null, returnType,
- Modifiers.EMPTY, null, null, null));
- }
-
- void handleValuedFormalParameter(Token equals, Token token) {
- Expression defaultValue = popNode();
- Expression parameterName = popNode();
- pushNode(new SendSet(null, parameterName, new Operator(equals),
- new NodeList.singleton(defaultValue)));
- }
-
- void endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) {
- Block finallyBlock = null;
- if (finallyKeyword != null) {
- finallyBlock = popNode();
- }
- NodeList catchBlocks = makeNodeList(catchCount, null, null, null);
- Block tryBlock = popNode();
- pushNode(new TryStatement(tryBlock, catchBlocks, finallyBlock,
- tryKeyword, finallyKeyword));
- }
-
- void handleCaseMatch(Token caseKeyword, Token colon) {
- pushNode(new CaseMatch(caseKeyword, popNode(), colon));
- }
-
- void handleCatchBlock(Token onKeyword, Token catchKeyword) {
- Block block = popNode();
- NodeList formals = catchKeyword != null? popNode(): null;
- TypeAnnotation type = onKeyword != null ? popNode() : null;
- pushNode(new CatchBlock(type, formals, block, onKeyword, catchKeyword));
- }
-
- void endSwitchStatement(Token switchKeyword, Token endToken) {
- NodeList cases = popNode();
- ParenthesizedExpression expression = popNode();
- pushNode(new SwitchStatement(expression, cases, switchKeyword));
- }
-
- void endSwitchBlock(int caseCount, Token beginToken, Token endToken) {
- Link<Node> caseNodes = const Link<Node>();
- while (caseCount > 0) {
- SwitchCase switchCase = popNode();
- caseNodes = caseNodes.prepend(switchCase);
- caseCount--;
- }
- pushNode(new NodeList(beginToken, caseNodes, endToken, null));
- }
-
- void handleSwitchCase(int labelCount, int caseCount,
- Token defaultKeyword, int statementCount,
- Token firstToken, Token endToken) {
- NodeList statements = makeNodeList(statementCount, null, null, null);
- NodeList labelsAndCases =
- makeNodeList(labelCount + caseCount, null, null, null);
- pushNode(new SwitchCase(labelsAndCases, defaultKeyword, statements,
- firstToken));
- }
-
- void handleBreakStatement(bool hasTarget,
- Token breakKeyword, Token endToken) {
- Identifier target = null;
- if (hasTarget) {
- target = popNode();
- }
- pushNode(new BreakStatement(target, breakKeyword, endToken));
- }
-
- void handleContinueStatement(bool hasTarget,
- Token continueKeyword, Token endToken) {
- Identifier target = null;
- if (hasTarget) {
- target = popNode();
- }
- pushNode(new ContinueStatement(target, continueKeyword, endToken));
- }
-
- void handleEmptyStatement(Token token) {
- pushNode(new EmptyStatement(token));
- }
-
- void endFactoryMethod(Token beginToken, Token endToken) {
- super.endFactoryMethod(beginToken, endToken);
- Statement body = popNode();
- AsyncModifier asyncModifier = popNode();
- NodeList formals = popNode();
- Node name = popNode();
-
- // TODO(ahe): Move this parsing to the parser.
- int modifierCount = 0;
- Token modifier = beginToken;
- if (modifier.stringValue == "external") {
- handleModifier(modifier);
- modifierCount++;
- modifier = modifier.next;
- }
- if (modifier.stringValue == "const") {
- handleModifier(modifier);
- modifierCount++;
- modifier = modifier.next;
- }
- assert(modifier.stringValue == "factory");
- handleModifier(modifier);
- modifierCount++;
- handleModifiers(modifierCount);
- Modifiers modifiers = popNode();
-
- pushNode(new FunctionExpression(name, formals, body, null,
- modifiers, null, null, asyncModifier));
- }
-
- void endForIn(Token awaitToken, Token forToken,
- Token inKeyword, Token endToken) {
- Statement body = popNode();
- Expression expression = popNode();
- Node declaredIdentifier = popNode();
- if (awaitToken == null) {
- pushNode(new SyncForIn(declaredIdentifier, expression, body,
- forToken, inKeyword));
- } else {
- pushNode(new AsyncForIn(declaredIdentifier, expression, body, awaitToken,
- forToken, inKeyword));
- }
- }
-
- void endMetadataStar(int count, bool forParameter) {
- // TODO(johnniwinther): Handle metadata for all node kinds.
- if (forParameter) {
- if (0 == count) {
- pushNode(null);
- } else {
- pushNode(makeNodeList(count, null, null, ' '));
- }
- }
- }
-
- void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
- NodeList arguments = popNode();
- if (arguments == null) {
- // This is a constant expression.
- Identifier name;
- if (periodBeforeName != null) {
- name = popNode();
- }
- NodeList typeArguments = popNode();
- Node receiver = popNode();
- if (typeArguments != null) {
- receiver = new TypeAnnotation(receiver, typeArguments);
- recoverableError(typeArguments,
- 'Type arguments are not allowed here.');
- } else {
- Identifier identifier = receiver.asIdentifier();
- Send send = receiver.asSend();
- if (identifier != null) {
- receiver = new Send(null, identifier);
- } else if (send == null) {
- internalError(node: receiver);
- }
- }
- Send send = receiver;
- if (name != null) {
- send = new Send(receiver, name);
- }
- pushNode(new Metadata(beginToken, send));
- } else {
- // This is a const constructor call.
- endConstructorReference(beginToken, periodBeforeName, endToken);
- Node constructor = popNode();
- pushNode(new Metadata(beginToken,
- new NewExpression(null,
- new Send(null, constructor, arguments))));
- }
- }
-
- void handleAssertStatement(Token assertKeyword, Token semicolonToken) {
- NodeList arguments = popNode();
- Node selector = new Identifier(assertKeyword);
- Node send = new Send(null, selector, arguments);
- pushNode(new ExpressionStatement(send, semicolonToken));
- }
-
- void endUnnamedFunction(Token token) {
- Statement body = popNode();
- AsyncModifier asyncModifier = popNode();
- NodeList formals = popNode();
- pushNode(new FunctionExpression(null, formals, body, null,
- Modifiers.EMPTY, null, null,
- asyncModifier));
- }
-
- void handleIsOperator(Token operathor, Token not, Token endToken) {
- TypeAnnotation type = popNode();
- Expression expression = popNode();
- Node argument;
- if (not != null) {
- argument = new Send.prefix(type, new Operator(not));
- } else {
- argument = type;
- }
-
- NodeList arguments = new NodeList.singleton(argument);
- pushNode(new Send(expression, new Operator(operathor), arguments));
- }
-
- void handleLabel(Token colon) {
- Identifier name = popNode();
- pushNode(new Label(name, colon));
- }
-
- void endLabeledStatement(int labelCount) {
- Statement statement = popNode();
- NodeList labels = makeNodeList(labelCount, null, null, null);
- pushNode(new LabeledStatement(labels, statement));
- }
-
- void log(message) {
- listener.log(message);
- }
-
- void internalError({Token token, Node node}) {
- // TODO(ahe): This should call listener.internalError.
- Spannable spannable = (token == null) ? node : token;
- throw new SpannableAssertionFailure(spannable, 'Internal error in parser.');
- }
-}
-
-abstract class PartialElement implements DeclarationSite {
- Token beginToken;
- Token endToken;
-
- bool hasParseError = false;
-
- bool get isErroneous => hasParseError;
-
- DeclarationSite get declarationSite => this;
-}
-
-abstract class PartialFunctionMixin implements BaseFunctionElementX {
- FunctionExpression cachedNode;
- Modifiers get modifiers;
- Token beginToken;
- Token getOrSet;
- Token endToken;
-
- /**
- * The position is computed in the constructor using [findMyName]. Computing
- * it on demand fails in case tokens are GC'd.
- */
- Token _position;
-
- void init(Token beginToken, Token getOrSet, Token endToken) {
- this.beginToken = beginToken;
- this.getOrSet = getOrSet;
- this.endToken = endToken;
- _position = ElementX.findNameToken(
- beginToken,
- modifiers.isFactory || isGenerativeConstructor,
- name, enclosingElement.name);
- }
-
- bool get hasNode => cachedNode != null;
-
- FunctionExpression get node {
- assert(invariant(this, cachedNode != null,
- message: "Node has not been computed for $this."));
- return cachedNode;
- }
-
- FunctionExpression parseNode(DiagnosticListener listener) {
- if (cachedNode != null) return cachedNode;
- parseFunction(Parser p) {
- if (isClassMember && modifiers.isFactory) {
- p.parseFactoryMethod(beginToken);
- } else {
- p.parseFunction(beginToken, getOrSet);
- }
- }
- cachedNode = parse(listener, this, declarationSite, parseFunction);
- return cachedNode;
- }
-
- Token get position => _position;
-
- void reusePartialFunctionMixin() {
- cachedNode = null;
- }
-
- DeclarationSite get declarationSite;
-}
-
-abstract class PartialFunctionElement
- implements PartialElement, PartialFunctionMixin {
-
- factory PartialFunctionElement(
- String name,
- Token beginToken,
- Token getOrSet,
- Token endToken,
- Modifiers modifiers,
- Element enclosingElement,
- {bool hasBody: true}) {
- if (getOrSet == null) {
- return new PartialMethodElement(
- name, beginToken, endToken, modifiers,
- enclosingElement, hasBody: hasBody);
- } else if (identical(getOrSet.stringValue, 'get')) {
- return new PartialGetterElement(
- name, beginToken, getOrSet, endToken, modifiers,
- enclosingElement, hasBody: hasBody);
- } else {
- assert(identical(getOrSet.stringValue, 'set'));
- return new PartialSetterElement(
- name, beginToken, getOrSet, endToken, modifiers,
- enclosingElement, hasBody: hasBody);
- }
- }
-
- PartialFunctionElement copyWithEnclosing(Element enclosing);
-}
-
-
-class PartialMethodElement extends MethodElementX
- with PartialElement, PartialFunctionMixin
- implements PartialFunctionElement {
- PartialMethodElement(String name,
- Token beginToken,
- Token endToken,
- Modifiers modifiers,
- Element enclosing,
- {bool hasBody: true})
- : super(name, ElementKind.FUNCTION, modifiers, enclosing, hasBody) {
- init(beginToken, null, endToken);
- }
-
- void reuseElement() {
- super.reuseElement();
- reusePartialFunctionMixin();
- }
-
- PartialMethodElement copyWithEnclosing(Element enclosing) {
- return new PartialMethodElement(
- name, beginToken, endToken, modifiers, enclosing, hasBody: hasBody);
- }
-}
-
-class PartialGetterElement extends GetterElementX
- with PartialElement, PartialFunctionMixin
- implements GetterElement, PartialFunctionElement {
- PartialGetterElement(String name,
- Token beginToken,
- Token getToken,
- Token endToken,
- Modifiers modifiers,
- Element enclosing,
- {bool hasBody: true})
- : super(name, modifiers, enclosing, hasBody) {
- init(beginToken, getToken, endToken);
- }
-
- @override
- SetterElement get setter => abstractField.setter;
-
- void reuseElement() {
- super.reuseElement();
- reusePartialFunctionMixin();
- }
-
- PartialGetterElement copyWithEnclosing(Element enclosing) {
- return new PartialGetterElement(
- name, beginToken, getOrSet, endToken, modifiers, enclosing,
- hasBody: hasBody);
- }
-}
-
-class PartialSetterElement extends SetterElementX
- with PartialElement, PartialFunctionMixin
- implements SetterElement, PartialFunctionElement {
- PartialSetterElement(String name,
- Token beginToken,
- Token setToken,
- Token endToken,
- Modifiers modifiers,
- Element enclosing,
- {bool hasBody: true})
- : super(name, modifiers, enclosing, hasBody) {
- init(beginToken, setToken, endToken);
- }
-
- @override
- GetterElement get getter => abstractField.getter;
-
- void reuseElement() {
- super.reuseElement();
- reusePartialFunctionMixin();
- }
-
- PartialSetterElement copyWithEnclosing(Element enclosing) {
- return new PartialSetterElement(
- name, beginToken, getOrSet, endToken, modifiers, enclosing,
- hasBody: hasBody);
- }
-}
-
-class PartialConstructorElement extends ConstructorElementX
- with PartialElement, PartialFunctionMixin {
- PartialConstructorElement(String name,
- Token beginToken,
- Token endToken,
- ElementKind kind,
- Modifiers modifiers,
- Element enclosing)
- : super(name, kind, modifiers, enclosing) {
- init(beginToken, null, endToken);
- }
-
- void reuseElement() {
- super.reuseElement();
- reusePartialFunctionMixin();
- }
-}
-
-class PartialFieldList extends VariableList with PartialElement {
- PartialFieldList(Token beginToken,
- Token endToken,
- Modifiers modifiers,
- bool hasParseError)
- : super(modifiers) {
- super.beginToken = beginToken;
- super.endToken = endToken;
- super.hasParseError = hasParseError;
- }
-
- VariableDefinitions parseNode(Element element, DiagnosticListener listener) {
- if (definitions != null) return definitions;
- listener.withCurrentElement(element, () {
- definitions = parse(
- listener, element, declarationSite,
- (Parser parser) => parser.parseMember(beginToken));
-
- if (!hasParseError &&
- !definitions.modifiers.isVar &&
- !definitions.modifiers.isFinal &&
- !definitions.modifiers.isConst &&
- definitions.type == null &&
- !definitions.isErroneous) {
- listener.reportError(
- definitions,
- MessageKind.GENERIC,
- { 'text': 'A field declaration must start with var, final, '
- 'const, or a type annotation.' });
- }
- });
- return definitions;
- }
-
- computeType(Element element, Compiler compiler) {
- if (type != null) return type;
- // TODO(johnniwinther): Compute this in the resolver.
- compiler.withCurrentElement(element, () {
- VariableDefinitions node = parseNode(element, compiler);
- if (node.type != null) {
- type = compiler.resolver.resolveTypeAnnotation(element, node.type);
- } else {
- type = const DynamicType();
- }
- });
- assert(type != null);
- return type;
- }
-}
-
-class PartialTypedefElement extends TypedefElementX with PartialElement {
-
- PartialTypedefElement(
- String name,
- Element enclosing,
- Token beginToken,
- Token endToken)
- : super(name, enclosing) {
- this.beginToken = beginToken;
- this.endToken = endToken;
- }
-
- Token get token => beginToken;
-
- Node parseNode(DiagnosticListener listener) {
- if (cachedNode != null) return cachedNode;
- cachedNode = parse(
- listener, this, declarationSite,
- (p) => p.parseTopLevelDeclaration(token));
- return cachedNode;
- }
-
- Token get position => findMyName(token);
-}
-
-/// A [MetadataAnnotation] which is constructed on demand.
-class PartialMetadataAnnotation extends MetadataAnnotationX
- implements PartialElement {
- Token beginToken; // TODO(ahe): Make this final when issue 22065 is fixed.
-
- final Token tokenAfterEndToken;
-
- Expression cachedNode;
-
- bool hasParseError = false;
-
- PartialMetadataAnnotation(this.beginToken, this.tokenAfterEndToken);
-
- bool get isErroneous => hasParseError;
-
- DeclarationSite get declarationSite => this;
-
- Token get endToken {
- Token token = beginToken;
- while (token.kind != EOF_TOKEN) {
- if (identical(token.next, tokenAfterEndToken)) break;
- token = token.next;
- }
- assert(token != null);
- return token;
- }
-
- void set endToken(_) {
- throw new UnsupportedError("endToken=");
- }
-
- Node parseNode(DiagnosticListener listener) {
- if (cachedNode != null) return cachedNode;
- var metadata = parse(listener,
- annotatedElement,
- declarationSite,
- (p) => p.parseMetadata(beginToken));
- if (metadata is Metadata) {
- cachedNode = metadata.expression;
- return cachedNode;
- } else {
- assert (metadata is ErrorNode);
- return metadata;
- }
- }
-
- bool get hasNode => cachedNode != null;
-
- Node get node {
- assert(invariant(this, hasNode));
- return cachedNode;
- }
-}
-
-Node parse(
- DiagnosticListener diagnosticListener,
- ElementX element,
- PartialElement partial,
- doParse(Parser parser)) {
- CompilationUnitElement unit = element.compilationUnit;
- NodeListener listener = new NodeListener(diagnosticListener, unit);
- listener.memberErrors = listener.memberErrors.prepend(false);
- try {
- if (partial.hasParseError) {
- listener.suppressParseErrors = true;
- }
- doParse(new Parser(listener));
- } on ParserError catch (e) {
- partial.hasParseError = true;
- return new ErrorNode(element.position, e.reason);
- }
- Node node = listener.popNode();
- assert(listener.nodes.isEmpty);
- return node;
-}

Powered by Google App Engine
This is Rietveld 408576698