traceur
Version:
ES6 to ES5 compiler
1,311 lines • 116 kB
JavaScript
"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,