Index: frog/leg/scanner/listener.dart |
=================================================================== |
--- frog/leg/scanner/listener.dart (revision 5925) |
+++ frog/leg/scanner/listener.dart (working copy) |
@@ -1,1476 +0,0 @@ |
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
-// for details. All rights reserved. Use of this source code is governed by a |
-// BSD-style license that can be found in the LICENSE file. |
- |
-final bool VERBOSE = false; |
- |
-class Listener { |
- void beginArguments(Token token) { |
- } |
- |
- void endArguments(int count, Token beginToken, Token endToken) { |
- } |
- |
- void beginBlock(Token token) { |
- } |
- |
- void endBlock(int count, Token beginToken, Token endToken) { |
- } |
- |
- void beginClassBody(Token token) { |
- } |
- |
- void endClassBody(int memberCount, Token beginToken, Token endToken) { |
- } |
- |
- void beginClassDeclaration(Token token) { |
- } |
- |
- void endClassDeclaration(int interfacesCount, Token beginToken, |
- Token extendsKeyword, Token implementsKeyword, |
- Token endToken) { |
- } |
- |
- void beginDoWhileStatement(Token token) { |
- } |
- |
- void endDoWhileStatement(Token doKeyword, Token whileKeyword, |
- Token endToken) { |
- } |
- |
- void beginExpressionStatement(Token token) { |
- } |
- |
- void endExpressionStatement(Token token) { |
- } |
- |
- void beginDefaultClause(Token token) { |
- } |
- |
- void handleNoDefaultClause(Token token) { |
- } |
- |
- void endDefaultClause(Token defaultKeyword) { |
- } |
- |
- void beginFactoryMethod(Token token) { |
- } |
- |
- void endFactoryMethod(Token factoryKeyword, Token periodBeforeName, |
- Token endToken) { |
- } |
- |
- void beginFormalParameter(Token token) { |
- } |
- |
- void endFormalParameter(Token token, Token thisKeyword) { |
- } |
- |
- void beginFormalParameters(Token token) { |
- } |
- |
- void endFormalParameters(int count, Token beginToken, Token endToken) { |
- } |
- |
- void endFields(int count, Token beginToken, Token endToken) { |
- } |
- |
- void beginForStatement(Token token) { |
- } |
- |
- void endForStatement(int updateExpressionCount, |
- Token beginToken, Token endToken) { |
- } |
- |
- void endForInStatement(Token beginToken, Token inKeyword, Token endToken) { |
- } |
- |
- void beginFunction(Token token) { |
- } |
- |
- void endFunction(Token getOrSet, Token endToken) { |
- } |
- |
- void beginFunctionDeclaration(Token token) { |
- } |
- |
- void endFunctionDeclaration(Token token) { |
- } |
- |
- void beginFunctionBody(Token token) { |
- } |
- |
- void endFunctionBody(int count, Token beginToken, Token endToken) { |
- } |
- |
- void handleNoFunctionBody(Token token) { |
- } |
- |
- void beginFunctionName(Token token) { |
- } |
- |
- void endFunctionName(Token token) { |
- } |
- |
- void beginFunctionTypeAlias(Token token) { |
- } |
- |
- void endFunctionTypeAlias(Token typedefKeyword, Token endToken) { |
- } |
- |
- void beginIfStatement(Token token) { |
- } |
- |
- void endIfStatement(Token ifToken, Token elseToken) { |
- } |
- |
- void beginInitializedIdentifier(Token token) { |
- } |
- |
- void endInitializedIdentifier() { |
- } |
- |
- void beginInitializer(Token token) { |
- } |
- |
- void endInitializer(Token assignmentOperator) { |
- } |
- |
- void beginInitializers(Token token) { |
- } |
- |
- void endInitializers(int count, Token beginToken, Token endToken) { |
- } |
- |
- void handleNoInitializers() { |
- } |
- |
- void beginInterface(Token token) { |
- } |
- |
- void endInterface(int supertypeCount, Token interfaceKeyword, |
- Token extendsKeyword, Token endToken) { |
- } |
- |
- void beginLabeledStatement(Token token) { |
- } |
- |
- void endLabeledStatement(Token colon) { |
- } |
- |
- void beginLiteralMapEntry(Token token) { |
- } |
- |
- void endLiteralMapEntry(Token colon, Token endToken) { |
- } |
- |
- void beginLiteralString(Token token) { |
- } |
- |
- void endLiteralString(int interpolationCount) { |
- } |
- |
- void handleStringJuxtaposition(int literalCount) { |
- } |
- |
- void beginMember(Token token) { |
- } |
- |
- void endMethod(Token getOrSet, Token beginToken, Token endToken) { |
- } |
- |
- void beginOptionalFormalParameters(Token token) { |
- } |
- |
- void endOptionalFormalParameters(int count, |
- Token beginToken, Token endToken) { |
- } |
- |
- void beginReturnStatement(Token token) { |
- } |
- |
- void endReturnStatement(bool hasExpression, |
- Token beginToken, Token endToken) { |
- } |
- |
- void beginScriptTag(Token token) { |
- } |
- |
- void endScriptTag(bool hasPrefix, Token beginToken, Token endToken) { |
- } |
- |
- void beginSend(Token token) { |
- } |
- |
- void endSend(Token token) { |
- } |
- |
- void beginSwitchStatement(Token token) { |
- } |
- |
- void endSwitchStatement(Token switchKeyword, Token endToken) { |
- } |
- |
- void beginSwitchBlock(Token token) { |
- } |
- |
- void endSwitchBlock(int caseCount, Token beginToken, Token endToken) { |
- } |
- |
- void beginThrowStatement(Token token) { |
- } |
- |
- void endThrowStatement(Token throwToken, Token endToken) { |
- } |
- |
- void endRethrowStatement(Token throwToken, Token endToken) { |
- } |
- |
- void beginTopLevelMember(Token token) { |
- } |
- |
- void endTopLevelFields(int count, Token beginToken, Token endToken) { |
- } |
- |
- void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) { |
- } |
- |
- void beginTryStatement(Token token) { |
- } |
- |
- void handleCatchBlock(Token catchKeyword) { |
- } |
- |
- void handleFinallyBlock(Token finallyKeyword) { |
- } |
- |
- void endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) { |
- } |
- |
- void endType(Token beginToken, Token endToken) { |
- } |
- |
- void beginTypeArguments(Token token) { |
- } |
- |
- void endTypeArguments(int count, Token beginToken, Token endToken) { |
- } |
- |
- void handleNoTypeArguments(Token token) { |
- } |
- |
- void beginTypeVariable(Token token) { |
- } |
- |
- void endTypeVariable(Token token) { |
- } |
- |
- void beginTypeVariables(Token token) { |
- } |
- |
- void endTypeVariables(int count, Token beginToken, Token endToken) { |
- } |
- |
- void beginUnamedFunction(Token token) { |
- } |
- |
- void endUnamedFunction(Token token) { |
- } |
- |
- void beginVariablesDeclaration(Token token) { |
- } |
- |
- void endVariablesDeclaration(int count, Token endToken) { |
- } |
- |
- void beginWhileStatement(Token token) { |
- } |
- |
- void endWhileStatement(Token whileKeyword, Token endToken) { |
- } |
- |
- void handleAssignmentExpression(Token token) { |
- } |
- |
- void handleBinaryExpression(Token token) { |
- } |
- |
- void handleConditionalExpression(Token question, Token colon) { |
- } |
- |
- void handleConstExpression(Token token, bool named) { |
- } |
- |
- void handleFunctionTypedFormalParameter(Token token) { |
- } |
- |
- void handleIdentifier(Token token) { |
- } |
- |
- void handleIndexedExpression(Token openCurlyBracket, |
- Token closeCurlyBracket) { |
- } |
- |
- void handleIsOperator(Token operathor, Token not, Token endToken) { |
- // TODO(ahe): Rename [operathor] to "operator" when VM bug is fixed. |
- } |
- |
- void handleLiteralBool(Token token) { |
- } |
- |
- void handleBreakStatement(bool hasTarget, |
- Token breakKeyword, Token endToken) { |
- } |
- |
- void handleContinueStatement(bool hasTarget, |
- Token continueKeyword, Token endToken) { |
- } |
- |
- void handleEmptyStatement(Token token) { |
- } |
- |
- /** Called with either the token containing a double literal, or |
- * an immediately preceding "unary plus" token. |
- */ |
- void handleLiteralDouble(Token token) { |
- } |
- |
- /** Called with either the token containing an integer literal, |
- * or an immediately preceding "unary plus" token. |
- */ |
- void handleLiteralInt(Token token) { |
- } |
- |
- void handleLiteralList(int count, Token beginToken, Token constKeyword, |
- Token endToken) { |
- } |
- |
- void handleLiteralMap(int count, Token beginToken, Token constKeyword, |
- Token endToken) { |
- } |
- |
- void handleLiteralNull(Token token) { |
- } |
- |
- void handleModifier(Token token) { |
- } |
- |
- void handleModifiers(int count) { |
- } |
- |
- void handleNamedArgument(Token colon) { |
- } |
- |
- void handleNewExpression(Token token, bool named) { |
- } |
- |
- void handleNoArguments(Token token) { |
- } |
- |
- void handleNoExpression(Token token) { |
- } |
- |
- void handleNoType(Token token) { |
- } |
- |
- void handleNoTypeVariables(Token token) { |
- } |
- |
- void handleOperatorName(Token operatorKeyword, Token token) { |
- } |
- |
- void handleParenthesizedExpression(BeginGroupToken token) { |
- } |
- |
- void handleQualified(Token period) { |
- } |
- |
- void handleStringPart(Token token) { |
- } |
- |
- void handleSuperExpression(Token token) { |
- } |
- |
- void handleSwitchCase(Token labelToken, int expressionCount, |
- Token defaultKeyword, int statementCount, |
- Token firstToken, Token endToken) { |
- } |
- |
- void handleThisExpression(Token token) { |
- } |
- |
- void handleUnaryPostfixAssignmentExpression(Token token) { |
- } |
- |
- void handleUnaryPrefixExpression(Token token) { |
- } |
- |
- void handleUnaryPrefixAssignmentExpression(Token token) { |
- } |
- |
- void handleValuedFormalParameter(Token equals, Token token) { |
- } |
- |
- void handleVoidKeyword(Token token) { |
- } |
- |
- Token expected(String string, Token token) { |
- error("expected '$string', but got '${token.slowToString()}'", token); |
- return skipToEof(token); |
- } |
- |
- void expectedIdentifier(Token token) { |
- error("expected identifier, but got '${token.slowToString()}'", token); |
- } |
- |
- Token expectedType(Token token) { |
- error("expected a type, but got '${token.slowToString()}'", token); |
- return skipToEof(token); |
- } |
- |
- Token expectedExpression(Token token) { |
- error("expected an expression, but got '${token.slowToString()}'", token); |
- return skipToEof(token); |
- } |
- |
- Token unexpected(Token token) { |
- error("unexpected token '${token.slowToString()}'", token); |
- return skipToEof(token); |
- } |
- |
- Token expectedBlockToSkip(Token token) { |
- error("expected a block, but got '${token.slowToString()}'", token); |
- return skipToEof(token); |
- } |
- |
- Token expectedFunctionBody(Token token) { |
- error("expected a function body, but got '${token.slowToString()}'", token); |
- return skipToEof(token); |
- } |
- |
- Token expectedClassBody(Token token) { |
- error("expected a class body, but got '${token.slowToString()}'", token); |
- return skipToEof(token); |
- } |
- |
- Token expectedClassBodyToSkip(Token token) { |
- error("expected a class body, but got '${token.slowToString()}'", token); |
- return skipToEof(token); |
- } |
- |
- skipToEof(Token token) { |
- while (token.info !== EOF_INFO) { |
- token = token.next; |
- } |
- return token; |
- } |
- |
- void recoverableError(String message, [Token token, Node node]) { |
- if (token === null && node !== null) { |
- token = node.getBeginToken(); |
- } |
- error(message, token); |
- } |
- |
- void error(String message, Token token) { |
- throw new ParserError("$message @ ${token.charOffset}"); |
- } |
-} |
- |
-class ParserError { |
- final String reason; |
- ParserError(this.reason); |
- toString() => reason; |
-} |
- |
-/** |
- * A listener for parser events. |
- */ |
-class ElementListener extends Listener { |
- final DiagnosticListener listener; |
- final CompilationUnitElement compilationUnitElement; |
- final StringValidator stringValidator; |
- Link<StringQuoting> interpolationScope; |
- |
- Link<Node> nodes = const EmptyLink<Node>(); |
- |
- ElementListener(DiagnosticListener listener, |
- CompilationUnitElement this.compilationUnitElement) |
- : this.listener = listener, |
- stringValidator = new StringValidator(listener), |
- interpolationScope = const EmptyLink<StringQuoting>(); |
- |
- void pushQuoting(StringQuoting quoting) { |
- interpolationScope = interpolationScope.prepend(quoting); |
- } |
- |
- StringQuoting popQuoting() { |
- StringQuoting result = interpolationScope.head; |
- interpolationScope = interpolationScope.tail; |
- return result; |
- } |
- |
- LiteralString popLiteralString() { |
- StringNode node = popNode(); |
- // TODO(lrn): Handle interpolations in script tags. |
- if (node.isInterpolation) { |
- listener.cancel("String interpolation not supported in library tags", |
- node: node); |
- return null; |
- } |
- return node; |
- } |
- |
- void endScriptTag(bool hasPrefix, Token beginToken, Token endToken) { |
- StringNode prefix = null; |
- Identifier argumentName = null; |
- if (hasPrefix) { |
- prefix = popLiteralString(); |
- argumentName = popNode(); |
- } |
- StringNode firstArgument = popLiteralString(); |
- Identifier tag = popNode(); |
- compilationUnitElement.addTag(new ScriptTag(tag, firstArgument, |
- argumentName, prefix, |
- beginToken, endToken), |
- listener); |
- } |
- |
- void endClassDeclaration(int interfacesCount, Token beginToken, |
- Token extendsKeyword, Token implementsKeyword, |
- Token endToken) { |
- SourceString nativeName = native.checkForNativeClass(this); |
- NodeList interfaces = |
- makeNodeList(interfacesCount, implementsKeyword, null, ","); |
- TypeAnnotation supertype = popNode(); |
- NodeList typeParameters = popNode(); |
- Identifier name = popNode(); |
- ClassElement element = new PartialClassElement( |
- name.source, beginToken, endToken, compilationUnitElement); |
- element.nativeName = nativeName; |
- pushElement(element); |
- } |
- |
- void endDefaultClause(Token defaultKeyword) { |
- NodeList typeParameters = popNode(); |
- Node name = popNode(); |
- pushNode(new TypeAnnotation(name, typeParameters)); |
- } |
- |
- void handleNoDefaultClause(Token token) { |
- pushNode(null); |
- } |
- |
- void endInterface(int supertypeCount, Token interfaceKeyword, |
- Token extendsKeyword, Token endToken) { |
- // TODO(ahe): Record the defaultClause. |
- Node defaultClause = popNode(); |
- NodeList supertypes = |
- makeNodeList(supertypeCount, extendsKeyword, null, ","); |
- NodeList typeParameters = popNode(); |
- Identifier name = popNode(); |
- pushElement(new PartialClassElement(name.source, interfaceKeyword, |
- endToken, |
- compilationUnitElement)); |
- } |
- |
- void endFunctionTypeAlias(Token typedefKeyword, Token endToken) { |
- NodeList typeVariables = popNode(); // TOOD(karlklose): do not throw away. |
- Identifier name = popNode(); |
- TypeAnnotation returnType = popNode(); |
- pushElement(new TypedefElement(name.source, compilationUnitElement, |
- typedefKeyword)); |
- } |
- |
- void handleVoidKeyword(Token token) { |
- pushNode(new TypeAnnotation(new Identifier(token), null)); |
- } |
- |
- void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) { |
- Identifier name = popNode(); |
- Modifiers modifiers = popNode(); |
- ElementKind kind; |
- if (getOrSet === null) { |
- kind = ElementKind.FUNCTION; |
- } else if (getOrSet.stringValue === 'get') { |
- kind = ElementKind.GETTER; |
- } else if (getOrSet.stringValue === 'set') { |
- kind = ElementKind.SETTER; |
- } |
- pushElement(new PartialFunctionElement(name.source, beginToken, getOrSet, |
- endToken, kind, |
- modifiers, compilationUnitElement)); |
- } |
- |
- void endTopLevelFields(int count, Token beginToken, Token endToken) { |
- void buildFieldElement(SourceString name, Element fields) { |
- pushElement(new VariableElement( |
- name, fields, ElementKind.FIELD, compilationUnitElement)); |
- } |
- NodeList variables = makeNodeList(count, null, null, ","); |
- Modifiers modifiers = popNode(); |
- buildFieldElements(modifiers, variables, compilationUnitElement, |
- buildFieldElement, |
- beginToken, endToken); |
- } |
- |
- void buildFieldElements(Modifiers modifiers, |
- NodeList variables, |
- ContainerElement enclosingElement, |
- void buildFieldElement(SourceString name, |
- Element fields), |
- Token beginToken, Token endToken) { |
- Element fields = new PartialFieldListElement(beginToken, |
- endToken, |
- modifiers, |
- enclosingElement); |
- for (Link<Node> nodes = variables.nodes; !nodes.isEmpty(); |
- nodes = nodes.tail) { |
- Expression initializedIdentifier = nodes.head; |
- Identifier identifier = initializedIdentifier.asIdentifier(); |
- if (identifier === null) { |
- identifier = initializedIdentifier.asSendSet().selector.asIdentifier(); |
- } |
- SourceString name = identifier.source; |
- buildFieldElement(name, fields); |
- } |
- } |
- |
- void handleIdentifier(Token token) { |
- pushNode(new Identifier(token)); |
- } |
- |
- void handleQualified(Token period) { |
- Identifier last = popNode(); |
- Identifier 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)); |
- } |
- |
- 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) { |
- NodeList nodes = makeNodeList(count, null, null, null); |
- pushNode(new Modifiers(nodes)); |
- } |
- |
- Token expected(String string, Token token) { |
- listener.cancel("expected '$string', but got '${token.slowToString()}'", |
- token: token); |
- return skipToEof(token); |
- } |
- |
- void expectedIdentifier(Token token) { |
- listener.cancel("expected identifier, but got '${token.slowToString()}'", |
- token: token); |
- pushNode(null); |
- } |
- |
- Token expectedType(Token token) { |
- listener.cancel("expected a type, but got '${token.slowToString()}'", |
- token: token); |
- pushNode(null); |
- return skipToEof(token); |
- } |
- |
- Token expectedExpression(Token token) { |
- listener.cancel("expected an expression, but got '${token.slowToString()}'", |
- token: token); |
- pushNode(null); |
- return skipToEof(token); |
- } |
- |
- Token unexpected(Token token) { |
- listener.cancel("unexpected token '${token.slowToString()}'", token: token); |
- return skipToEof(token); |
- } |
- |
- Token expectedBlockToSkip(Token token) { |
- if (token.stringValue === 'native') { |
- return native.handleNativeBlockToSkip(this, token); |
- } else { |
- return unexpected(token); |
- } |
- } |
- |
- Token expectedFunctionBody(Token token) { |
- String printString = token.slowToString(); |
- listener.cancel("expected a function body, but got '$printString'", |
- token: token); |
- return skipToEof(token); |
- } |
- |
- Token expectedClassBody(Token token) { |
- listener.cancel("expected a class body, but got '${token.slowToString()}'", |
- token: token); |
- return skipToEof(token); |
- } |
- |
- Token expectedClassBodyToSkip(Token token) { |
- if (token.stringValue === 'native') { |
- return native.handleNativeClassBodyToSkip(this, token); |
- } else { |
- return unexpected(token); |
- } |
- } |
- |
- void recoverableError(String message, [Token token, Node node]) { |
- listener.cancel(message, token: token, node: node); |
- } |
- |
- void pushElement(Element element) { |
- compilationUnitElement.addMember(element, 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; |
- } |
- |
- Node peekNode() { |
- assert(!nodes.isEmpty()); |
- Node node = nodes.head; |
- if (VERBOSE) log("peek $node"); |
- return node; |
- } |
- |
- void log(message) { |
- print(message); |
- } |
- |
- NodeList makeNodeList(int count, Token beginToken, Token endToken, |
- String delimiter) { |
- Link<Node> nodes = const EmptyLink<Node>(); |
- for (; count > 0; --count) { |
- // This effectively reverses the order of nodes so they end up |
- // in correct (source) order. |
- nodes = nodes.prepend(popNode()); |
- } |
- SourceString sourceDelimiter = |
- (delimiter === null) ? null : new SourceString(delimiter); |
- return new NodeList(beginToken, nodes, endToken, sourceDelimiter); |
- } |
- |
- void beginLiteralString(Token token) { |
- SourceString 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 EmptyLink<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 nodes = new NodeList(null, parts, null, null); |
- pushNode(new StringInterpolation(string, nodes)); |
- } |
- } |
- |
- 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); |
- } |
-} |
- |
-class NodeListener extends ElementListener { |
- NodeListener(DiagnosticListener listener, CompilationUnitElement element) |
- : super(listener, element); |
- |
- void endClassDeclaration(int interfacesCount, Token beginToken, |
- Token extendsKeyword, Token implementsKeyword, |
- Token endToken) { |
- NodeList body = popNode(); |
- NodeList interfaces = |
- makeNodeList(interfacesCount, implementsKeyword, null, ","); |
- TypeAnnotation supertype = popNode(); |
- NodeList typeParameters = popNode(); |
- Identifier name = popNode(); |
- pushNode(new ClassNode(name, typeParameters, supertype, interfaces, null, |
- beginToken, extendsKeyword, endToken)); |
- } |
- |
- void endFunctionTypeAlias(Token typedefKeyword, Token endToken) { |
- NodeList formals = popNode(); |
- NodeList typeParameters = null; // TODO(ahe): Don't discard these. |
- Identifier name = popNode(); |
- TypeAnnotation returnType = popNode(); |
- pushNode(new Typedef(returnType, name, typeParameters, formals, |
- typedefKeyword, endToken)); |
- } |
- |
- void endInterface(int supertypeCount, Token interfaceKeyword, |
- Token extendsKeyword, Token endToken) { |
- NodeList body = popNode(); |
- TypeAnnotation defaultClause = popNode(); |
- NodeList supertypes = makeNodeList(supertypeCount, extendsKeyword, |
- null, ','); |
- NodeList typeParameters = popNode(); |
- Identifier name = popNode(); |
- pushNode(new ClassNode(name, typeParameters, null, supertypes, |
- defaultClause, interfaceKeyword, null, endToken)); |
- } |
- |
- 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, null, ","); |
- Modifiers modifiers = popNode(); |
- pushNode(new VariableDefinitions(null, modifiers, variables, endToken)); |
- } |
- |
- void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) { |
- Statement body = popNode(); |
- NodeList formalParameters = popNode(); |
- Identifier name = popNode(); |
- Modifiers modifiers = popNode(); |
- ElementKind kind; |
- if (getOrSet === null) { |
- kind = ElementKind.FUNCTION; |
- } else if (getOrSet.stringValue === 'get') { |
- kind = ElementKind.GETTER; |
- } else if (getOrSet.stringValue === 'set') { |
- kind = ElementKind.SETTER; |
- } |
- pushElement(new PartialFunctionElement(name.source, beginToken, getOrSet, |
- endToken, kind, |
- modifiers, compilationUnitElement)); |
- } |
- |
- void endFormalParameter(Token token, 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); |
- } |
- } |
- TypeAnnotation type = popNode(); |
- Modifiers modifiers = popNode(); |
- pushNode(new VariableDefinitions(type, modifiers, |
- new NodeList.singleton(name), token)); |
- } |
- |
- void endFormalParameters(int count, Token beginToken, Token endToken) { |
- pushNode(makeNodeList(count, beginToken, endToken, ",")); |
- } |
- |
- void endArguments(int count, Token beginToken, Token endToken) { |
- pushNode(makeNodeList(count, beginToken, endToken, ",")); |
- } |
- |
- void handleNoArguments(Token token) { |
- pushNode(null); |
- } |
- |
- void endReturnStatement(bool hasExpression, |
- Token beginToken, Token endToken) { |
- Expression expression = hasExpression ? popNode() : null; |
- pushNode(new Return(beginToken, endToken, expression)); |
- } |
- |
- void endExpressionStatement(Token token) { |
- pushNode(new ExpressionStatement(popNode(), token)); |
- } |
- |
- void handleOnError(Token token, var error) { |
- listener.cancel("internal error: '${token.value}': ${error}", token: token); |
- } |
- |
- Token expectedFunctionBody(Token token) { |
- if (token.stringValue === 'native') { |
- return native.handleNativeFunctionBody(this, token); |
- } else { |
- listener.cancel( |
- "expected a function body, but got '${token.slowToString()}'", |
- token: token); |
- return skipToEof(token); |
- } |
- } |
- |
- Token expectedClassBody(Token token) { |
- if (token.stringValue === 'native') { |
- return native.handleNativeClassBody(this, token); |
- } else { |
- listener.cancel( |
- "expected a class body, but got '${token.slowToString()}'", |
- token: token); |
- 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 handleBinaryExpression(Token token) { |
- Node argument = popNode(); |
- Node receiver = popNode(); |
- if (token.stringValue === '.') { |
- if (argument is !Send) internalError(node: argument); |
- if (argument.asSend().receiver !== null) internalError(node: argument); |
- if (argument is SendSet) internalError(node: argument); |
- pushNode(argument.asSend().copyWithReceiver(receiver)); |
- } else { |
- NodeList arguments = new NodeList.singleton(argument); |
- pushNode(new Send(receiver, new Operator(token), arguments)); |
- } |
- } |
- |
- void handleAssignmentExpression(Token token) { |
- Node arg = popNode(); |
- Node node = popNode(); |
- Send send = node.asSend(); |
- if (send === null) internalError(node: node); |
- if (!(send.isPropertyAccess || send.isIndex)) internalError(node: send); |
- if (send.asSendSet() !== null) internalError(node: send); |
- NodeList arguments; |
- if (send.isIndex) { |
- Link<Node> link = new Link<Node>(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)); |
- } |
- |
- 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) { |
- pushNode(new Block(makeNodeList(count, beginToken, endToken, null))); |
- } |
- |
- void handleNoFunctionBody(Token token) { |
- pushNode(null); |
- } |
- |
- void endFunction(Token getOrSet, Token endToken) { |
- Statement body = 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)); |
- } |
- |
- 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, null, ","); |
- TypeAnnotation type = popNode(); |
- Modifiers modifiers = popNode(); |
- pushNode(new VariableDefinitions(type, modifiers, variables, endToken)); |
- } |
- |
- void endInitializer(Token assignmentOperator) { |
- Expression initializer = popNode(); |
- NodeList arguments = 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 endThrowStatement(Token throwToken, Token endToken) { |
- Expression expression = popNode(); |
- pushNode(new Throw(expression, throwToken, endToken)); |
- } |
- |
- void endRethrowStatement(Token throwToken, Token endToken) { |
- pushNode(new Throw(null, throwToken, endToken)); |
- } |
- |
- 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) internalError(node: node); |
- if (!(send.isPropertyAccess || send.isIndex)) internalError(node: send); |
- 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)); |
- } else { |
- pushNode(new SendSet.postfix(send.receiver, send.selector, op, argument)); |
- } |
- } |
- |
- 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, null, ","); |
- Modifiers modifiers = popNode(); |
- pushNode(new VariableDefinitions(null, modifiers, variables, endToken)); |
- } |
- |
- void endMethod(Token getOrSet, Token beginToken, Token endToken) { |
- Statement body = popNode(); |
- NodeList initializers = popNode(); |
- NodeList formalParameters = popNode(); |
- Expression name = popNode(); |
- Modifiers modifiers = popNode(); |
- pushNode(new FunctionExpression(name, formalParameters, body, null, |
- modifiers, initializers, getOrSet)); |
- } |
- |
- void handleLiteralMap(int count, Token beginToken, Token constKeyword, |
- Token endToken) { |
- NodeList entries = makeNodeList(count, beginToken, endToken, ','); |
- NodeList typeArguments = popNode(); |
- pushNode(new LiteralMap(typeArguments, entries)); |
- } |
- |
- void endLiteralMapEntry(Token colon, Token endToken) { |
- Expression value = popNode(); |
- Expression key = popNode(); |
- if (key.asLiteralString() === null) { |
- recoverableError('expected a constant string', node: key); |
- } |
- pushNode(new LiteralMapEntry(key, colon, value)); |
- } |
- |
- void handleLiteralList(int count, Token beginToken, Token constKeyword, |
- Token endToken) { |
- NodeList elements = makeNodeList(count, beginToken, endToken, ','); |
- NodeList typeArguments = popNode(); |
- // TODO(ahe): Type arguments are discarded. |
- pushNode(new LiteralList(null, elements, constKeyword)); |
- } |
- |
- void handleIndexedExpression(Token openSquareBracket, |
- Token closeSquareBracket) { |
- NodeList arguments = |
- makeNodeList(1, openSquareBracket, closeSquareBracket, null); |
- Node receiver = popNode(); |
- Token token = |
- new StringToken(INDEX_INFO, '[]', openSquareBracket.charOffset); |
- Node selector = new Operator(token); |
- pushNode(new Send(receiver, selector, arguments)); |
- } |
- |
- void handleNewExpression(Token token, bool named) { |
- NodeList arguments = popNode(); |
- Node name = popNode(); |
- if (named) { |
- TypeAnnotation type = popNode(); |
- name = new Send(type, name); |
- } |
- pushNode(new NewExpression(token, new Send(null, name, arguments))); |
- } |
- |
- void handleConstExpression(Token token, bool named) { |
- NodeList arguments = popNode(); |
- if (named) { |
- Identifier name = popNode(); |
- } |
- TypeAnnotation type = popNode(); |
- pushNode(new NewExpression(token, new Send(null, type, arguments))); |
- } |
- |
- 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, |
- 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 handleCatchBlock(Token catchKeyword) { |
- Block block = popNode(); |
- NodeList formals = popNode(); |
- pushNode(new CatchBlock(formals, block, 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> nodes = const EmptyLink<Node>(); |
- while (caseCount > 0) { |
- SwitchCase switchCase = popNode(); |
- nodes = nodes.prepend(switchCase); |
- caseCount--; |
- } |
- pushNode(new NodeList(beginToken, nodes, endToken, null)); |
- } |
- |
- void handleSwitchCase(Token labelToken, int expressionCount, |
- Token defaultKeyword, int statementCount, |
- Token firstToken, Token endToken) { |
- NodeList statements = makeNodeList(statementCount, null, null, null); |
- NodeList expressions = makeNodeList(expressionCount, null, null, null); |
- Identifier label = null; |
- if (labelToken !== null) { |
- label = popNode(); |
- } |
- pushNode(new SwitchCase(label, expressions, 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 factoryKeyword, Token periodBeforeName, |
- Token endToken) { |
- Statement body = popNode(); |
- NodeList formals = popNode(); |
- NodeList typeParameters = popNode(); // TODO(karlklose): don't throw away. |
- Node name = popNode(); |
- if (periodBeforeName !== null) { |
- // A library prefix was handled in [handleQualified]. |
- name = new Send(popNode(), name); |
- } |
- handleModifier(factoryKeyword); |
- handleModifiers(1); |
- Modifiers modifiers = popNode(); |
- pushNode(new FunctionExpression(name, formals, body, null, |
- modifiers, null, null)); |
- } |
- |
- void endForInStatement(Token beginToken, Token inKeyword, Token endToken) { |
- Statement body = popNode(); |
- Expression expression = popNode(); |
- Node declaredIdentifier = popNode(); |
- pushNode(new ForInStatement(declaredIdentifier, expression, body, |
- beginToken, inKeyword)); |
- } |
- |
- void endUnamedFunction(Token token) { |
- Statement body = popNode(); |
- NodeList formals = popNode(); |
- pushNode(new FunctionExpression(null, formals, body, null, |
- null, null, null)); |
- } |
- |
- 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 endLabeledStatement(Token colon) { |
- Statement statement = popNode(); |
- Identifier label = popNode(); |
- pushNode(new LabeledStatement(label, colon, statement)); |
- } |
- |
- void log(message) { |
- listener.log(message); |
- } |
- |
- void internalError([Token token, Node node]) { |
- listener.cancel('internal error', token: token, node: node); |
- throw 'internal error'; |
- } |
-} |
- |
-class PartialFunctionElement extends FunctionElement { |
- final Token beginToken; |
- final Token getOrSet; |
- final Token endToken; |
- |
- PartialFunctionElement(SourceString name, |
- Token this.beginToken, |
- Token this.getOrSet, |
- Token this.endToken, |
- ElementKind kind, |
- Modifiers modifiers, |
- Element enclosing) |
- : super(name, kind, modifiers, enclosing); |
- |
- FunctionExpression parseNode(DiagnosticListener listener) { |
- if (cachedNode != null) return cachedNode; |
- cachedNode = parse(listener, |
- getCompilationUnit(), |
- (p) => p.parseFunction(beginToken, getOrSet)); |
- return cachedNode; |
- } |
- |
- Token position() => findMyName(beginToken); |
-} |
- |
-class PartialFieldListElement extends VariableListElement { |
- final Token beginToken; |
- final Token endToken; |
- |
- PartialFieldListElement(Token this.beginToken, |
- Token this.endToken, |
- Modifiers modifiers, |
- Element enclosing) |
- : super(ElementKind.VARIABLE_LIST, modifiers, enclosing); |
- |
- VariableDefinitions parseNode(DiagnosticListener listener) { |
- if (cachedNode != null) return cachedNode; |
- cachedNode = parse(listener, |
- getCompilationUnit(), |
- (p) => p.parseVariablesDeclaration(beginToken)); |
- return cachedNode; |
- } |
- |
- Token position() => beginToken; // findMyName doesn't work. I'm nameless. |
-} |
- |
-Node parse(DiagnosticListener diagnosticListener, |
- CompilationUnitElement element, |
- doParse(Parser parser)) { |
- NodeListener listener = new NodeListener(diagnosticListener, element); |
- doParse(new Parser(listener)); |
- Node node = listener.popNode(); |
- assert(listener.nodes.isEmpty()); |
- return node; |
-} |