You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2015/08/01 01:22:21 UTC
[1/3] incubator-ranger git commit: RANGER-585
Repository: incubator-ranger
Updated Branches:
refs/heads/tag-policy 7917b7013 -> 974034bee
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/974034be/security-admin/src/main/webapp/scripts/Init.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/Init.js b/security-admin/src/main/webapp/scripts/Init.js
index a8acd0d..9b22ba5 100644
--- a/security-admin/src/main/webapp/scripts/Init.js
+++ b/security-admin/src/main/webapp/scripts/Init.js
@@ -93,7 +93,10 @@
},
'bootbox' : {
deps: ['jquery']
- }
+ },
+ 'esprima': {
+ 'exports' : 'esprima'
+ },
},
paths: {
@@ -145,6 +148,7 @@
'i18nprecompile' : '../libs/bower/require-handlebars-plugin/js/i18nprecompile',
'json2' : '../libs/bower/require-handlebars-plugin/js/json2',
'hbs' : '../libs/bower/require-handlebars-plugin/js/hbs',
+ 'esprima' : '../libs/bower/esprima/esprima',
'tmpl' : '../templates'
},
@@ -158,4 +162,4 @@
templateExtension: "html",
compileOptions: {}
}
-});
+});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/974034be/security-admin/src/main/webapp/scripts/modules/globalize/message/en.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/modules/globalize/message/en.js b/security-admin/src/main/webapp/scripts/modules/globalize/message/en.js
index 36a513e..c8d187e 100644
--- a/security-admin/src/main/webapp/scripts/modules/globalize/message/en.js
+++ b/security-admin/src/main/webapp/scripts/modules/globalize/message/en.js
@@ -326,7 +326,9 @@ define(function(require) {
policyDisabledMsg : 'This policy is currently in disabled state.',
noRecordsFound : 'No Records Found',
keyDeleteMsg : 'Key deleted successfully',
- rolloverSuccessfully : 'Key rollover successfully'
+ rolloverSuccessfully : 'Key rollover successfully',
+ addUserOrGroup : 'Please select group/user for the selected permission, else group/user will not be added.',
+ addUserOrGroupForPC : 'Please select group/user for the added policy condition, else group/user will not be added.',
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/974034be/security-admin/src/main/webapp/scripts/utils/XAUtils.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/utils/XAUtils.js b/security-admin/src/main/webapp/scripts/utils/XAUtils.js
index 00075dc..d3530e7 100644
--- a/security-admin/src/main/webapp/scripts/utils/XAUtils.js
+++ b/security-admin/src/main/webapp/scripts/utils/XAUtils.js
@@ -941,7 +941,7 @@ define(function(require) {
$.extend(PolicyConditions.prototype, {
render : function() {
- this.$input = this.$tpl.find('input');
+ this.$input = this.$tpl.find('input, textarea');
var pluginOpts = {
tags : true,
width : '220px',
@@ -949,7 +949,12 @@ define(function(require) {
minimumInputLength : 1,
tokenSeparators : [ ",", ";" ],
}
- this.$input.select2(pluginOpts);
+ _.each(this.$input, function(elem){
+ if($(elem).is('input')){
+ $(elem).select2(pluginOpts);
+ }
+ })
+
},
value2str : function(value) {
@@ -964,8 +969,14 @@ define(function(require) {
value2input : function(value) {
_.each(value, function(val, name) {
- this.$input.filter('[name=' + name + ']').select2('val',
- value[name]);
+ var elem = this.$input.filter('[name=' + name + ']');
+ if((elem).is('input')){
+ elem.select2('val',
+ value[name]);
+ }else{
+ elem.val(value[name])
+ }
+
}, this);
},
@@ -973,8 +984,11 @@ define(function(require) {
var obj = {};
_.each(this.$input, function(input) {
var name = input.name;
- var val = this.$input.filter('[name="' + name + '"]')
- .select2('val');
+ if($(input).is('input')){
+ var val = this.$input.filter('[name="' + name + '"]').select2('val');
+ }else{
+ var val = $(input).val();
+ }
obj[name] = val;
}, this);
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/974034be/security-admin/src/main/webapp/scripts/views/policies/PermissionList.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/views/policies/PermissionList.js b/security-admin/src/main/webapp/scripts/views/policies/PermissionList.js
index 6e3eb63..590d80f 100644
--- a/security-admin/src/main/webapp/scripts/views/policies/PermissionList.js
+++ b/security-admin/src/main/webapp/scripts/views/policies/PermissionList.js
@@ -34,6 +34,7 @@ define(function(require) {
var VXGroupList = require('collections/VXGroupList');
var VXUserList = require('collections/VXUserList');
require('bootstrap-editable');
+ require('esprima');
var FormInputItem = Backbone.Marionette.ItemView.extend({
_msvName : 'FormInputItem',
@@ -384,15 +385,20 @@ define(function(require) {
var that = this;
if(this.policyConditions.length > 0){
- var tmpl = _.map(this.policyConditions,function(obj){
+ var tmpl = _.map(this.policyConditions,function(obj){
+ if(!_.isUndefined(obj.evaluatorOptions) && !_.isUndefined(obj.evaluatorOptions['ui.isMultiline']) && Boolean(obj.evaluatorOptions['ui.isMultiline'])){
+ return '<div class="editable-address margin-bottom-5"><label style="display:block !important;"><span>'+obj.label+' : </span><i title="JavaScript Condition Examples :\ncountry_code == \'USA\', time_range >= 900 && time_range <= 1800 etc." class="icon-info-sign" style="float: right;margin-top: 6px;"></i>\
+ </label><textarea name="'+obj.name+'" placeholder="Please enter condtion.."></textarea></div>'
+ }
return '<div class="editable-address margin-bottom-5"><label style="display:block !important;"><span>'+obj.label+' : </span></label><input type="text" name="'+obj.name+'" ></div>'
+
});
//Create new bootstrap x-editable `policyConditions` dataType for policy conditions
XAUtil.customXEditableForPolicyCond(tmpl.join(''));
//create x-editable for policy conditions
this.$('#policyConditions').editable({
emptytext : 'Add Conditions',
- value : this.conditions,
+ value : this.conditions,
display: function(value) {
var continue_ = false, i = 0;
if(!value) {
@@ -401,14 +407,19 @@ define(function(require) {
}
_.each(value, function(val, name){ if(!_.isEmpty(val)) continue_ = true; });
if(continue_){
+ //Generate html to show on UI
var html = _.map(value, function(val,name) {
var label = (i%2 == 0) ? 'label label-inverse' : 'label';
+ if(_.isEmpty(val)){
+ return '';
+ }
i++;
- return _.isEmpty(val) ? '' : '<span class="'+label+'">'+name+' : '+ val + '</span>';
+ return '<span class="'+label+'" >'+name+' : '+ val + '</span>';
});
var cond = _.map(value, function(val, name) {
return {'type' : name, 'values' : !_.isArray(val) ? val.split(',') : val};
});
+
that.model.set('conditions', cond);
$(this).html(html);
that.ui.addConditionsSpan.find('i').attr('class', 'icon-pencil');
@@ -419,12 +430,39 @@ define(function(require) {
that.ui.addConditionsSpan.find('i').attr('class', 'icon-plus');
that.ui.addConditionsSpan.attr('title','add');
}
- }
+ },
+ validate:function(value){
+ var error = {'flag' : false};
+ _.each(value, function(val, name){
+ var tmp = _.findWhere(that.multiLinecond, { 'name' : name});
+ if(!_.isUndefined(tmp)){
+ try {
+ var t = esprima.parse(val);
+ }catch(e){
+ if(!error.flag){
+ console.log(e.message)
+ error.flag = true;
+ error.message = e.message;
+ error.fieldName = name;
+ }
+ }
+ }
+ })
+ $('.editableform').find('.editable-error-block').remove();
+ if(error.flag){
+ $('.editableform').find('.editable-error-block').remove();
+ $('.editableform').find('[name="'+error.fieldName+'"]').parent().append('<div class="editable-error-block help-block" style="display: none;"></div>')
+ return error.message;
+ }
+ },
});
that.ui.addConditionsSpan.click(function(e) {
e.stopPropagation();
that.$('#policyConditions').editable('toggle');
});
+ //to show only mutiline line policy codition
+ this.multiLinecond = _.filter(that.policyConditions, function(m){ return (!_.isUndefined(m.evaluatorOptions['ui.isMultiline']) && m.evaluatorOptions['ui.isMultiline']) });
+ this.multiLinecond = _.isArray(this.multiLinecond) ? this.multiLinecond : [this.multiLinecond];
}
},
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/974034be/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyCreate.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyCreate.js b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyCreate.js
index 332a1d9..10875f1 100644
--- a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyCreate.js
+++ b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyCreate.js
@@ -141,7 +141,12 @@ define(function(require){
var validateObj = this.form.formValidation();
valid = (validateObj.groupSet && validateObj.permSet) || (validateObj.userSet && validateObj.userPerm);
if(!valid){
- if(validateObj.groupSet && (!validateObj.permSet)){
+ if((!validateObj.groupSet && !validateObj.userSet) && (validateObj.condSet)) {
+ this.popupCallBack(localization.tt('msg.addUserOrGroupForPC'),validateObj);
+ }else if((!validateObj.groupSet && !validateObj.userSet) && (validateObj.permSet)) {
+ this.popupCallBack(localization.tt('msg.addUserOrGroup'),validateObj);
+
+ }else if(validateObj.groupSet && (!validateObj.permSet)){
this.popupCallBack(localization.tt('msg.addGroupPermission'),validateObj);
}else if((!validateObj.groupSet) && (validateObj.permSet)) {
this.popupCallBack(localization.tt('msg.addGroup'),validateObj);
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/974034be/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyForm.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyForm.js b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyForm.js
index bbb38f5..0f36791 100644
--- a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyForm.js
+++ b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyForm.js
@@ -518,8 +518,8 @@ define(function(require){
return JSON.stringify(context);
},
formValidation : function(){
- var groupSet = false,permSet = false,groupPermSet = false;
- var userSet=false, userPerm = false, userPermSet =false,breakFlag =false;
+ var groupSet = false,permSet = false,groupPermSet = false,
+ userSet=false, userPerm = false, userPermSet =false,breakFlag =false, condSet = false;
console.log('validation called..');
this.formInputList.each(function(m){
if(_.isEmpty(m.attributes)) return;
@@ -539,12 +539,16 @@ define(function(require){
}
}
}
+ if(m.has('conditions')){
+ condSet = m.has('conditions') ? true : false;
+ }
});
var auditStatus = this.fields.isAuditEnabled.editor.getValue();
var obj = { groupPermSet : groupPermSet , groupSet : groupSet,
userSet : userSet, isUsers:userPermSet,
- auditLoggin : auditStatus
+ auditLoggin : auditStatus,
+ condSet : condSet,
};
if(groupSet || userSet){
obj['permSet'] = groupSet ? permSet : false;
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/974034be/security-admin/src/main/webapp/templates/common/TopNav_tmpl.html
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/templates/common/TopNav_tmpl.html b/security-admin/src/main/webapp/templates/common/TopNav_tmpl.html
index 6b62ba3..a5bc392 100644
--- a/security-admin/src/main/webapp/templates/common/TopNav_tmpl.html
+++ b/security-admin/src/main/webapp/templates/common/TopNav_tmpl.html
@@ -23,7 +23,7 @@
<li><a href="#!/policymanager/resource"><i class="icon-file"></i>Resource Based Policies</a></li>
{{/hasAccessToTab}}
{{#hasAccessToTab 'Tag Based Policies'}}
- <li><a href="#!/policymanager/tag"><i class="icon-tag"></i>Tag Based Policies</a></li>
+ <li><a href="#!/policymanager/tag"><i class="icon-tags"></i>Tag Based Policies</a></li>
{{/hasAccessToTab}}
{{#hasAccessToTab 'Reports'}}
<li><a href="#!/reports/userAccess"><i class="icon-beaker"></i>Reports</a></li>
[3/3] incubator-ranger git commit: RANGER-585
Posted by ma...@apache.org.
RANGER-585
Signed-off-by: Madhan Neethiraj <ma...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/974034be
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/974034be
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/974034be
Branch: refs/heads/tag-policy
Commit: 974034bee9512a927540ee2f29a29e3b7c4d7fc1
Parents: 7917b70
Author: Gautam Borad <gb...@gmail.com>
Authored: Tue Jul 28 17:50:18 2015 +0530
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Fri Jul 31 16:04:11 2015 -0700
----------------------------------------------------------------------
.../main/webapp/libs/bower/esprima/esprima.js | 5599 ++++++++++++++++++
security-admin/src/main/webapp/scripts/Init.js | 8 +-
.../scripts/modules/globalize/message/en.js | 4 +-
.../src/main/webapp/scripts/utils/XAUtils.js | 26 +-
.../scripts/views/policies/PermissionList.js | 46 +-
.../views/policies/RangerPolicyCreate.js | 7 +-
.../scripts/views/policies/RangerPolicyForm.js | 10 +-
.../webapp/templates/common/TopNav_tmpl.html | 2 +-
8 files changed, 5684 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
[2/3] incubator-ranger git commit: RANGER-585
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/974034be/security-admin/src/main/webapp/libs/bower/esprima/esprima.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/libs/bower/esprima/esprima.js b/security-admin/src/main/webapp/libs/bower/esprima/esprima.js
new file mode 100644
index 0000000..ab1d312
--- /dev/null
+++ b/security-admin/src/main/webapp/libs/bower/esprima/esprima.js
@@ -0,0 +1,5599 @@
+/*
+ Copyright (c) jQuery Foundation, Inc. and Contributors, All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+(function (root, factory) {
+ 'use strict';
+
+ // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,
+ // Rhino, and plain browser loading.
+
+ /* istanbul ignore next */
+ /*if (typeof define === 'function' && define.amd) {
+ define(['exports'], factory);
+ } else*/
+ if (typeof exports !== 'undefined') {
+ factory(exports);
+ } else {
+ factory((root.esprima = {}));
+ }
+}(this, function (exports) {
+ 'use strict';
+
+ var Token,
+ TokenName,
+ FnExprTokens,
+ Syntax,
+ PlaceHolders,
+ Messages,
+ Regex,
+ source,
+ strict,
+ sourceType,
+ index,
+ lineNumber,
+ lineStart,
+ hasLineTerminator,
+ lastIndex,
+ lastLineNumber,
+ lastLineStart,
+ startIndex,
+ startLineNumber,
+ startLineStart,
+ scanning,
+ length,
+ lookahead,
+ state,
+ extra,
+ isBindingElement,
+ isAssignmentTarget,
+ firstCoverInitializedNameError;
+
+ Token = {
+ BooleanLiteral: 1,
+ EOF: 2,
+ Identifier: 3,
+ Keyword: 4,
+ NullLiteral: 5,
+ NumericLiteral: 6,
+ Punctuator: 7,
+ StringLiteral: 8,
+ RegularExpression: 9,
+ Template: 10
+ };
+
+ TokenName = {};
+ TokenName[Token.BooleanLiteral] = 'Boolean';
+ TokenName[Token.EOF] = '<end>';
+ TokenName[Token.Identifier] = 'Identifier';
+ TokenName[Token.Keyword] = 'Keyword';
+ TokenName[Token.NullLiteral] = 'Null';
+ TokenName[Token.NumericLiteral] = 'Numeric';
+ TokenName[Token.Punctuator] = 'Punctuator';
+ TokenName[Token.StringLiteral] = 'String';
+ TokenName[Token.RegularExpression] = 'RegularExpression';
+ TokenName[Token.Template] = 'Template';
+
+ // A function following one of those tokens is an expression.
+ FnExprTokens = ['(', '{', '[', 'in', 'typeof', 'instanceof', 'new',
+ 'return', 'case', 'delete', 'throw', 'void',
+ // assignment operators
+ '=', '+=', '-=', '*=', '/=', '%=', '<<=', '>>=', '>>>=',
+ '&=', '|=', '^=', ',',
+ // binary/unary operators
+ '+', '-', '*', '/', '%', '++', '--', '<<', '>>', '>>>', '&',
+ '|', '^', '!', '~', '&&', '||', '?', ':', '===', '==', '>=',
+ '<=', '<', '>', '!=', '!=='];
+
+ Syntax = {
+ AssignmentExpression: 'AssignmentExpression',
+ AssignmentPattern: 'AssignmentPattern',
+ ArrayExpression: 'ArrayExpression',
+ ArrayPattern: 'ArrayPattern',
+ ArrowFunctionExpression: 'ArrowFunctionExpression',
+ BlockStatement: 'BlockStatement',
+ BinaryExpression: 'BinaryExpression',
+ BreakStatement: 'BreakStatement',
+ CallExpression: 'CallExpression',
+ CatchClause: 'CatchClause',
+ ClassBody: 'ClassBody',
+ ClassDeclaration: 'ClassDeclaration',
+ ClassExpression: 'ClassExpression',
+ ConditionalExpression: 'ConditionalExpression',
+ ContinueStatement: 'ContinueStatement',
+ DoWhileStatement: 'DoWhileStatement',
+ DebuggerStatement: 'DebuggerStatement',
+ EmptyStatement: 'EmptyStatement',
+ ExportAllDeclaration: 'ExportAllDeclaration',
+ ExportDefaultDeclaration: 'ExportDefaultDeclaration',
+ ExportNamedDeclaration: 'ExportNamedDeclaration',
+ ExportSpecifier: 'ExportSpecifier',
+ ExpressionStatement: 'ExpressionStatement',
+ ForStatement: 'ForStatement',
+ ForOfStatement: 'ForOfStatement',
+ ForInStatement: 'ForInStatement',
+ FunctionDeclaration: 'FunctionDeclaration',
+ FunctionExpression: 'FunctionExpression',
+ Identifier: 'Identifier',
+ IfStatement: 'IfStatement',
+ ImportDeclaration: 'ImportDeclaration',
+ ImportDefaultSpecifier: 'ImportDefaultSpecifier',
+ ImportNamespaceSpecifier: 'ImportNamespaceSpecifier',
+ ImportSpecifier: 'ImportSpecifier',
+ Literal: 'Literal',
+ LabeledStatement: 'LabeledStatement',
+ LogicalExpression: 'LogicalExpression',
+ MemberExpression: 'MemberExpression',
+ MetaProperty: 'MetaProperty',
+ MethodDefinition: 'MethodDefinition',
+ NewExpression: 'NewExpression',
+ ObjectExpression: 'ObjectExpression',
+ ObjectPattern: 'ObjectPattern',
+ Program: 'Program',
+ Property: 'Property',
+ RestElement: 'RestElement',
+ ReturnStatement: 'ReturnStatement',
+ SequenceExpression: 'SequenceExpression',
+ SpreadElement: 'SpreadElement',
+ Super: 'Super',
+ SwitchCase: 'SwitchCase',
+ SwitchStatement: 'SwitchStatement',
+ TaggedTemplateExpression: 'TaggedTemplateExpression',
+ TemplateElement: 'TemplateElement',
+ TemplateLiteral: 'TemplateLiteral',
+ ThisExpression: 'ThisExpression',
+ ThrowStatement: 'ThrowStatement',
+ TryStatement: 'TryStatement',
+ UnaryExpression: 'UnaryExpression',
+ UpdateExpression: 'UpdateExpression',
+ VariableDeclaration: 'VariableDeclaration',
+ VariableDeclarator: 'VariableDeclarator',
+ WhileStatement: 'WhileStatement',
+ WithStatement: 'WithStatement',
+ YieldExpression: 'YieldExpression'
+ };
+
+ PlaceHolders = {
+ ArrowParameterPlaceHolder: 'ArrowParameterPlaceHolder'
+ };
+
+ // Error messages should be identical to V8.
+ Messages = {
+ UnexpectedToken: 'Unexpected token %0',
+ UnexpectedNumber: 'Unexpected number',
+ UnexpectedString: 'Unexpected string',
+ UnexpectedIdentifier: 'Unexpected identifier',
+ UnexpectedReserved: 'Unexpected reserved word',
+ UnexpectedTemplate: 'Unexpected quasi %0',
+ UnexpectedEOS: 'Unexpected end of input',
+ NewlineAfterThrow: 'Illegal newline after throw',
+ InvalidRegExp: 'Invalid regular expression',
+ UnterminatedRegExp: 'Invalid regular expression: missing /',
+ InvalidLHSInAssignment: 'Invalid left-hand side in assignment',
+ InvalidLHSInForIn: 'Invalid left-hand side in for-in',
+ InvalidLHSInForLoop: 'Invalid left-hand side in for-loop',
+ MultipleDefaultsInSwitch: 'More than one default clause in switch statement',
+ NoCatchOrFinally: 'Missing catch or finally after try',
+ UnknownLabel: 'Undefined label \'%0\'',
+ Redeclaration: '%0 \'%1\' has already been declared',
+ IllegalContinue: 'Illegal continue statement',
+ IllegalBreak: 'Illegal break statement',
+ IllegalReturn: 'Illegal return statement',
+ StrictModeWith: 'Strict mode code may not include a with statement',
+ StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode',
+ StrictVarName: 'Variable name may not be eval or arguments in strict mode',
+ StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode',
+ StrictParamDupe: 'Strict mode function may not have duplicate parameter names',
+ StrictFunctionName: 'Function name may not be eval or arguments in strict mode',
+ StrictOctalLiteral: 'Octal literals are not allowed in strict mode.',
+ StrictDelete: 'Delete of an unqualified identifier in strict mode.',
+ StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode',
+ StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode',
+ StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode',
+ StrictReservedWord: 'Use of future reserved word in strict mode',
+ TemplateOctalLiteral: 'Octal literals are not allowed in template strings.',
+ ParameterAfterRestParameter: 'Rest parameter must be last formal parameter',
+ DefaultRestParameter: 'Unexpected token =',
+ ObjectPatternAsRestParameter: 'Unexpected token {',
+ DuplicateProtoProperty: 'Duplicate __proto__ fields are not allowed in object literals',
+ ConstructorSpecialMethod: 'Class constructor may not be an accessor',
+ DuplicateConstructor: 'A class may only have one constructor',
+ StaticPrototype: 'Classes may not have static property named prototype',
+ MissingFromClause: 'Unexpected token',
+ NoAsAfterImportNamespace: 'Unexpected token',
+ InvalidModuleSpecifier: 'Unexpected token',
+ IllegalImportDeclaration: 'Unexpected token',
+ IllegalExportDeclaration: 'Unexpected token',
+ DuplicateBinding: 'Duplicate binding %0'
+ };
+
+ // See also tools/generate-unicode-regex.js.
+ Regex = {
+ // ECMAScript 6/Unicode v7.0.0 NonAsciiIdentifierStart:
+ NonAsciiIdentifierStart: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-
\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1
310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80
-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\u
FB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-
\uDDB2\uDDC1-\uDDC4\uDDDA\uDE00-\uDE11\uDE13-\uDE2B\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDE00-\uDE2F\uDE44\uDE80-\uDEAA]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|\uD809[\uDC00-\uDC6E]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uD
FCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D]/,
+
+ // ECMAScript 6/Unicode v7.0.0 NonAsciiIdentifierPart:
+ NonAsciiIdentifierPart: /[\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B2\u08E4-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\
u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0
DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\
u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3
099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA69D\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21
-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDD0-\uDDDA\uDE00-\uDE11\uDE13-\uDE37\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF01-\uD
F03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|\uD809[\uDC00-\uDC6E]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uD
D3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/
+ };
+
+ // Ensure the condition is true, otherwise throw an error.
+ // This is only to have a better contract semantic, i.e. another safety net
+ // to catch a logic error. The condition shall be fulfilled in normal case.
+ // Do NOT use this to enforce a certain condition on any user input.
+
+ function assert(condition, message) {
+ /* istanbul ignore if */
+ if (!condition) {
+ throw new Error('ASSERT: ' + message);
+ }
+ }
+
+ function isDecimalDigit(ch) {
+ return (ch >= 0x30 && ch <= 0x39); // 0..9
+ }
+
+ function isHexDigit(ch) {
+ return '0123456789abcdefABCDEF'.indexOf(ch) >= 0;
+ }
+
+ function isOctalDigit(ch) {
+ return '01234567'.indexOf(ch) >= 0;
+ }
+
+ function octalToDecimal(ch) {
+ // \0 is not octal escape sequence
+ var octal = (ch !== '0'), code = '01234567'.indexOf(ch);
+
+ if (index < length && isOctalDigit(source[index])) {
+ octal = true;
+ code = code * 8 + '01234567'.indexOf(source[index++]);
+
+ // 3 digits are only allowed when string starts
+ // with 0, 1, 2, 3
+ if ('0123'.indexOf(ch) >= 0 &&
+ index < length &&
+ isOctalDigit(source[index])) {
+ code = code * 8 + '01234567'.indexOf(source[index++]);
+ }
+ }
+
+ return {
+ code: code,
+ octal: octal
+ };
+ }
+
+ // 11.2 White Space
+
+ function isWhiteSpace(ch) {
+ return (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) ||
+ (ch >= 0x1680 && [0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(ch) >= 0);
+ }
+
+ // 11.3 Line Terminators
+
+ function isLineTerminator(ch) {
+ return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029);
+ }
+
+ // 11.6 Identifier Names and Identifiers
+
+ function isIdentifierStart(ch) {
+ return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore)
+ (ch >= 0x41 && ch <= 0x5A) || // A..Z
+ (ch >= 0x61 && ch <= 0x7A) || // a..z
+ (ch === 0x5C) || // \ (backslash)
+ ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch)));
+ }
+
+ function isIdentifierPart(ch) {
+ return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore)
+ (ch >= 0x41 && ch <= 0x5A) || // A..Z
+ (ch >= 0x61 && ch <= 0x7A) || // a..z
+ (ch >= 0x30 && ch <= 0x39) || // 0..9
+ (ch === 0x5C) || // \ (backslash)
+ ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch)));
+ }
+
+ // 11.6.2.2 Future Reserved Words
+
+ function isFutureReservedWord(id) {
+ switch (id) {
+ case 'enum':
+ case 'export':
+ case 'import':
+ case 'super':
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ function isStrictModeReservedWord(id) {
+ switch (id) {
+ case 'implements':
+ case 'interface':
+ case 'package':
+ case 'private':
+ case 'protected':
+ case 'public':
+ case 'static':
+ case 'yield':
+ case 'let':
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ function isRestrictedWord(id) {
+ return id === 'eval' || id === 'arguments';
+ }
+
+ // 11.6.2.1 Keywords
+
+ function isKeyword(id) {
+
+ // 'const' is specialized as Keyword in V8.
+ // 'yield' and 'let' are for compatibility with SpiderMonkey and ES.next.
+ // Some others are from future reserved words.
+
+ switch (id.length) {
+ case 2:
+ return (id === 'if') || (id === 'in') || (id === 'do');
+ case 3:
+ return (id === 'var') || (id === 'for') || (id === 'new') ||
+ (id === 'try') || (id === 'let');
+ case 4:
+ return (id === 'this') || (id === 'else') || (id === 'case') ||
+ (id === 'void') || (id === 'with') || (id === 'enum');
+ case 5:
+ return (id === 'while') || (id === 'break') || (id === 'catch') ||
+ (id === 'throw') || (id === 'const') || (id === 'yield') ||
+ (id === 'class') || (id === 'super');
+ case 6:
+ return (id === 'return') || (id === 'typeof') || (id === 'delete') ||
+ (id === 'switch') || (id === 'export') || (id === 'import');
+ case 7:
+ return (id === 'default') || (id === 'finally') || (id === 'extends');
+ case 8:
+ return (id === 'function') || (id === 'continue') || (id === 'debugger');
+ case 10:
+ return (id === 'instanceof');
+ default:
+ return false;
+ }
+ }
+
+ // 11.4 Comments
+
+ function addComment(type, value, start, end, loc) {
+ var comment;
+
+ assert(typeof start === 'number', 'Comment must have valid position');
+
+ state.lastCommentStart = start;
+
+ comment = {
+ type: type,
+ value: value
+ };
+ if (extra.range) {
+ comment.range = [start, end];
+ }
+ if (extra.loc) {
+ comment.loc = loc;
+ }
+ extra.comments.push(comment);
+ if (extra.attachComment) {
+ extra.leadingComments.push(comment);
+ extra.trailingComments.push(comment);
+ }
+ }
+
+ function skipSingleLineComment(offset) {
+ var start, loc, ch, comment;
+
+ start = index - offset;
+ loc = {
+ start: {
+ line: lineNumber,
+ column: index - lineStart - offset
+ }
+ };
+
+ while (index < length) {
+ ch = source.charCodeAt(index);
+ ++index;
+ if (isLineTerminator(ch)) {
+ hasLineTerminator = true;
+ if (extra.comments) {
+ comment = source.slice(start + offset, index - 1);
+ loc.end = {
+ line: lineNumber,
+ column: index - lineStart - 1
+ };
+ addComment('Line', comment, start, index - 1, loc);
+ }
+ if (ch === 13 && source.charCodeAt(index) === 10) {
+ ++index;
+ }
+ ++lineNumber;
+ lineStart = index;
+ return;
+ }
+ }
+
+ if (extra.comments) {
+ comment = source.slice(start + offset, index);
+ loc.end = {
+ line: lineNumber,
+ column: index - lineStart
+ };
+ addComment('Line', comment, start, index, loc);
+ }
+ }
+
+ function skipMultiLineComment() {
+ var start, loc, ch, comment;
+
+ if (extra.comments) {
+ start = index - 2;
+ loc = {
+ start: {
+ line: lineNumber,
+ column: index - lineStart - 2
+ }
+ };
+ }
+
+ while (index < length) {
+ ch = source.charCodeAt(index);
+ if (isLineTerminator(ch)) {
+ if (ch === 0x0D && source.charCodeAt(index + 1) === 0x0A) {
+ ++index;
+ }
+ hasLineTerminator = true;
+ ++lineNumber;
+ ++index;
+ lineStart = index;
+ } else if (ch === 0x2A) {
+ // Block comment ends with '*/'.
+ if (source.charCodeAt(index + 1) === 0x2F) {
+ ++index;
+ ++index;
+ if (extra.comments) {
+ comment = source.slice(start + 2, index - 2);
+ loc.end = {
+ line: lineNumber,
+ column: index - lineStart
+ };
+ addComment('Block', comment, start, index, loc);
+ }
+ return;
+ }
+ ++index;
+ } else {
+ ++index;
+ }
+ }
+
+ // Ran off the end of the file - the whole thing is a comment
+ if (extra.comments) {
+ loc.end = {
+ line: lineNumber,
+ column: index - lineStart
+ };
+ comment = source.slice(start + 2, index);
+ addComment('Block', comment, start, index, loc);
+ }
+ tolerateUnexpectedToken();
+ }
+
+ function skipComment() {
+ var ch, start;
+ hasLineTerminator = false;
+
+ start = (index === 0);
+ while (index < length) {
+ ch = source.charCodeAt(index);
+
+ if (isWhiteSpace(ch)) {
+ ++index;
+ } else if (isLineTerminator(ch)) {
+ hasLineTerminator = true;
+ ++index;
+ if (ch === 0x0D && source.charCodeAt(index) === 0x0A) {
+ ++index;
+ }
+ ++lineNumber;
+ lineStart = index;
+ start = true;
+ } else if (ch === 0x2F) { // U+002F is '/'
+ ch = source.charCodeAt(index + 1);
+ if (ch === 0x2F) {
+ ++index;
+ ++index;
+ skipSingleLineComment(2);
+ start = true;
+ } else if (ch === 0x2A) { // U+002A is '*'
+ ++index;
+ ++index;
+ skipMultiLineComment();
+ } else {
+ break;
+ }
+ } else if (start && ch === 0x2D) { // U+002D is '-'
+ // U+003E is '>'
+ if ((source.charCodeAt(index + 1) === 0x2D) && (source.charCodeAt(index + 2) === 0x3E)) {
+ // '-->' is a single-line comment
+ index += 3;
+ skipSingleLineComment(3);
+ } else {
+ break;
+ }
+ } else if (ch === 0x3C) { // U+003C is '<'
+ if (source.slice(index + 1, index + 4) === '!--') {
+ ++index; // `<`
+ ++index; // `!`
+ ++index; // `-`
+ ++index; // `-`
+ skipSingleLineComment(4);
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ }
+
+ function scanHexEscape(prefix) {
+ var i, len, ch, code = 0;
+
+ len = (prefix === 'u') ? 4 : 2;
+ for (i = 0; i < len; ++i) {
+ if (index < length && isHexDigit(source[index])) {
+ ch = source[index++];
+ code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
+ } else {
+ return '';
+ }
+ }
+ return String.fromCharCode(code);
+ }
+
+ function scanUnicodeCodePointEscape() {
+ var ch, code, cu1, cu2;
+
+ ch = source[index];
+ code = 0;
+
+ // At least, one hex digit is required.
+ if (ch === '}') {
+ throwUnexpectedToken();
+ }
+
+ while (index < length) {
+ ch = source[index++];
+ if (!isHexDigit(ch)) {
+ break;
+ }
+ code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
+ }
+
+ if (code > 0x10FFFF || ch !== '}') {
+ throwUnexpectedToken();
+ }
+
+ // UTF-16 Encoding
+ if (code <= 0xFFFF) {
+ return String.fromCharCode(code);
+ }
+ cu1 = ((code - 0x10000) >> 10) + 0xD800;
+ cu2 = ((code - 0x10000) & 1023) + 0xDC00;
+ return String.fromCharCode(cu1, cu2);
+ }
+
+ function getEscapedIdentifier() {
+ var ch, id;
+
+ ch = source.charCodeAt(index++);
+ id = String.fromCharCode(ch);
+
+ // '\u' (U+005C, U+0075) denotes an escaped character.
+ if (ch === 0x5C) {
+ if (source.charCodeAt(index) !== 0x75) {
+ throwUnexpectedToken();
+ }
+ ++index;
+ if (source[index] === '{') {
+ ++index;
+ ch = scanUnicodeCodePointEscape();
+ } else {
+ ch = scanHexEscape('u');
+ if (!ch || ch === '\\' || !isIdentifierStart(ch.charCodeAt(0))) {
+ throwUnexpectedToken();
+ }
+ }
+ id = ch;
+ }
+
+ while (index < length) {
+ ch = source.charCodeAt(index);
+ if (!isIdentifierPart(ch)) {
+ break;
+ }
+ ++index;
+ id += String.fromCharCode(ch);
+
+ // '\u' (U+005C, U+0075) denotes an escaped character.
+ if (ch === 0x5C) {
+ id = id.substr(0, id.length - 1);
+ if (source.charCodeAt(index) !== 0x75) {
+ throwUnexpectedToken();
+ }
+ ++index;
+ if (source[index] === '{') {
+ ++index;
+ ch = scanUnicodeCodePointEscape();
+ } else {
+ ch = scanHexEscape('u');
+ if (!ch || ch === '\\' || !isIdentifierPart(ch.charCodeAt(0))) {
+ throwUnexpectedToken();
+ }
+ }
+ id += ch;
+ }
+ }
+
+ return id;
+ }
+
+ function getIdentifier() {
+ var start, ch;
+
+ start = index++;
+ while (index < length) {
+ ch = source.charCodeAt(index);
+ if (ch === 0x5C) {
+ // Blackslash (U+005C) marks Unicode escape sequence.
+ index = start;
+ return getEscapedIdentifier();
+ }
+ if (isIdentifierPart(ch)) {
+ ++index;
+ } else {
+ break;
+ }
+ }
+
+ return source.slice(start, index);
+ }
+
+ function scanIdentifier() {
+ var start, id, type;
+
+ start = index;
+
+ // Backslash (U+005C) starts an escaped character.
+ id = (source.charCodeAt(index) === 0x5C) ? getEscapedIdentifier() : getIdentifier();
+
+ // There is no keyword or literal with only one character.
+ // Thus, it must be an identifier.
+ if (id.length === 1) {
+ type = Token.Identifier;
+ } else if (isKeyword(id)) {
+ type = Token.Keyword;
+ } else if (id === 'null') {
+ type = Token.NullLiteral;
+ } else if (id === 'true' || id === 'false') {
+ type = Token.BooleanLiteral;
+ } else {
+ type = Token.Identifier;
+ }
+
+ return {
+ type: type,
+ value: id,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ start: start,
+ end: index
+ };
+ }
+
+
+ // 11.7 Punctuators
+
+ function scanPunctuator() {
+ var token, str;
+
+ token = {
+ type: Token.Punctuator,
+ value: '',
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ start: index,
+ end: index
+ };
+
+ // Check for most common single-character punctuators.
+ str = source[index];
+ switch (str) {
+
+ case '(':
+ if (extra.tokenize) {
+ extra.openParenToken = extra.tokens.length;
+ }
+ ++index;
+ break;
+
+ case '{':
+ if (extra.tokenize) {
+ extra.openCurlyToken = extra.tokens.length;
+ }
+ state.curlyStack.push('{');
+ ++index;
+ break;
+
+ case '.':
+ ++index;
+ if (source[index] === '.' && source[index + 1] === '.') {
+ // Spread operator: ...
+ index += 2;
+ str = '...';
+ }
+ break;
+
+ case '}':
+ ++index;
+ state.curlyStack.pop();
+ break;
+ case ')':
+ case ';':
+ case ',':
+ case '[':
+ case ']':
+ case ':':
+ case '?':
+ case '~':
+ ++index;
+ break;
+
+ default:
+ // 4-character punctuator.
+ str = source.substr(index, 4);
+ if (str === '>>>=') {
+ index += 4;
+ } else {
+
+ // 3-character punctuators.
+ str = str.substr(0, 3);
+ if (str === '===' || str === '!==' || str === '>>>' ||
+ str === '<<=' || str === '>>=') {
+ index += 3;
+ } else {
+
+ // 2-character punctuators.
+ str = str.substr(0, 2);
+ if (str === '&&' || str === '||' || str === '==' || str === '!=' ||
+ str === '+=' || str === '-=' || str === '*=' || str === '/=' ||
+ str === '++' || str === '--' || str === '<<' || str === '>>' ||
+ str === '&=' || str === '|=' || str === '^=' || str === '%=' ||
+ str === '<=' || str === '>=' || str === '=>') {
+ index += 2;
+ } else {
+
+ // 1-character punctuators.
+ str = source[index];
+ if ('<>=!+-*%&|^/'.indexOf(str) >= 0) {
+ ++index;
+ }
+ }
+ }
+ }
+ }
+
+ if (index === token.start) {
+ throwUnexpectedToken();
+ }
+
+ token.end = index;
+ token.value = str;
+ return token;
+ }
+
+ // 11.8.3 Numeric Literals
+
+ function scanHexLiteral(start) {
+ var number = '';
+
+ while (index < length) {
+ if (!isHexDigit(source[index])) {
+ break;
+ }
+ number += source[index++];
+ }
+
+ if (number.length === 0) {
+ throwUnexpectedToken();
+ }
+
+ if (isIdentifierStart(source.charCodeAt(index))) {
+ throwUnexpectedToken();
+ }
+
+ return {
+ type: Token.NumericLiteral,
+ value: parseInt('0x' + number, 16),
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ start: start,
+ end: index
+ };
+ }
+
+ function scanBinaryLiteral(start) {
+ var ch, number;
+
+ number = '';
+
+ while (index < length) {
+ ch = source[index];
+ if (ch !== '0' && ch !== '1') {
+ break;
+ }
+ number += source[index++];
+ }
+
+ if (number.length === 0) {
+ // only 0b or 0B
+ throwUnexpectedToken();
+ }
+
+ if (index < length) {
+ ch = source.charCodeAt(index);
+ /* istanbul ignore else */
+ if (isIdentifierStart(ch) || isDecimalDigit(ch)) {
+ throwUnexpectedToken();
+ }
+ }
+
+ return {
+ type: Token.NumericLiteral,
+ value: parseInt(number, 2),
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ start: start,
+ end: index
+ };
+ }
+
+ function scanOctalLiteral(prefix, start) {
+ var number, octal;
+
+ if (isOctalDigit(prefix)) {
+ octal = true;
+ number = '0' + source[index++];
+ } else {
+ octal = false;
+ ++index;
+ number = '';
+ }
+
+ while (index < length) {
+ if (!isOctalDigit(source[index])) {
+ break;
+ }
+ number += source[index++];
+ }
+
+ if (!octal && number.length === 0) {
+ // only 0o or 0O
+ throwUnexpectedToken();
+ }
+
+ if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) {
+ throwUnexpectedToken();
+ }
+
+ return {
+ type: Token.NumericLiteral,
+ value: parseInt(number, 8),
+ octal: octal,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ start: start,
+ end: index
+ };
+ }
+
+ function isImplicitOctalLiteral() {
+ var i, ch;
+
+ // Implicit octal, unless there is a non-octal digit.
+ // (Annex B.1.1 on Numeric Literals)
+ for (i = index + 1; i < length; ++i) {
+ ch = source[i];
+ if (ch === '8' || ch === '9') {
+ return false;
+ }
+ if (!isOctalDigit(ch)) {
+ return true;
+ }
+ }
+
+ return true;
+ }
+
+ function scanNumericLiteral() {
+ var number, start, ch;
+
+ ch = source[index];
+ assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'),
+ 'Numeric literal must start with a decimal digit or a decimal point');
+
+ start = index;
+ number = '';
+ if (ch !== '.') {
+ number = source[index++];
+ ch = source[index];
+
+ // Hex number starts with '0x'.
+ // Octal number starts with '0'.
+ // Octal number in ES6 starts with '0o'.
+ // Binary number in ES6 starts with '0b'.
+ if (number === '0') {
+ if (ch === 'x' || ch === 'X') {
+ ++index;
+ return scanHexLiteral(start);
+ }
+ if (ch === 'b' || ch === 'B') {
+ ++index;
+ return scanBinaryLiteral(start);
+ }
+ if (ch === 'o' || ch === 'O') {
+ return scanOctalLiteral(ch, start);
+ }
+
+ if (isOctalDigit(ch)) {
+ if (isImplicitOctalLiteral()) {
+ return scanOctalLiteral(ch, start);
+ }
+ }
+ }
+
+ while (isDecimalDigit(source.charCodeAt(index))) {
+ number += source[index++];
+ }
+ ch = source[index];
+ }
+
+ if (ch === '.') {
+ number += source[index++];
+ while (isDecimalDigit(source.charCodeAt(index))) {
+ number += source[index++];
+ }
+ ch = source[index];
+ }
+
+ if (ch === 'e' || ch === 'E') {
+ number += source[index++];
+
+ ch = source[index];
+ if (ch === '+' || ch === '-') {
+ number += source[index++];
+ }
+ if (isDecimalDigit(source.charCodeAt(index))) {
+ while (isDecimalDigit(source.charCodeAt(index))) {
+ number += source[index++];
+ }
+ } else {
+ throwUnexpectedToken();
+ }
+ }
+
+ if (isIdentifierStart(source.charCodeAt(index))) {
+ throwUnexpectedToken();
+ }
+
+ return {
+ type: Token.NumericLiteral,
+ value: parseFloat(number),
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ start: start,
+ end: index
+ };
+ }
+
+ // 11.8.4 String Literals
+
+ function scanStringLiteral() {
+ var str = '', quote, start, ch, unescaped, octToDec, octal = false;
+
+ quote = source[index];
+ assert((quote === '\'' || quote === '"'),
+ 'String literal must starts with a quote');
+
+ start = index;
+ ++index;
+
+ while (index < length) {
+ ch = source[index++];
+
+ if (ch === quote) {
+ quote = '';
+ break;
+ } else if (ch === '\\') {
+ ch = source[index++];
+ if (!ch || !isLineTerminator(ch.charCodeAt(0))) {
+ switch (ch) {
+ case 'u':
+ case 'x':
+ if (source[index] === '{') {
+ ++index;
+ str += scanUnicodeCodePointEscape();
+ } else {
+ unescaped = scanHexEscape(ch);
+ if (!unescaped) {
+ throw throwUnexpectedToken();
+ }
+ str += unescaped;
+ }
+ break;
+ case 'n':
+ str += '\n';
+ break;
+ case 'r':
+ str += '\r';
+ break;
+ case 't':
+ str += '\t';
+ break;
+ case 'b':
+ str += '\b';
+ break;
+ case 'f':
+ str += '\f';
+ break;
+ case 'v':
+ str += '\x0B';
+ break;
+ case '8':
+ case '9':
+ str += ch;
+ tolerateUnexpectedToken();
+ break;
+
+ default:
+ if (isOctalDigit(ch)) {
+ octToDec = octalToDecimal(ch);
+
+ octal = octToDec.octal || octal;
+ str += String.fromCharCode(octToDec.code);
+ } else {
+ str += ch;
+ }
+ break;
+ }
+ } else {
+ ++lineNumber;
+ if (ch === '\r' && source[index] === '\n') {
+ ++index;
+ }
+ lineStart = index;
+ }
+ } else if (isLineTerminator(ch.charCodeAt(0))) {
+ break;
+ } else {
+ str += ch;
+ }
+ }
+
+ if (quote !== '') {
+ throwUnexpectedToken();
+ }
+
+ return {
+ type: Token.StringLiteral,
+ value: str,
+ octal: octal,
+ lineNumber: startLineNumber,
+ lineStart: startLineStart,
+ start: start,
+ end: index
+ };
+ }
+
+ // 11.8.6 Template Literal Lexical Components
+
+ function scanTemplate() {
+ var cooked = '', ch, start, rawOffset, terminated, head, tail, restore, unescaped;
+
+ terminated = false;
+ tail = false;
+ start = index;
+ head = (source[index] === '`');
+ rawOffset = 2;
+
+ ++index;
+
+ while (index < length) {
+ ch = source[index++];
+ if (ch === '`') {
+ rawOffset = 1;
+ tail = true;
+ terminated = true;
+ break;
+ } else if (ch === '$') {
+ if (source[index] === '{') {
+ state.curlyStack.push('${');
+ ++index;
+ terminated = true;
+ break;
+ }
+ cooked += ch;
+ } else if (ch === '\\') {
+ ch = source[index++];
+ if (!isLineTerminator(ch.charCodeAt(0))) {
+ switch (ch) {
+ case 'n':
+ cooked += '\n';
+ break;
+ case 'r':
+ cooked += '\r';
+ break;
+ case 't':
+ cooked += '\t';
+ break;
+ case 'u':
+ case 'x':
+ if (source[index] === '{') {
+ ++index;
+ cooked += scanUnicodeCodePointEscape();
+ } else {
+ restore = index;
+ unescaped = scanHexEscape(ch);
+ if (unescaped) {
+ cooked += unescaped;
+ } else {
+ index = restore;
+ cooked += ch;
+ }
+ }
+ break;
+ case 'b':
+ cooked += '\b';
+ break;
+ case 'f':
+ cooked += '\f';
+ break;
+ case 'v':
+ cooked += '\v';
+ break;
+
+ default:
+ if (ch === '0') {
+ if (isDecimalDigit(source.charCodeAt(index))) {
+ // Illegal: \01 \02 and so on
+ throwError(Messages.TemplateOctalLiteral);
+ }
+ cooked += '\0';
+ } else if (isOctalDigit(ch)) {
+ // Illegal: \1 \2
+ throwError(Messages.TemplateOctalLiteral);
+ } else {
+ cooked += ch;
+ }
+ break;
+ }
+ } else {
+ ++lineNumber;
+ if (ch === '\r' && source[index] === '\n') {
+ ++index;
+ }
+ lineStart = index;
+ }
+ } else if (isLineTerminator(ch.charCodeAt(0))) {
+ ++lineNumber;
+ if (ch === '\r' && source[index] === '\n') {
+ ++index;
+ }
+ lineStart = index;
+ cooked += '\n';
+ } else {
+ cooked += ch;
+ }
+ }
+
+ if (!terminated) {
+ throwUnexpectedToken();
+ }
+
+ if (!head) {
+ state.curlyStack.pop();
+ }
+
+ return {
+ type: Token.Template,
+ value: {
+ cooked: cooked,
+ raw: source.slice(start + 1, index - rawOffset)
+ },
+ head: head,
+ tail: tail,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ start: start,
+ end: index
+ };
+ }
+
+ // 11.8.5 Regular Expression Literals
+
+ function testRegExp(pattern, flags) {
+ // The BMP character to use as a replacement for astral symbols when
+ // translating an ES6 "u"-flagged pattern to an ES5-compatible
+ // approximation.
+ // Note: replacing with '\uFFFF' enables false positives in unlikely
+ // scenarios. For example, `[\u{1044f}-\u{10440}]` is an invalid
+ // pattern that would not be detected by this substitution.
+ var astralSubstitute = '\uFFFF',
+ tmp = pattern;
+
+ if (flags.indexOf('u') >= 0) {
+ tmp = tmp
+ // Replace every Unicode escape sequence with the equivalent
+ // BMP character or a constant ASCII code point in the case of
+ // astral symbols. (See the above note on `astralSubstitute`
+ // for more information.)
+ .replace(/\\u\{([0-9a-fA-F]+)\}|\\u([a-fA-F0-9]{4})/g, function ($0, $1, $2) {
+ var codePoint = parseInt($1 || $2, 16);
+ if (codePoint > 0x10FFFF) {
+ throwUnexpectedToken(null, Messages.InvalidRegExp);
+ }
+ if (codePoint <= 0xFFFF) {
+ return String.fromCharCode(codePoint);
+ }
+ return astralSubstitute;
+ })
+ // Replace each paired surrogate with a single ASCII symbol to
+ // avoid throwing on regular expressions that are only valid in
+ // combination with the "u" flag.
+ .replace(
+ /[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
+ astralSubstitute
+ );
+ }
+
+ // First, detect invalid regular expressions.
+ try {
+ RegExp(tmp);
+ } catch (e) {
+ throwUnexpectedToken(null, Messages.InvalidRegExp);
+ }
+
+ // Return a regular expression object for this pattern-flag pair, or
+ // `null` in case the current environment doesn't support the flags it
+ // uses.
+ try {
+ return new RegExp(pattern, flags);
+ } catch (exception) {
+ return null;
+ }
+ }
+
+ function scanRegExpBody() {
+ var ch, str, classMarker, terminated, body;
+
+ ch = source[index];
+ assert(ch === '/', 'Regular expression literal must start with a slash');
+ str = source[index++];
+
+ classMarker = false;
+ terminated = false;
+ while (index < length) {
+ ch = source[index++];
+ str += ch;
+ if (ch === '\\') {
+ ch = source[index++];
+ // ECMA-262 7.8.5
+ if (isLineTerminator(ch.charCodeAt(0))) {
+ throwUnexpectedToken(null, Messages.UnterminatedRegExp);
+ }
+ str += ch;
+ } else if (isLineTerminator(ch.charCodeAt(0))) {
+ throwUnexpectedToken(null, Messages.UnterminatedRegExp);
+ } else if (classMarker) {
+ if (ch === ']') {
+ classMarker = false;
+ }
+ } else {
+ if (ch === '/') {
+ terminated = true;
+ break;
+ } else if (ch === '[') {
+ classMarker = true;
+ }
+ }
+ }
+
+ if (!terminated) {
+ throwUnexpectedToken(null, Messages.UnterminatedRegExp);
+ }
+
+ // Exclude leading and trailing slash.
+ body = str.substr(1, str.length - 2);
+ return {
+ value: body,
+ literal: str
+ };
+ }
+
+ function scanRegExpFlags() {
+ var ch, str, flags, restore;
+
+ str = '';
+ flags = '';
+ while (index < length) {
+ ch = source[index];
+ if (!isIdentifierPart(ch.charCodeAt(0))) {
+ break;
+ }
+
+ ++index;
+ if (ch === '\\' && index < length) {
+ ch = source[index];
+ if (ch === 'u') {
+ ++index;
+ restore = index;
+ ch = scanHexEscape('u');
+ if (ch) {
+ flags += ch;
+ for (str += '\\u'; restore < index; ++restore) {
+ str += source[restore];
+ }
+ } else {
+ index = restore;
+ flags += 'u';
+ str += '\\u';
+ }
+ tolerateUnexpectedToken();
+ } else {
+ str += '\\';
+ tolerateUnexpectedToken();
+ }
+ } else {
+ flags += ch;
+ str += ch;
+ }
+ }
+
+ return {
+ value: flags,
+ literal: str
+ };
+ }
+
+ function scanRegExp() {
+ scanning = true;
+ var start, body, flags, value;
+
+ lookahead = null;
+ skipComment();
+ start = index;
+
+ body = scanRegExpBody();
+ flags = scanRegExpFlags();
+ value = testRegExp(body.value, flags.value);
+ scanning = false;
+ if (extra.tokenize) {
+ return {
+ type: Token.RegularExpression,
+ value: value,
+ regex: {
+ pattern: body.value,
+ flags: flags.value
+ },
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ start: start,
+ end: index
+ };
+ }
+
+ return {
+ literal: body.literal + flags.literal,
+ value: value,
+ regex: {
+ pattern: body.value,
+ flags: flags.value
+ },
+ start: start,
+ end: index
+ };
+ }
+
+ function collectRegex() {
+ var pos, loc, regex, token;
+
+ skipComment();
+
+ pos = index;
+ loc = {
+ start: {
+ line: lineNumber,
+ column: index - lineStart
+ }
+ };
+
+ regex = scanRegExp();
+
+ loc.end = {
+ line: lineNumber,
+ column: index - lineStart
+ };
+
+ /* istanbul ignore next */
+ if (!extra.tokenize) {
+ // Pop the previous token, which is likely '/' or '/='
+ if (extra.tokens.length > 0) {
+ token = extra.tokens[extra.tokens.length - 1];
+ if (token.range[0] === pos && token.type === 'Punctuator') {
+ if (token.value === '/' || token.value === '/=') {
+ extra.tokens.pop();
+ }
+ }
+ }
+
+ extra.tokens.push({
+ type: 'RegularExpression',
+ value: regex.literal,
+ regex: regex.regex,
+ range: [pos, index],
+ loc: loc
+ });
+ }
+
+ return regex;
+ }
+
+ function isIdentifierName(token) {
+ return token.type === Token.Identifier ||
+ token.type === Token.Keyword ||
+ token.type === Token.BooleanLiteral ||
+ token.type === Token.NullLiteral;
+ }
+
+ function advanceSlash() {
+ var prevToken,
+ checkToken;
+ // Using the following algorithm:
+ // https://github.com/mozilla/sweet.js/wiki/design
+ prevToken = extra.tokens[extra.tokens.length - 1];
+ if (!prevToken) {
+ // Nothing before that: it cannot be a division.
+ return collectRegex();
+ }
+ if (prevToken.type === 'Punctuator') {
+ if (prevToken.value === ']') {
+ return scanPunctuator();
+ }
+ if (prevToken.value === ')') {
+ checkToken = extra.tokens[extra.openParenToken - 1];
+ if (checkToken &&
+ checkToken.type === 'Keyword' &&
+ (checkToken.value === 'if' ||
+ checkToken.value === 'while' ||
+ checkToken.value === 'for' ||
+ checkToken.value === 'with')) {
+ return collectRegex();
+ }
+ return scanPunctuator();
+ }
+ if (prevToken.value === '}') {
+ // Dividing a function by anything makes little sense,
+ // but we have to check for that.
+ if (extra.tokens[extra.openCurlyToken - 3] &&
+ extra.tokens[extra.openCurlyToken - 3].type === 'Keyword') {
+ // Anonymous function.
+ checkToken = extra.tokens[extra.openCurlyToken - 4];
+ if (!checkToken) {
+ return scanPunctuator();
+ }
+ } else if (extra.tokens[extra.openCurlyToken - 4] &&
+ extra.tokens[extra.openCurlyToken - 4].type === 'Keyword') {
+ // Named function.
+ checkToken = extra.tokens[extra.openCurlyToken - 5];
+ if (!checkToken) {
+ return collectRegex();
+ }
+ } else {
+ return scanPunctuator();
+ }
+ // checkToken determines whether the function is
+ // a declaration or an expression.
+ if (FnExprTokens.indexOf(checkToken.value) >= 0) {
+ // It is an expression.
+ return scanPunctuator();
+ }
+ // It is a declaration.
+ return collectRegex();
+ }
+ return collectRegex();
+ }
+ if (prevToken.type === 'Keyword' && prevToken.value !== 'this') {
+ return collectRegex();
+ }
+ return scanPunctuator();
+ }
+
+ function advance() {
+ var ch, token;
+
+ if (index >= length) {
+ return {
+ type: Token.EOF,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ start: index,
+ end: index
+ };
+ }
+
+ ch = source.charCodeAt(index);
+
+ if (isIdentifierStart(ch)) {
+ token = scanIdentifier();
+ if (strict && isStrictModeReservedWord(token.value)) {
+ token.type = Token.Keyword;
+ }
+ return token;
+ }
+
+ // Very common: ( and ) and ;
+ if (ch === 0x28 || ch === 0x29 || ch === 0x3B) {
+ return scanPunctuator();
+ }
+
+ // String literal starts with single quote (U+0027) or double quote (U+0022).
+ if (ch === 0x27 || ch === 0x22) {
+ return scanStringLiteral();
+ }
+
+ // Dot (.) U+002E can also start a floating-point number, hence the need
+ // to check the next character.
+ if (ch === 0x2E) {
+ if (isDecimalDigit(source.charCodeAt(index + 1))) {
+ return scanNumericLiteral();
+ }
+ return scanPunctuator();
+ }
+
+ if (isDecimalDigit(ch)) {
+ return scanNumericLiteral();
+ }
+
+ // Slash (/) U+002F can also start a regex.
+ if (extra.tokenize && ch === 0x2F) {
+ return advanceSlash();
+ }
+
+ // Template literals start with ` (U+0060) for template head
+ // or } (U+007D) for template middle or template tail.
+ if (ch === 0x60 || (ch === 0x7D && state.curlyStack[state.curlyStack.length - 1] === '${')) {
+ return scanTemplate();
+ }
+
+ return scanPunctuator();
+ }
+
+ function collectToken() {
+ var loc, token, value, entry;
+
+ loc = {
+ start: {
+ line: lineNumber,
+ column: index - lineStart
+ }
+ };
+
+ token = advance();
+ loc.end = {
+ line: lineNumber,
+ column: index - lineStart
+ };
+
+ if (token.type !== Token.EOF) {
+ value = source.slice(token.start, token.end);
+ entry = {
+ type: TokenName[token.type],
+ value: value,
+ range: [token.start, token.end],
+ loc: loc
+ };
+ if (token.regex) {
+ entry.regex = {
+ pattern: token.regex.pattern,
+ flags: token.regex.flags
+ };
+ }
+ extra.tokens.push(entry);
+ }
+
+ return token;
+ }
+
+ function lex() {
+ var token;
+ scanning = true;
+
+ lastIndex = index;
+ lastLineNumber = lineNumber;
+ lastLineStart = lineStart;
+
+ skipComment();
+
+ token = lookahead;
+
+ startIndex = index;
+ startLineNumber = lineNumber;
+ startLineStart = lineStart;
+
+ lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance();
+ scanning = false;
+ return token;
+ }
+
+ function peek() {
+ scanning = true;
+
+ skipComment();
+
+ lastIndex = index;
+ lastLineNumber = lineNumber;
+ lastLineStart = lineStart;
+
+ startIndex = index;
+ startLineNumber = lineNumber;
+ startLineStart = lineStart;
+
+ lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance();
+ scanning = false;
+ }
+
+ function Position() {
+ this.line = startLineNumber;
+ this.column = startIndex - startLineStart;
+ }
+
+ function SourceLocation() {
+ this.start = new Position();
+ this.end = null;
+ }
+
+ function WrappingSourceLocation(startToken) {
+ this.start = {
+ line: startToken.lineNumber,
+ column: startToken.start - startToken.lineStart
+ };
+ this.end = null;
+ }
+
+ function Node() {
+ if (extra.range) {
+ this.range = [startIndex, 0];
+ }
+ if (extra.loc) {
+ this.loc = new SourceLocation();
+ }
+ }
+
+ function WrappingNode(startToken) {
+ if (extra.range) {
+ this.range = [startToken.start, 0];
+ }
+ if (extra.loc) {
+ this.loc = new WrappingSourceLocation(startToken);
+ }
+ }
+
+ WrappingNode.prototype = Node.prototype = {
+
+ processComment: function () {
+ var lastChild,
+ leadingComments,
+ trailingComments,
+ bottomRight = extra.bottomRightStack,
+ i,
+ comment,
+ last = bottomRight[bottomRight.length - 1];
+
+ if (this.type === Syntax.Program) {
+ if (this.body.length > 0) {
+ return;
+ }
+ }
+
+ if (extra.trailingComments.length > 0) {
+ trailingComments = [];
+ for (i = extra.trailingComments.length - 1; i >= 0; --i) {
+ comment = extra.trailingComments[i];
+ if (comment.range[0] >= this.range[1]) {
+ trailingComments.unshift(comment);
+ extra.trailingComments.splice(i, 1);
+ }
+ }
+ extra.trailingComments = [];
+ } else {
+ if (last && last.trailingComments && last.trailingComments[0].range[0] >= this.range[1]) {
+ trailingComments = last.trailingComments;
+ delete last.trailingComments;
+ }
+ }
+
+ // Eating the stack.
+ while (last && last.range[0] >= this.range[0]) {
+ lastChild = bottomRight.pop();
+ last = bottomRight[bottomRight.length - 1];
+ }
+
+ if (lastChild) {
+ if (lastChild.leadingComments) {
+ leadingComments = [];
+ for (i = lastChild.leadingComments.length - 1; i >= 0; --i) {
+ comment = lastChild.leadingComments[i];
+ if (comment.range[1] <= this.range[0]) {
+ leadingComments.unshift(comment);
+ lastChild.leadingComments.splice(i, 1);
+ }
+ }
+
+ if (!lastChild.leadingComments.length) {
+ lastChild.leadingComments = undefined;
+ }
+ }
+ } else if (extra.leadingComments.length > 0) {
+ leadingComments = [];
+ for (i = extra.leadingComments.length - 1; i >= 0; --i) {
+ comment = extra.leadingComments[i];
+ if (comment.range[1] <= this.range[0]) {
+ leadingComments.unshift(comment);
+ extra.leadingComments.splice(i, 1);
+ }
+ }
+ }
+
+
+ if (leadingComments && leadingComments.length > 0) {
+ this.leadingComments = leadingComments;
+ }
+ if (trailingComments && trailingComments.length > 0) {
+ this.trailingComments = trailingComments;
+ }
+
+ bottomRight.push(this);
+ },
+
+ finish: function () {
+ if (extra.range) {
+ this.range[1] = lastIndex;
+ }
+ if (extra.loc) {
+ this.loc.end = {
+ line: lastLineNumber,
+ column: lastIndex - lastLineStart
+ };
+ if (extra.source) {
+ this.loc.source = extra.source;
+ }
+ }
+
+ if (extra.attachComment) {
+ this.processComment();
+ }
+ },
+
+ finishArrayExpression: function (elements) {
+ this.type = Syntax.ArrayExpression;
+ this.elements = elements;
+ this.finish();
+ return this;
+ },
+
+ finishArrayPattern: function (elements) {
+ this.type = Syntax.ArrayPattern;
+ this.elements = elements;
+ this.finish();
+ return this;
+ },
+
+ finishArrowFunctionExpression: function (params, defaults, body, expression) {
+ this.type = Syntax.ArrowFunctionExpression;
+ this.id = null;
+ this.params = params;
+ this.defaults = defaults;
+ this.body = body;
+ this.generator = false;
+ this.expression = expression;
+ this.finish();
+ return this;
+ },
+
+ finishAssignmentExpression: function (operator, left, right) {
+ this.type = Syntax.AssignmentExpression;
+ this.operator = operator;
+ this.left = left;
+ this.right = right;
+ this.finish();
+ return this;
+ },
+
+ finishAssignmentPattern: function (left, right) {
+ this.type = Syntax.AssignmentPattern;
+ this.left = left;
+ this.right = right;
+ this.finish();
+ return this;
+ },
+
+ finishBinaryExpression: function (operator, left, right) {
+ this.type = (operator === '||' || operator === '&&') ? Syntax.LogicalExpression : Syntax.BinaryExpression;
+ this.operator = operator;
+ this.left = left;
+ this.right = right;
+ this.finish();
+ return this;
+ },
+
+ finishBlockStatement: function (body) {
+ this.type = Syntax.BlockStatement;
+ this.body = body;
+ this.finish();
+ return this;
+ },
+
+ finishBreakStatement: function (label) {
+ this.type = Syntax.BreakStatement;
+ this.label = label;
+ this.finish();
+ return this;
+ },
+
+ finishCallExpression: function (callee, args) {
+ this.type = Syntax.CallExpression;
+ this.callee = callee;
+ this.arguments = args;
+ this.finish();
+ return this;
+ },
+
+ finishCatchClause: function (param, body) {
+ this.type = Syntax.CatchClause;
+ this.param = param;
+ this.body = body;
+ this.finish();
+ return this;
+ },
+
+ finishClassBody: function (body) {
+ this.type = Syntax.ClassBody;
+ this.body = body;
+ this.finish();
+ return this;
+ },
+
+ finishClassDeclaration: function (id, superClass, body) {
+ this.type = Syntax.ClassDeclaration;
+ this.id = id;
+ this.superClass = superClass;
+ this.body = body;
+ this.finish();
+ return this;
+ },
+
+ finishClassExpression: function (id, superClass, body) {
+ this.type = Syntax.ClassExpression;
+ this.id = id;
+ this.superClass = superClass;
+ this.body = body;
+ this.finish();
+ return this;
+ },
+
+ finishConditionalExpression: function (test, consequent, alternate) {
+ this.type = Syntax.ConditionalExpression;
+ this.test = test;
+ this.consequent = consequent;
+ this.alternate = alternate;
+ this.finish();
+ return this;
+ },
+
+ finishContinueStatement: function (label) {
+ this.type = Syntax.ContinueStatement;
+ this.label = label;
+ this.finish();
+ return this;
+ },
+
+ finishDebuggerStatement: function () {
+ this.type = Syntax.DebuggerStatement;
+ this.finish();
+ return this;
+ },
+
+ finishDoWhileStatement: function (body, test) {
+ this.type = Syntax.DoWhileStatement;
+ this.body = body;
+ this.test = test;
+ this.finish();
+ return this;
+ },
+
+ finishEmptyStatement: function () {
+ this.type = Syntax.EmptyStatement;
+ this.finish();
+ return this;
+ },
+
+ finishExpressionStatement: function (expression) {
+ this.type = Syntax.ExpressionStatement;
+ this.expression = expression;
+ this.finish();
+ return this;
+ },
+
+ finishForStatement: function (init, test, update, body) {
+ this.type = Syntax.ForStatement;
+ this.init = init;
+ this.test = test;
+ this.update = update;
+ this.body = body;
+ this.finish();
+ return this;
+ },
+
+ finishForOfStatement: function (left, right, body) {
+ this.type = Syntax.ForOfStatement;
+ this.left = left;
+ this.right = right;
+ this.body = body;
+ this.finish();
+ return this;
+ },
+
+ finishForInStatement: function (left, right, body) {
+ this.type = Syntax.ForInStatement;
+ this.left = left;
+ this.right = right;
+ this.body = body;
+ this.each = false;
+ this.finish();
+ return this;
+ },
+
+ finishFunctionDeclaration: function (id, params, defaults, body, generator) {
+ this.type = Syntax.FunctionDeclaration;
+ this.id = id;
+ this.params = params;
+ this.defaults = defaults;
+ this.body = body;
+ this.generator = generator;
+ this.expression = false;
+ this.finish();
+ return this;
+ },
+
+ finishFunctionExpression: function (id, params, defaults, body, generator) {
+ this.type = Syntax.FunctionExpression;
+ this.id = id;
+ this.params = params;
+ this.defaults = defaults;
+ this.body = body;
+ this.generator = generator;
+ this.expression = false;
+ this.finish();
+ return this;
+ },
+
+ finishIdentifier: function (name) {
+ this.type = Syntax.Identifier;
+ this.name = name;
+ this.finish();
+ return this;
+ },
+
+ finishIfStatement: function (test, consequent, alternate) {
+ this.type = Syntax.IfStatement;
+ this.test = test;
+ this.consequent = consequent;
+ this.alternate = alternate;
+ this.finish();
+ return this;
+ },
+
+ finishLabeledStatement: function (label, body) {
+ this.type = Syntax.LabeledStatement;
+ this.label = label;
+ this.body = body;
+ this.finish();
+ return this;
+ },
+
+ finishLiteral: function (token) {
+ this.type = Syntax.Literal;
+ this.value = token.value;
+ this.raw = source.slice(token.start, token.end);
+ if (token.regex) {
+ this.regex = token.regex;
+ }
+ this.finish();
+ return this;
+ },
+
+ finishMemberExpression: function (accessor, object, property) {
+ this.type = Syntax.MemberExpression;
+ this.computed = accessor === '[';
+ this.object = object;
+ this.property = property;
+ this.finish();
+ return this;
+ },
+
+ finishMetaProperty: function (meta, property) {
+ this.type = Syntax.MetaProperty;
+ this.meta = meta;
+ this.property = property;
+ this.finish();
+ return this;
+ },
+
+ finishNewExpression: function (callee, args) {
+ this.type = Syntax.NewExpression;
+ this.callee = callee;
+ this.arguments = args;
+ this.finish();
+ return this;
+ },
+
+ finishObjectExpression: function (properties) {
+ this.type = Syntax.ObjectExpression;
+ this.properties = properties;
+ this.finish();
+ return this;
+ },
+
+ finishObjectPattern: function (properties) {
+ this.type = Syntax.ObjectPattern;
+ this.properties = properties;
+ this.finish();
+ return this;
+ },
+
+ finishPostfixExpression: function (operator, argument) {
+ this.type = Syntax.UpdateExpression;
+ this.operator = operator;
+ this.argument = argument;
+ this.prefix = false;
+ this.finish();
+ return this;
+ },
+
+ finishProgram: function (body) {
+ this.type = Syntax.Program;
+ this.body = body;
+ if (sourceType === 'module') {
+ // very restrictive for now
+ this.sourceType = sourceType;
+ }
+ this.finish();
+ return this;
+ },
+
+ finishProperty: function (kind, key, computed, value, method, shorthand) {
+ this.type = Syntax.Property;
+ this.key = key;
+ this.computed = computed;
+ this.value = value;
+ this.kind = kind;
+ this.method = method;
+ this.shorthand = shorthand;
+ this.finish();
+ return this;
+ },
+
+ finishRestElement: function (argument) {
+ this.type = Syntax.RestElement;
+ this.argument = argument;
+ this.finish();
+ return this;
+ },
+
+ finishReturnStatement: function (argument) {
+ this.type = Syntax.ReturnStatement;
+ this.argument = argument;
+ this.finish();
+ return this;
+ },
+
+ finishSequenceExpression: function (expressions) {
+ this.type = Syntax.SequenceExpression;
+ this.expressions = expressions;
+ this.finish();
+ return this;
+ },
+
+ finishSpreadElement: function (argument) {
+ this.type = Syntax.SpreadElement;
+ this.argument = argument;
+ this.finish();
+ return this;
+ },
+
+ finishSwitchCase: function (test, consequent) {
+ this.type = Syntax.SwitchCase;
+ this.test = test;
+ this.consequent = consequent;
+ this.finish();
+ return this;
+ },
+
+ finishSuper: function () {
+ this.type = Syntax.Super;
+ this.finish();
+ return this;
+ },
+
+ finishSwitchStatement: function (discriminant, cases) {
+ this.type = Syntax.SwitchStatement;
+ this.discriminant = discriminant;
+ this.cases = cases;
+ this.finish();
+ return this;
+ },
+
+ finishTaggedTemplateExpression: function (tag, quasi) {
+ this.type = Syntax.TaggedTemplateExpression;
+ this.tag = tag;
+ this.quasi = quasi;
+ this.finish();
+ return this;
+ },
+
+ finishTemplateElement: function (value, tail) {
+ this.type = Syntax.TemplateElement;
+ this.value = value;
+ this.tail = tail;
+ this.finish();
+ return this;
+ },
+
+ finishTemplateLiteral: function (quasis, expressions) {
+ this.type = Syntax.TemplateLiteral;
+ this.quasis = quasis;
+ this.expressions = expressions;
+ this.finish();
+ return this;
+ },
+
+ finishThisExpression: function () {
+ this.type = Syntax.ThisExpression;
+ this.finish();
+ return this;
+ },
+
+ finishThrowStatement: function (argument) {
+ this.type = Syntax.ThrowStatement;
+ this.argument = argument;
+ this.finish();
+ return this;
+ },
+
+ finishTryStatement: function (block, handler, finalizer) {
+ this.type = Syntax.TryStatement;
+ this.block = block;
+ this.guardedHandlers = [];
+ this.handlers = handler ? [ handler ] : [];
+ this.handler = handler;
+ this.finalizer = finalizer;
+ this.finish();
+ return this;
+ },
+
+ finishUnaryExpression: function (operator, argument) {
+ this.type = (operator === '++' || operator === '--') ? Syntax.UpdateExpression : Syntax.UnaryExpression;
+ this.operator = operator;
+ this.argument = argument;
+ this.prefix = true;
+ this.finish();
+ return this;
+ },
+
+ finishVariableDeclaration: function (declarations) {
+ this.type = Syntax.VariableDeclaration;
+ this.declarations = declarations;
+ this.kind = 'var';
+ this.finish();
+ return this;
+ },
+
+ finishLexicalDeclaration: function (declarations, kind) {
+ this.type = Syntax.VariableDeclaration;
+ this.declarations = declarations;
+ this.kind = kind;
+ this.finish();
+ return this;
+ },
+
+ finishVariableDeclarator: function (id, init) {
+ this.type = Syntax.VariableDeclarator;
+ this.id = id;
+ this.init = init;
+ this.finish();
+ return this;
+ },
+
+ finishWhileStatement: function (test, body) {
+ this.type = Syntax.WhileStatement;
+ this.test = test;
+ this.body = body;
+ this.finish();
+ return this;
+ },
+
+ finishWithStatement: function (object, body) {
+ this.type = Syntax.WithStatement;
+ this.object = object;
+ this.body = body;
+ this.finish();
+ return this;
+ },
+
+ finishExportSpecifier: function (local, exported) {
+ this.type = Syntax.ExportSpecifier;
+ this.exported = exported || local;
+ this.local = local;
+ this.finish();
+ return this;
+ },
+
+ finishImportDefaultSpecifier: function (local) {
+ this.
<TRUNCATED>