UNPKG

traceur

Version:
1,311 lines 116 kB
"use strict"; function $__interopRequire(id) { id = require(id); return id && id.__esModule && id || {default: id}; } Object.defineProperties(module.exports, { __esModule: {value: true}, Parser: { enumerable: true, get: function() { return Parser; } } }); var $__createClass = $__interopRequire("traceur/dist/commonjs/runtime/modules/createClass.js").default; var $__superConstructor = $__interopRequire("traceur/dist/commonjs/runtime/modules/superConstructor.js").default; var FindVisitor = require("../codegeneration/FindVisitor.js").FindVisitor; var IdentifierToken = require("./IdentifierToken.js").IdentifierToken; var $__27 = require("./trees/ParseTreeType.js"), ARRAY_LITERAL = $__27.ARRAY_LITERAL, BINDING_IDENTIFIER = $__27.BINDING_IDENTIFIER, CALL_EXPRESSION = $__27.CALL_EXPRESSION, COMPUTED_PROPERTY_NAME = $__27.COMPUTED_PROPERTY_NAME, COVER_FORMALS = $__27.COVER_FORMALS, FORMAL_PARAMETER_LIST = $__27.FORMAL_PARAMETER_LIST, IDENTIFIER_EXPRESSION = $__27.IDENTIFIER_EXPRESSION, LITERAL_PROPERTY_NAME = $__27.LITERAL_PROPERTY_NAME, OBJECT_LITERAL = $__27.OBJECT_LITERAL, REST_PARAMETER = $__27.REST_PARAMETER, SYNTAX_ERROR_TREE = $__27.SYNTAX_ERROR_TREE; var Options = require("../Options.js").Options; var $__29 = require("./PredefinedName.js"), AS = $__29.AS, ASYNC = $__29.ASYNC, ASYNC_STAR = $__29.ASYNC_STAR, AWAIT = $__29.AWAIT, CONSTRUCTOR = $__29.CONSTRUCTOR, FROM = $__29.FROM, GET = $__29.GET, OF = $__29.OF, ON = $__29.ON, SET = $__29.SET, TYPE = $__29.TYPE; var SyntaxErrorReporter = require("../util/SyntaxErrorReporter.js").SyntaxErrorReporter; var $__31 = require("./Scanner.js"), getLastToken = $__31.getLastToken, getPosition = $__31.getPosition, initScanner = $__31.init, isAtEnd = $__31.isAtEnd, nextCloseAngle = $__31.nextCloseAngle, nextJsxTextToken = $__31.nextJsxTextToken, nextJsxToken = $__31.nextJsxToken, nextRegularExpressionLiteralToken = $__31.nextRegularExpressionLiteralToken, nextTemplateLiteralToken = $__31.nextTemplateLiteralToken, nextToken = $__31.nextToken, peek = $__31.peek, peekJsxToken = $__31.peekJsxToken, peekLocation = $__31.peekLocation, peekLookahead = $__31.peekLookahead, peekToken = $__31.peekToken, peekTokenLookahead = $__31.peekTokenLookahead, peekTokenNoLineTerminator = $__31.peekTokenNoLineTerminator, peekType = $__31.peekType, resetScanner = $__31.setIndex; var SourceRange = require("../util/SourceRange.js").SourceRange; var $__33 = require("./Token.js"), Token = $__33.Token, isAssignmentOperator = $__33.isAssignmentOperator; var getKeywordType = require("./Keywords.js").getKeywordType; var validateConstructor = require("../semantics/ConstructorValidator.js").validateConstructor; var validateParameters = $__interopRequire("../staticsemantics/validateParameters.js").default; var isValidSimpleAssignmentTarget = $__interopRequire("../staticsemantics/isValidSimpleAssignmentTarget.js").default; var $__38 = require("./TokenType.js"), AMPERSAND = $__38.AMPERSAND, AND = $__38.AND, ARROW = $__38.ARROW, AT = $__38.AT, BANG = $__38.BANG, BAR = $__38.BAR, BREAK = $__38.BREAK, CARET = $__38.CARET, CASE = $__38.CASE, CATCH = $__38.CATCH, CLASS = $__38.CLASS, CLOSE_ANGLE = $__38.CLOSE_ANGLE, CLOSE_CURLY = $__38.CLOSE_CURLY, CLOSE_PAREN = $__38.CLOSE_PAREN, CLOSE_SQUARE = $__38.CLOSE_SQUARE, COLON = $__38.COLON, COMMA = $__38.COMMA, CONST = $__38.CONST, CONTINUE = $__38.CONTINUE, DEBUGGER = $__38.DEBUGGER, DEFAULT = $__38.DEFAULT, DELETE = $__38.DELETE, DO = $__38.DO, DOT_DOT_DOT = $__38.DOT_DOT_DOT, ELSE = $__38.ELSE, END_OF_FILE = $__38.END_OF_FILE, EQUAL = $__38.EQUAL, EQUAL_EQUAL = $__38.EQUAL_EQUAL, EQUAL_EQUAL_EQUAL = $__38.EQUAL_EQUAL_EQUAL, ERROR = $__38.ERROR, EXPORT = $__38.EXPORT, EXTENDS = $__38.EXTENDS, FALSE = $__38.FALSE, FINALLY = $__38.FINALLY, FOR = $__38.FOR, FUNCTION = $__38.FUNCTION, GREATER_EQUAL = $__38.GREATER_EQUAL, IDENTIFIER = $__38.IDENTIFIER, IF = $__38.IF, IMPLEMENTS = $__38.IMPLEMENTS, IMPORT = $__38.IMPORT, IN = $__38.IN, INSTANCEOF = $__38.INSTANCEOF, INTERFACE = $__38.INTERFACE, JSX_IDENTIFIER = $__38.JSX_IDENTIFIER, LEFT_SHIFT = $__38.LEFT_SHIFT, LESS_EQUAL = $__38.LESS_EQUAL, LET = $__38.LET, MINUS = $__38.MINUS, MINUS_MINUS = $__38.MINUS_MINUS, NEW = $__38.NEW, NO_SUBSTITUTION_TEMPLATE = $__38.NO_SUBSTITUTION_TEMPLATE, NOT_EQUAL = $__38.NOT_EQUAL, NOT_EQUAL_EQUAL = $__38.NOT_EQUAL_EQUAL, NULL = $__38.NULL, NUMBER = $__38.NUMBER, OPEN_ANGLE = $__38.OPEN_ANGLE, OPEN_CURLY = $__38.OPEN_CURLY, OPEN_PAREN = $__38.OPEN_PAREN, OPEN_SQUARE = $__38.OPEN_SQUARE, OR = $__38.OR, PACKAGE = $__38.PACKAGE, PERCENT = $__38.PERCENT, PERIOD = $__38.PERIOD, PLUS = $__38.PLUS, PLUS_PLUS = $__38.PLUS_PLUS, PRIVATE = $__38.PRIVATE, PROTECTED = $__38.PROTECTED, PUBLIC = $__38.PUBLIC, QUESTION = $__38.QUESTION, RETURN = $__38.RETURN, RIGHT_SHIFT = $__38.RIGHT_SHIFT, SEMI_COLON = $__38.SEMI_COLON, SLASH = $__38.SLASH, SLASH_EQUAL = $__38.SLASH_EQUAL, STAR = $__38.STAR, STAR_STAR = $__38.STAR_STAR, STATIC = $__38.STATIC, STRING = $__38.STRING, SUPER = $__38.SUPER, SWITCH = $__38.SWITCH, TEMPLATE_HEAD = $__38.TEMPLATE_HEAD, TEMPLATE_TAIL = $__38.TEMPLATE_TAIL, THIS = $__38.THIS, THROW = $__38.THROW, TILDE = $__38.TILDE, TRUE = $__38.TRUE, TRY = $__38.TRY, TYPEOF = $__38.TYPEOF, UNSIGNED_RIGHT_SHIFT = $__38.UNSIGNED_RIGHT_SHIFT, VAR = $__38.VAR, VOID = $__38.VOID, WHILE = $__38.WHILE, WITH = $__38.WITH, YIELD = $__38.YIELD; var $__39 = require("./trees/ParseTrees.js"), ArgumentList = $__39.ArgumentList, ArrayComprehension = $__39.ArrayComprehension, ArrayLiteral = $__39.ArrayLiteral, ArrayPattern = $__39.ArrayPattern, ArrayType = $__39.ArrayType, ArrowFunction = $__39.ArrowFunction, AssignmentElement = $__39.AssignmentElement, AwaitExpression = $__39.AwaitExpression, BinaryExpression = $__39.BinaryExpression, BindingElement = $__39.BindingElement, BindingIdentifier = $__39.BindingIdentifier, Block = $__39.Block, BreakStatement = $__39.BreakStatement, CallExpression = $__39.CallExpression, CallSignature = $__39.CallSignature, CaseClause = $__39.CaseClause, Catch = $__39.Catch, ClassDeclaration = $__39.ClassDeclaration, ClassExpression = $__39.ClassExpression, CommaExpression = $__39.CommaExpression, ComprehensionFor = $__39.ComprehensionFor, ComprehensionIf = $__39.ComprehensionIf, ComputedPropertyName = $__39.ComputedPropertyName, ConditionalExpression = $__39.ConditionalExpression, ConstructSignature = $__39.ConstructSignature, ConstructorType = $__39.ConstructorType, ContinueStatement = $__39.ContinueStatement, CoverFormals = $__39.CoverFormals, CoverInitializedName = $__39.CoverInitializedName, DebuggerStatement = $__39.DebuggerStatement, Annotation = $__39.Annotation, DefaultClause = $__39.DefaultClause, DoWhileStatement = $__39.DoWhileStatement, EmptyStatement = $__39.EmptyStatement, ExportDeclaration = $__39.ExportDeclaration, ExportDefault = $__39.ExportDefault, ExportSpecifier = $__39.ExportSpecifier, ExportSpecifierSet = $__39.ExportSpecifierSet, ExportStar = $__39.ExportStar, ExpressionStatement = $__39.ExpressionStatement, Finally = $__39.Finally, ForInStatement = $__39.ForInStatement, ForOfStatement = $__39.ForOfStatement, ForOnStatement = $__39.ForOnStatement, ForStatement = $__39.ForStatement, FormalParameter = $__39.FormalParameter, FormalParameterList = $__39.FormalParameterList, ForwardDefaultExport = $__39.ForwardDefaultExport, FunctionBody = $__39.FunctionBody, FunctionDeclaration = $__39.FunctionDeclaration, FunctionExpression = $__39.FunctionExpression, FunctionType = $__39.FunctionType, GeneratorComprehension = $__39.GeneratorComprehension, GetAccessor = $__39.GetAccessor, IdentifierExpression = $__39.IdentifierExpression, IfStatement = $__39.IfStatement, ImportClausePair = $__39.ImportClausePair, ImportDeclaration = $__39.ImportDeclaration, ImportSpecifier = $__39.ImportSpecifier, ImportSpecifierSet = $__39.ImportSpecifierSet, ImportedBinding = $__39.ImportedBinding, ImportTypeClause = $__39.ImportTypeClause, IndexSignature = $__39.IndexSignature, InterfaceDeclaration = $__39.InterfaceDeclaration, JsxAttribute = $__39.JsxAttribute, JsxElement = $__39.JsxElement, JsxElementName = $__39.JsxElementName, JsxPlaceholder = $__39.JsxPlaceholder, JsxSpreadAttribute = $__39.JsxSpreadAttribute, JsxText = $__39.JsxText, LabelledStatement = $__39.LabelledStatement, LiteralExpression = $__39.LiteralExpression, LiteralPropertyName = $__39.LiteralPropertyName, MemberExpression = $__39.MemberExpression, MemberLookupExpression = $__39.MemberLookupExpression, Method = $__39.Method, MethodSignature = $__39.MethodSignature, Module = $__39.Module, ModuleSpecifier = $__39.ModuleSpecifier, NameSpaceExport = $__39.NameSpaceExport, NameSpaceImport = $__39.NameSpaceImport, NamedExport = $__39.NamedExport, NewExpression = $__39.NewExpression, ObjectLiteral = $__39.ObjectLiteral, ObjectPattern = $__39.ObjectPattern, ObjectPatternField = $__39.ObjectPatternField, ObjectType = $__39.ObjectType, ParenExpression = $__39.ParenExpression, PostfixExpression = $__39.PostfixExpression, PredefinedType = $__39.PredefinedType, PropertyNameAssignment = $__39.PropertyNameAssignment, PropertyNameShorthand = $__39.PropertyNameShorthand, PropertySignature = $__39.PropertySignature, PropertyVariableDeclaration = $__39.PropertyVariableDeclaration, RestParameter = $__39.RestParameter, ReturnStatement = $__39.ReturnStatement, Script = $__39.Script, SetAccessor = $__39.SetAccessor, SpreadExpression = $__39.SpreadExpression, SpreadPatternElement = $__39.SpreadPatternElement, SuperExpression = $__39.SuperExpression, SwitchStatement = $__39.SwitchStatement, SyntaxErrorTree = $__39.SyntaxErrorTree, TemplateLiteralExpression = $__39.TemplateLiteralExpression, TemplateLiteralPortion = $__39.TemplateLiteralPortion, TemplateSubstitution = $__39.TemplateSubstitution, ThisExpression = $__39.ThisExpression, ThrowStatement = $__39.ThrowStatement, TryStatement = $__39.TryStatement, TypeAliasDeclaration = $__39.TypeAliasDeclaration, TypeArguments = $__39.TypeArguments, TypeName = $__39.TypeName, TypeParameter = $__39.TypeParameter, TypeParameters = $__39.TypeParameters, TypeReference = $__39.TypeReference, UnaryExpression = $__39.UnaryExpression, UnionType = $__39.UnionType, VariableDeclaration = $__39.VariableDeclaration, VariableDeclarationList = $__39.VariableDeclarationList, VariableStatement = $__39.VariableStatement, WhileStatement = $__39.WhileStatement, WithStatement = $__39.WithStatement, YieldExpression = $__39.YieldExpression; var ALLOW_IN = true; var NO_IN = false; var INITIALIZER_REQUIRED = true; var INITIALIZER_OPTIONAL = false; var ValidateObjectLiteral = function($__super) { function ValidateObjectLiteral() { $__superConstructor(ValidateObjectLiteral).call(this); this.errorToken = null; } return ($__createClass)(ValidateObjectLiteral, {visitCoverInitializedName: function(tree) { this.errorToken = tree.equalToken; this.found = true; }}, {}, $__super); }(FindVisitor); function containsInitializer(declarations) { return declarations.some(function(v) { return v.initializer; }); } var FUNCTION_STATE_SCRIPT = 1; var FUNCTION_STATE_MODULE = 1 << 1; var FUNCTION_STATE_FUNCTION = 1 << 2; var FUNCTION_STATE_ARROW = 1 << 3; var FUNCTION_STATE_METHOD = 1 << 4; var FUNCTION_STATE_DERIVED_CONSTRUCTOR = 1 << 5; var FUNCTION_STATE_GENERATOR = 1 << 6; var FUNCTION_STATE_ASYNC = 1 << 7; var FUNCTION_STATE_LENIENT = FUNCTION_STATE_METHOD | FUNCTION_STATE_GENERATOR | FUNCTION_STATE_ASYNC | FUNCTION_STATE_DERIVED_CONSTRUCTOR; var FunctionState = function() { function FunctionState(outer, kind) { this.outer = outer; this.kind = kind; } return ($__createClass)(FunctionState, { isTopMost: function() { return this.kind & (FUNCTION_STATE_SCRIPT | FUNCTION_STATE_MODULE); }, isMethod: function() { return this.kind & FUNCTION_STATE_METHOD; }, isDerivedConstructor: function() { return this.kind & FUNCTION_STATE_DERIVED_CONSTRUCTOR; }, isArrowFunction: function() { return this.kind & FUNCTION_STATE_ARROW; }, isGenerator: function() { return this.kind & FUNCTION_STATE_GENERATOR; }, isAsyncFunction: function() { return this.kind & FUNCTION_STATE_ASYNC; }, isAsyncGenerator: function() { return this.isGenerator() && this.isAsyncFunction(); } }, {}); }(); var Parser = function() { function Parser(file) { var errorReporter = arguments[1] !== (void 0) ? arguments[1] : new SyntaxErrorReporter(); var options = arguments[2] !== (void 0) ? arguments[2] : new Options(); this.errorReporter_ = errorReporter; initScanner(errorReporter, file, this, options); this.options_ = options; this.coverInitializedNameCount_ = 0; this.strictMode_ = false; this.annotations_ = []; this.functionState_ = null; } return ($__createClass)(Parser, { get allowYield_() { return this.functionState_.isGenerator(); }, get allowAwait_() { return this.functionState_.isAsyncFunction(); }, get allowForOn_() { return this.functionState_.isAsyncFunction(); }, parseScript: function() { this.strictMode_ = false; var start = this.getTreeStartLocation_(); var fs = this.pushFunctionState_(FUNCTION_STATE_SCRIPT); var scriptItemList = this.parseStatementList_(true); this.eat_(END_OF_FILE); this.popFunctionState_(fs); return new Script(this.getTreeLocation_(start), scriptItemList, null); }, pushFunctionState_: function(kind) { return this.functionState_ = new FunctionState(this.functionState_, kind); }, popFunctionState_: function(fs) { if (fs != this.functionState_) { throw new Error('Internal error'); } this.functionState_ = this.functionState_.outer; }, parseStatementList_: function(checkUseStrictDirective) { var result = []; var type; while ((type = peekType()) !== CLOSE_CURLY && type !== END_OF_FILE) { var statement = this.parseStatementListItem_(type); if (checkUseStrictDirective) { if (!statement.isDirectivePrologue()) { checkUseStrictDirective = false; } else if (statement.isUseStrictDirective()) { this.strictMode_ = true; checkUseStrictDirective = false; } } result.push(statement); } return result; }, parseStatementListItem_: function(type) { switch (type) { case LET: case CONST: if (this.options_.blockBinding) { return this.parseVariableStatement_(); } break; case CLASS: if (this.options_.classes) { return this.parseClassDeclaration_(); } break; case FUNCTION: return this.parseFunctionDeclaration_(); case IDENTIFIER: if (this.options_.types && this.peekPredefinedString_(TYPE) && peekLookahead(IDENTIFIER)) { return this.parseTypeAliasDeclaration_(); } break; } return this.parseStatementWithType_(type); }, parseModule: function() { var start = this.getTreeStartLocation_(); var fs = this.pushFunctionState_(FUNCTION_STATE_MODULE); var scriptItemList = this.parseModuleItemList_(); this.eat_(END_OF_FILE); this.popFunctionState_(fs); return new Module(this.getTreeLocation_(start), scriptItemList, null); }, parseModuleItemList_: function() { this.strictMode_ = true; var result = []; var type; while ((type = peekType()) !== END_OF_FILE) { var statement = this.parseModuleItem_(type); result.push(statement); } return result; }, parseModuleItem_: function(type) { switch (type) { case IMPORT: return this.parseImportDeclaration_(); case EXPORT: return this.parseExportDeclaration_(); case AT: if (this.options_.annotations) return this.parseAnnotatedDeclarations_(true); break; } return this.parseStatementListItem_(type); }, parseModuleSpecifier_: function() { var start = this.getTreeStartLocation_(); var token = this.eat_(STRING); return new ModuleSpecifier(this.getTreeLocation_(start), token); }, parseNameSpaceImport_: function() { var start = this.getTreeStartLocation_(); this.eat_(STAR); this.eatId_(AS); var binding = this.parseImportedBinding_(); return new NameSpaceImport(this.getTreeLocation_(start), binding); }, parseImportDeclaration_: function() { var start = this.getTreeStartLocation_(); this.eat_(IMPORT); var importClause = null; if (!peek(STRING)) { importClause = this.parseImportClause_(true, this.options_.types); this.eatId_(FROM); } var moduleSpecifier = this.parseModuleSpecifier_(); this.eatPossibleImplicitSemiColon_(); return new ImportDeclaration(this.getTreeLocation_(start), importClause, moduleSpecifier); }, parseImportClause_: function(allowImportedDefaultBinding, allowType) { switch (peekType()) { case STAR: return this.parseNameSpaceImport_(); case OPEN_CURLY: return this.parseImportSpecifierSet_(); case IDENTIFIER: if (allowType && this.peekPredefinedString_(TYPE)) { var start = this.getTreeStartLocation_(); var t = peekTokenLookahead(); if (t.type === OPEN_CURLY || t.type === IDENTIFIER && t.value !== FROM) { this.eatId_(TYPE); var clause = this.parseImportClause_(allowImportedDefaultBinding, false); return new ImportTypeClause(this.getTreeLocation_(start), clause); } } if (allowImportedDefaultBinding) { var start$__4 = this.getTreeStartLocation_(); var importedBinding = this.parseImportedBinding_(); if (this.eatIf_(COMMA)) { var second = this.parseImportClause_(false, false); return new ImportClausePair(this.getTreeLocation_(start$__4), importedBinding, second); } return importedBinding; } break; } return this.parseUnexpectedToken_(); }, parseImportSpecifierSet_: function() { var start = this.getTreeStartLocation_(); var specifiers = []; this.eat_(OPEN_CURLY); while (!peek(CLOSE_CURLY) && !isAtEnd()) { specifiers.push(this.parseImportSpecifier_()); if (!this.eatIf_(COMMA)) break; } this.eat_(CLOSE_CURLY); return new ImportSpecifierSet(this.getTreeLocation_(start), specifiers); }, parseImportedBinding_: function() { var start = this.getTreeStartLocation_(); var binding = this.parseBindingIdentifier_(); return new ImportedBinding(this.getTreeLocation_(start), binding); }, parseImportSpecifier_: function() { var start = this.getTreeStartLocation_(); var token = peekToken(); var isKeyword = token.isKeyword(); var binding; var name = this.eatIdName_(); if (isKeyword || this.peekPredefinedString_(AS)) { this.eatId_(AS); binding = this.parseImportedBinding_(); } else { binding = new ImportedBinding(name.location, new BindingIdentifier(name.location, name)); name = null; } return new ImportSpecifier(this.getTreeLocation_(start), binding, name); }, parseExportDeclaration_: function() { var start = this.getTreeStartLocation_(); this.eat_(EXPORT); var exportTree; var annotations = this.popAnnotations_(); var type = peekType(); switch (type) { case CONST: case LET: if (this.options_.blockBinding) { exportTree = this.parseVariableStatement_(); break; } return this.parseUnexpectedToken_(); case VAR: exportTree = this.parseVariableStatement_(); break; case FUNCTION: exportTree = this.parseFunctionDeclaration_(); break; case CLASS: exportTree = this.parseClassDeclaration_(); break; case DEFAULT: exportTree = this.parseExportDefault_(); break; case OPEN_CURLY: case STAR: exportTree = this.parseNamedExport_(); break; case IDENTIFIER: if (this.options_.asyncFunctions && this.peekPredefinedString_(ASYNC)) { var asyncToken = this.eatId_(); exportTree = this.parseAsyncFunctionDeclaration_(asyncToken); } else if (this.options_.types && this.peekPredefinedString_(TYPE) && peekLookahead(IDENTIFIER)) { exportTree = this.parseTypeAliasDeclaration_(); } else if (this.options_.exportFromExtended) { exportTree = this.parseNamedExport_(); } else { return this.parseUnexpectedToken_(); } break; default: { var token = peekToken(); if (!token.isKeyword()) { return this.parseUnexpectedToken_(); } exportTree = this.parseNamedExport_(); } } return new ExportDeclaration(this.getTreeLocation_(start), exportTree, annotations); }, parseExportDefault_: function() { var start = this.getTreeStartLocation_(); var defaultToken = this.eat_(DEFAULT); if (this.options_.exportFromExtended && this.peekPredefinedString_(FROM)) { var idName = new IdentifierToken(defaultToken.location, DEFAULT); var namedExport = new ForwardDefaultExport(this.getTreeLocation_(start), idName); this.eatId_(FROM); var moduleSpecifier = this.parseModuleSpecifier_(); return new NamedExport(this.getTreeLocation_(start), namedExport, moduleSpecifier); } var exportValue; switch (peekType()) { case FUNCTION: { var tree = this.parseFunctionExpression_(); if (tree.name) { tree = new FunctionDeclaration(tree.location, tree.name, tree.functionKind, tree.parameterList, tree.typeAnnotation, tree.annotations, tree.body); } exportValue = tree; break; } case CLASS: { if (!this.options_.classes) { return this.parseSyntaxError_('Unexpected reserved word'); } var tree$__5 = this.parseClassExpression_(); if (tree$__5.name) { tree$__5 = new ClassDeclaration(tree$__5.location, tree$__5.name, tree$__5.superClass, tree$__5.elements, tree$__5.annotations, tree$__5.typeParameters); } exportValue = tree$__5; break; } default: exportValue = this.parseAssignmentExpression_(ALLOW_IN); this.eatPossibleImplicitSemiColon_(); } return new ExportDefault(this.getTreeLocation_(start), exportValue); }, parseNamedExport_: function() { var start = this.getTreeStartLocation_(); var exportClause, moduleSpecifier = null; switch (peekType()) { case OPEN_CURLY: exportClause = this.parseExportSpecifierSet_(); if (this.peekPredefinedString_(FROM)) { this.eatId_(FROM); moduleSpecifier = this.parseModuleSpecifier_(); } else { this.validateExportSpecifierSet_(exportClause); } break; case STAR: exportClause = this.parseExportStar_(); this.eatId_(FROM); moduleSpecifier = this.parseModuleSpecifier_(); break; default: exportClause = this.parseForwardDefaultExport_(); this.eatId_(FROM); moduleSpecifier = this.parseModuleSpecifier_(); break; } this.eatPossibleImplicitSemiColon_(); return new NamedExport(this.getTreeLocation_(start), exportClause, moduleSpecifier); }, parseExportStar_: function() { var start = this.getTreeStartLocation_(); this.eat_(STAR); if (this.peekPredefinedString_(AS)) { this.eatId_(AS); var name = this.eatIdName_(); return new NameSpaceExport(this.getTreeLocation_(start), name); } return new ExportStar(this.getTreeLocation_(start)); }, parseExportSpecifierSet_: function() { var start = this.getTreeStartLocation_(); this.eat_(OPEN_CURLY); var specifiers = [this.parseExportSpecifier_()]; while (this.eatIf_(COMMA)) { if (peek(CLOSE_CURLY)) break; specifiers.push(this.parseExportSpecifier_()); } this.eat_(CLOSE_CURLY); return new ExportSpecifierSet(this.getTreeLocation_(start), specifiers); }, parseExportSpecifier_: function() { var start = this.getTreeStartLocation_(); var lhs = this.eatIdName_(); var rhs = null; if (this.peekPredefinedString_(AS)) { this.eatId_(); rhs = this.eatIdName_(); } return new ExportSpecifier(this.getTreeLocation_(start), lhs, rhs); }, parseForwardDefaultExport_: function() { var start = this.getTreeStartLocation_(); var idName = this.eatIdName_(); return new ForwardDefaultExport(this.getTreeLocation_(start), idName); }, validateExportSpecifierSet_: function(tree) { for (var i = 0; i < tree.specifiers.length; i++) { var specifier = tree.specifiers[i]; if (getKeywordType(specifier.lhs.value)) { this.reportError_(specifier.lhs.location, ("Unexpected token " + specifier.lhs.value)); } } }, peekId_: function(type) { if (type === IDENTIFIER) return true; if (this.strictMode_) return false; return peekToken().isStrictKeyword(); }, peekIdName_: function(token) { return token.type === IDENTIFIER || token.isKeyword(); }, parseClassShared_: function(constr) { var start = this.getTreeStartLocation_(); var strictMode = this.strictMode_; this.strictMode_ = true; this.eat_(CLASS); var name = null; var typeParameters = null; var annotations = []; if (constr === ClassDeclaration || !peek(EXTENDS) && !peek(OPEN_CURLY)) { name = this.parseBindingIdentifier_(); if (this.options_.types) { typeParameters = this.parseTypeParametersOpt_(); } annotations = this.popAnnotations_(); } var superClass = null; if (this.eatIf_(EXTENDS)) { superClass = this.parseLeftHandSideExpression_(); superClass = this.coverFormalsToParenExpression_(superClass); } this.eat_(OPEN_CURLY); var elements = this.parseClassElements_(superClass); this.eat_(CLOSE_CURLY); this.strictMode_ = strictMode; return new constr(this.getTreeLocation_(start), name, superClass, elements, annotations, typeParameters); }, parseClassDeclaration_: function() { return this.parseClassShared_(ClassDeclaration); }, parseClassExpression_: function() { return this.parseClassShared_(ClassExpression); }, parseClassElements_: function(derivedClass) { var result = []; while (true) { var type = peekType(); if (type === SEMI_COLON) { nextToken(); } else if (this.peekClassElement_(peekType())) { result.push(this.parseClassElement_(derivedClass)); } else { break; } } return result; }, peekClassElement_: function(type) { return this.peekPropertyName_(type) || type === STAR && this.options_.generators || type === AT && this.options_.annotations; }, parsePropertyName_: function() { if (peek(OPEN_SQUARE)) return this.parseComputedPropertyName_(); return this.parseLiteralPropertyName_(); }, parseLiteralPropertyName_: function() { var start = this.getTreeStartLocation_(); var token = nextToken(); return new LiteralPropertyName(this.getTreeLocation_(start), token); }, parseComputedPropertyName_: function() { var start = this.getTreeStartLocation_(); this.eat_(OPEN_SQUARE); var expression = this.parseAssignmentExpression_(ALLOW_IN); this.eat_(CLOSE_SQUARE); return new ComputedPropertyName(this.getTreeLocation_(start), expression); }, parseStatement: function() { var fs = this.pushFunctionState_(FUNCTION_STATE_LENIENT); var result = this.parseModuleItem_(peekType()); this.popFunctionState_(fs); return result; }, parseStatements: function() { var fs = this.pushFunctionState_(FUNCTION_STATE_LENIENT); var result = this.parseModuleItemList_(); this.popFunctionState_(fs); return result; }, parseStatement_: function() { return this.parseStatementWithType_(peekType()); }, parseStatementWithType_: function(type) { switch (type) { case RETURN: return this.parseReturnStatement_(); case VAR: return this.parseVariableStatement_(); case IF: return this.parseIfStatement_(); case FOR: return this.parseForStatement_(); case BREAK: return this.parseBreakStatement_(); case SWITCH: return this.parseSwitchStatement_(); case THROW: return this.parseThrowStatement_(); case WHILE: return this.parseWhileStatement_(); case AT: if (this.options_.annotations) return this.parseAnnotatedDeclarations_(false); break; case CONTINUE: return this.parseContinueStatement_(); case DEBUGGER: return this.parseDebuggerStatement_(); case DO: return this.parseDoWhileStatement_(); case OPEN_CURLY: return this.parseBlock_(); case SEMI_COLON: return this.parseEmptyStatement_(); case TRY: return this.parseTryStatement_(); case WITH: return this.parseWithStatement_(); case INTERFACE: if (this.options_.types) { return this.parseInterfaceDeclaration_(); } } return this.parseFallThroughStatement_(); }, parseFunctionDeclaration_: function() { return this.parseFunction_(FunctionDeclaration); }, parseFunctionExpression_: function() { return this.parseFunction_(FunctionExpression); }, parseAsyncFunctionDeclaration_: function(asyncToken) { return this.parseAsyncFunction_(asyncToken, FunctionDeclaration); }, parseAsyncFunctionExpression_: function(asyncToken) { return this.parseAsyncFunction_(asyncToken, FunctionExpression); }, peekAsyncStar_: function() { return this.options_.asyncGenerators && peek(STAR); }, parseAsyncFunction_: function(asyncToken, ctor) { var start = asyncToken.location.start; this.eat_(FUNCTION); var kind = FUNCTION_STATE_FUNCTION | FUNCTION_STATE_ASYNC; if (this.peekAsyncStar_()) { kind |= FUNCTION_STATE_GENERATOR; this.eat_(STAR); asyncToken = new IdentifierToken(asyncToken.location, ASYNC_STAR); } var fs = this.pushFunctionState_(kind); var f = this.parseFunction2_(start, asyncToken, ctor); this.popFunctionState_(fs); return f; }, parseFunction_: function(ctor) { var start = this.getTreeStartLocation_(); this.eat_(FUNCTION); var functionKind = null; var kind = FUNCTION_STATE_FUNCTION; if (this.options_.generators && peek(STAR)) { functionKind = this.eat_(STAR); kind |= FUNCTION_STATE_GENERATOR; } var fs = this.pushFunctionState_(kind); var f = this.parseFunction2_(start, functionKind, ctor); this.popFunctionState_(fs); return f; }, parseFunction2_: function(start, functionKind, ctor) { var name = null; var annotations = []; if (ctor === FunctionDeclaration || this.peekBindingIdentifier_(peekType())) { name = this.parseBindingIdentifier_(); annotations = this.popAnnotations_(); } this.eat_(OPEN_PAREN); var parameters = this.parseFormalParameters_(); this.eat_(CLOSE_PAREN); var typeAnnotation = this.parseTypeAnnotationOpt_(); var body = this.parseFunctionBody_(parameters); return new ctor(this.getTreeLocation_(start), name, functionKind, parameters, typeAnnotation, annotations, body); }, peekRest_: function(type) { return type === DOT_DOT_DOT && this.options_.restParameters; }, parseFormalParameters_: function() { var start = this.getTreeStartLocation_(); var formals = []; this.pushAnnotations_(); var type = peekType(); if (this.peekRest_(type)) { formals.push(this.parseFormalRestParameter_()); } else { if (this.peekFormalParameter_(peekType())) formals.push(this.parseFormalParameter_(INITIALIZER_OPTIONAL)); while (this.eatIf_(COMMA)) { this.pushAnnotations_(); if (this.peekRest_(peekType())) { formals.push(this.parseFormalRestParameter_()); break; } formals.push(this.parseFormalParameter_(INITIALIZER_OPTIONAL)); } } return new FormalParameterList(this.getTreeLocation_(start), formals); }, peekFormalParameter_: function(type) { return this.peekBindingElement_(type); }, parseFormalParameter_: function(initializerAllowed) { var start = this.getTreeStartLocation_(); var binding = this.parseBindingElementBinding_(); var typeAnnotation = this.parseTypeAnnotationOpt_(); var initializer = this.parseBindingElementInitializer_(initializerAllowed); return new FormalParameter(this.getTreeLocation_(start), new BindingElement(this.getTreeLocation_(start), binding, initializer), typeAnnotation, this.popAnnotations_()); }, parseFormalRestParameter_: function() { var start = this.getTreeStartLocation_(); var restParameter = this.parseRestParameter_(); var typeAnnotation = this.parseTypeAnnotationOpt_(); return new FormalParameter(this.getTreeLocation_(start), restParameter, typeAnnotation, this.popAnnotations_()); }, parseRestParameter_: function() { var start = this.getTreeStartLocation_(); this.eat_(DOT_DOT_DOT); var id = this.parseBindingIdentifier_(); var typeAnnotation = this.parseTypeAnnotationOpt_(); return new RestParameter(this.getTreeLocation_(start), id, typeAnnotation); }, parseFunctionBody_: function(params) { var start = this.getTreeStartLocation_(); this.eat_(OPEN_CURLY); var strictMode = this.strictMode_; var result = this.parseStatementList_(!strictMode); validateParameters(params, this.strictMode_, this.errorReporter_); this.strictMode_ = strictMode; this.eat_(CLOSE_CURLY); return new FunctionBody(this.getTreeLocation_(start), result); }, parseSpreadExpression_: function() { var start = this.getTreeStartLocation_(); this.eat_(DOT_DOT_DOT); var operand = this.parseAssignmentExpression_(ALLOW_IN); return new SpreadExpression(this.getTreeLocation_(start), operand); }, parseBlock_: function() { var start = this.getTreeStartLocation_(); this.eat_(OPEN_CURLY); var result = this.parseStatementList_(false); this.eat_(CLOSE_CURLY); return new Block(this.getTreeLocation_(start), result); }, parseVariableStatement_: function() { var start = this.getTreeStartLocation_(); var declarations = this.parseVariableDeclarationList_(ALLOW_IN, INITIALIZER_REQUIRED); this.checkInitializers_(declarations); this.eatPossibleImplicitSemiColon_(); return new VariableStatement(this.getTreeLocation_(start), declarations); }, parseVariableDeclarationList_: function(allowIn, initializerRequired) { var type = peekType(); switch (type) { case CONST: case LET: case VAR: nextToken(); break; default: throw Error('unreachable'); } var start = this.getTreeStartLocation_(); var declarations = []; declarations.push(this.parseVariableDeclaration_(type, allowIn, initializerRequired)); while (this.eatIf_(COMMA)) { declarations.push(this.parseVariableDeclaration_(type, allowIn, initializerRequired)); } return new VariableDeclarationList(this.getTreeLocation_(start), type, declarations); }, parseVariableDeclaration_: function(binding, noIn, initializerRequired) { var initRequired = initializerRequired !== INITIALIZER_OPTIONAL; var start = this.getTreeStartLocation_(); var lvalue; var typeAnnotation; if (this.peekPattern_(peekType())) { lvalue = this.parseBindingPattern_(); typeAnnotation = null; } else { lvalue = this.parseBindingIdentifier_(); typeAnnotation = this.parseTypeAnnotationOpt_(); } var init = null; if (peek(EQUAL)) { init = this.parseInitializer_(noIn); } else if (lvalue.isPattern() && initRequired) { this.reportError_(lvalue.location, 'destructuring must have an initializer'); } return new VariableDeclaration(this.getTreeLocation_(start), lvalue, typeAnnotation, init); }, parseInitializer_: function(allowIn) { this.eat_(EQUAL); return this.parseAssignmentExpression_(allowIn); }, parseInitializerOpt_: function(allowIn) { if (this.eatIf_(EQUAL)) return this.parseAssignmentExpression_(allowIn); return null; }, parseEmptyStatement_: function() { var start = this.getTreeStartLocation_(); this.eat_(SEMI_COLON); return new EmptyStatement(this.getTreeLocation_(start)); }, parseFallThroughStatement_: function() { var start = this.getTreeStartLocation_(); var expression; switch (peekType()) { case OPEN_CURLY: return this.parseUnexpectedToken_(); case FUNCTION: case CLASS: return this.parseUnexpectedReservedWord_(peekToken()); case LET: { var token = peekLookahead(OPEN_SQUARE); if (token) { return this.parseSyntaxError_("A statement cannot start with 'let ['"); } } } if (this.options_.asyncFunctions && this.peekPredefinedString_(ASYNC) && peekLookahead(FUNCTION)) { var asyncToken = this.eatId_(); var functionToken = peekTokenNoLineTerminator(); if (functionToken !== null) return this.parseAsyncFunctionDeclaration_(asyncToken); expression = new IdentifierExpression(this.getTreeLocation_(start), asyncToken); } else { expression = this.parseExpression_(ALLOW_IN); } if (expression.type === IDENTIFIER_EXPRESSION) { if (this.eatIf_(COLON)) { var nameToken = expression.identifierToken; var statement = this.parseStatement_(); return new LabelledStatement(this.getTreeLocation_(start), nameToken, statement); } } this.eatPossibleImplicitSemiColon_(); return new ExpressionStatement(this.getTreeLocation_(start), expression); }, parseIfStatement_: function() { var start = this.getTreeStartLocation_(); this.eat_(IF); this.eat_(OPEN_PAREN); var condition = this.parseExpression_(ALLOW_IN); this.eat_(CLOSE_PAREN); var ifClause = this.parseStatement_(); var elseClause = null; if (this.eatIf_(ELSE)) { elseClause = this.parseStatement_(); } return new IfStatement(this.getTreeLocation_(start), condition, ifClause, elseClause); }, parseDoWhileStatement_: function() { var start = this.getTreeStartLocation_(); this.eat_(DO); var body = this.parseStatement_(); this.eat_(WHILE); this.eat_(OPEN_PAREN); var condition = this.parseExpression_(ALLOW_IN); this.eat_(CLOSE_PAREN); this.eatPossibleImplicitSemiColon_(); return new DoWhileStatement(this.getTreeLocation_(start), body, condition); }, parseWhileStatement_: function() { var start = this.getTreeStartLocation_(); this.eat_(WHILE); this.eat_(OPEN_PAREN); var condition = this.parseExpression_(ALLOW_IN); this.eat_(CLOSE_PAREN); var body = this.parseStatement_(); return new WhileStatement(this.getTreeLocation_(start), condition, body); }, parseForStatement_: function() { var start = this.getTreeStartLocation_(); this.eat_(FOR); this.eat_(OPEN_PAREN); var type = peekType(); if (this.peekVariableDeclarationList_(type)) { var variables = this.parseVariableDeclarationList_(NO_IN, INITIALIZER_OPTIONAL); var declarations = variables.declarations; if (declarations.length > 1 || containsInitializer(declarations)) { return this.parseForStatement2_(start, variables); } type = peekType(); if (type === IN) { return this.parseForInStatement_(start, variables); } else if (this.peekOf_()) { return this.parseForOfStatement_(start, variables); } else if (this.allowForOn_ && this.peekOn_()) { return this.parseForOnStatement_(start, variables); } else { this.checkInitializers_(variables); return this.parseForStatement2_(start, variables); } } if (type === SEMI_COLON) { return this.parseForStatement2_(start, null); } var coverInitializedNameCount = this.coverInitializedNameCount_; var initializer = this.parseExpressionAllowPattern_(NO_IN); type = peekType(); if ((type === IN || this.peekOf_() || this.allowForOn_ && this.peekOn_())) { initializer = this.transformLeftHandSideExpression_(initializer); this.validateAssignmentTarget_(initializer, 'assignment'); if (this.peekOf_()) { return this.parseForOfStatement_(start, initializer); } else if (this.allowForOn_ && this.peekOn_()) { return this.parseForOnStatement_(start, initializer); } return this.parseForInStatement_(start, initializer); } this.ensureNoCoverInitializedNames_(initializer, coverInitializedNameCount); return this.parseForStatement2_(start, initializer); }, peekOf_: function() { return this.options_.forOf && this.peekPredefinedString_(OF); }, peekOn_: function() { return this.options_.forOn && this.peekPredefinedString_(ON); }, parseForOfStatement_: function(start, initializer) { this.eatId_(); var collection = this.parseExpression_(ALLOW_IN); this.eat_(CLOSE_PAREN); var body = this.parseStatement_(); return new ForOfStatement(this.getTreeLocation_(start), initializer, collection, body); }, parseForOnStatement_: function(start, initializer) { this.eatId_(); var observable = this.parseExpression_(ALLOW_IN); this.eat_(CLOSE_PAREN); var body = this.parseStatement_(); return new ForOnStatement(this.getTreeLocation_(start), initializer, observable, body); }, checkInitializers_: function(variables) { if (this.options_.blockBinding && variables.declarationType === CONST) { var type = variables.declarationType; for (var i = 0; i < variables.declarations.length; i++) { if (!this.checkInitializer_(type, variables.declarations[i])) { break; } } } }, checkInitializer_: function(type, declaration) { if (this.options_.blockBinding && type === CONST && declaration.initializer === null) { this.reportError_(declaration.location, 'const variables must have an initializer'); return false; } return true; }, peekVariableDeclarationList_: function(type) { switch (type) { case VAR: return true; case CONST: case LET: return this.options_.blockBinding; default: return false; } }, parseForStatement2_: function(start, initializer) { this.eat_(SEMI_COLON); var condition = null; if (!peek(SEMI_COLON)) { condition = this.parseExpression_(ALLOW_IN); } this.eat_(SEMI_COLON); var increment = null; if (!peek(CLOSE_PAREN)) { increment = this.parseExpression_(ALLOW_IN); } this.eat_(CLOSE_PAREN); var body = this.parseStatement_(); return new ForStatement(this.getTreeLocation_(start), initializer, condition, increment, body); }, parseForInStatement_: function(start, initializer) { this.eat_(IN); var collection = this.parseExpression_(ALLOW_IN); this.eat_(CLOSE_PAREN); var body = this.parseStatement_(); return new ForInStatement(this.getTreeLocation_(start), initializer, collection, body); }, parseContinueStatement_: function() { var start = this.getTreeStartLocation_(); this.eat_(CONTINUE); var name = null; if (!this.peekImplicitSemiColon_()) { name = this.eatIdOpt_(); } this.eatPossibleImplicitSemiColon_(); return new ContinueStatement(this.getTreeLocation_(start), name); }, parseBreakStatement_: function() { var start = this.getTreeStartLocation_(); this.eat_(BREAK); var name = null; if (!this.peekImplicitSemiColon_()) { name = this.eatIdOpt_(); } this.eatPossibleImplicitSemiColon_(); return new BreakStatement(this.getTreeLocation_(start), name); }, parseReturnStatement_: function() { var start = this.getTreeStartLocation_(); var returnToken = this.eat_(RETURN); if (this.functionState_.isTopMost()) { this.reportError_(returnToken.location, 'Illegal return statement'); } var expression = null; if (!this.peekImplicitSemiColon_()) { expression = this.parseExpression_(ALLOW_IN); } this.eatPossibleImplicitSemiColon_(); return new ReturnStatement(this.getTreeLocation_(start), expression); }, parseYieldExpression_: function(allowIn) { var start = this.getTreeStartLocation_(); this.eat_(YIELD); var expression = null; var isYieldFor = false; var token = peekTokenNoLineTerminator(); if (token !== null) { switch (token.type) { case CLOSE_CURLY: case CLOSE_PAREN: case CLOSE_SQUARE: case COLON: case COMMA: case END_OF_FILE: case SEMI_COLON: break; default: isYieldFor = this.eatIf_(STAR); expression = this.parseAssignmentExpression_(allowIn); } } return new YieldExpression(this.getTreeLocation_(start), expression, isYieldFor); }, parseWithStatement_: function() { var start = this.getTreeStartLocation_(); var withToken = this.eat_(WITH); if (this.strictMode_) { this.reportError_(withToken.location, 'Strict mode code may not include a with statement'); } this.eat_(OPEN_PAREN); var expression = this.parseExpression_(ALLOW_IN); this.eat_(CLOSE_PAREN); var body = this.parseStatement_(); return new WithStatement(this.getTreeLocation_(start), expression, body); }, parseSwitchStatement_: function() { var start = this.getTreeStartLocation_(); this.eat_(SWITCH); this.eat_(OPEN_PAREN); var expression = this.parseExpression_(ALLOW_IN); this.eat_(CLOSE_PAREN); this.eat_(OPEN_CURLY); var caseClauses = this.parseCaseClauses_(); this.eat_(CLOSE_CURLY); return new SwitchStatement(this.getTreeLocation_(start), expression, caseClauses); }, parseCaseClauses_: function() { var foundDefaultClause = false; var result = []; while (true) { var start = this.getTreeStartLocation_(); switch (peekType()) { case CASE: { nextToken(); var expression = this.parseExpression_(ALLOW_IN); this.eat_(COLON); var statements = this.parseCaseStatementsOpt_(); result.push(new CaseClause(this.getTreeLocation_(start), expression, statements)); break; } case DEFAULT: { var defaultToken = nextToken(); if (foundDefaultClause) { this.reportError_(defaultToken.location,